Skip to content

Commit 35b4f52

Browse files
Fix failing Keystore Passphrase test for feature branch (#50154)
One problem with the passphrase-from-file tests, as written, is that they would leave a SystemD environment variable set when they failed, and this setting would cause elasticsearch startup to fail for other tests as well. By using a try-finally, I hope that these tests will fail more gracefully. It appears that our Fedora and Ubuntu environments may be configured to store journald information under /var rather than under /run, so that it will persist between boots. Our destructive tests that read from the journal need to account for this in order to avoid trying to limit the output we check in tests.
1 parent d64ab04 commit 35b4f52

File tree

3 files changed

+55
-129
lines changed

3 files changed

+55
-129
lines changed

qa/os/src/test/java/org/elasticsearch/packaging/test/KeystoreManagementTests.java

+54-84
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ public class KeystoreManagementTests extends PackagingTestCase {
5858
public void test10InstallArchiveDistribution() throws Exception {
5959
assumeTrue(distribution().isArchive());
6060

61-
installation = installArchive(distribution);
61+
installation = installArchive(sh, distribution);
6262
verifyArchiveInstallation(installation, distribution());
6363

6464
final Installation.Executables bin = installation.executables();
65-
Shell.Result r = sh.runIgnoreExitCode(bin.elasticsearchKeystore + " has-passwd");
65+
Shell.Result r = sh.runIgnoreExitCode(bin.keystoreTool.toString() + " has-passwd");
6666
assertThat("has-passwd should fail", r.exitCode, not(is(0)));
6767
assertThat("has-passwd should fail", r.stderr, containsString("ERROR: Elasticsearch keystore not found"));
6868
}
@@ -72,12 +72,12 @@ public void test11InstallPackageDistribution() throws Exception {
7272
assumeTrue(distribution().isPackage());
7373

7474
assertRemoved(distribution);
75-
installation = installPackage(distribution);
75+
installation = installPackage(sh, distribution);
7676
assertInstalled(distribution);
7777
verifyPackageInstallation(installation, distribution, sh);
7878

7979
final Installation.Executables bin = installation.executables();
80-
Shell.Result r = sh.runIgnoreExitCode(bin.elasticsearchKeystore + " has-passwd");
80+
Shell.Result r = sh.runIgnoreExitCode(bin.keystoreTool.toString() + " has-passwd");
8181
assertThat("has-passwd should fail", r.exitCode, not(is(0)));
8282
assertThat("has-passwd should fail", r.stderr, containsString("ERROR: Keystore is not password-protected"));
8383
}
@@ -90,10 +90,7 @@ public void test20CreateKeystoreManually() throws Exception {
9090
final Installation.Executables bin = installation.executables();
9191
verifyKeystorePermissions();
9292

93-
String possibleSudo = distribution().isArchive() && Platforms.LINUX
94-
? "sudo -u " + ARCHIVE_OWNER + " "
95-
: "";
96-
Shell.Result r = sh.run(possibleSudo + bin.elasticsearchKeystore + " list");
93+
Shell.Result r = bin.keystoreTool.run("list");
9794
assertThat(r.stdout, containsString("keystore.seed"));
9895
}
9996

@@ -109,10 +106,7 @@ public void test30AutoCreateKeystore() throws Exception {
109106
verifyKeystorePermissions();
110107

111108
final Installation.Executables bin = installation.executables();
112-
String possibleSudo = distribution().isArchive() && Platforms.LINUX
113-
? "sudo -u " + ARCHIVE_OWNER + " "
114-
: "";
115-
Shell.Result r = sh.run(possibleSudo + bin.elasticsearchKeystore + " list");
109+
Shell.Result r = bin.keystoreTool.run("list");
116110
assertThat(r.stdout, containsString("keystore.seed"));
117111
}
118112

@@ -192,87 +186,57 @@ public void test50KeystorePasswordFromFile() throws Exception {
192186

193187
assertPasswordProtectedKeystore();
194188

195-
sh.getEnv().put("ES_KEYSTORE_PASSPHRASE_FILE", esKeystorePassphraseFile.toString());
196-
distribution().packagingConditional()
197-
.forPackage(
198-
() -> sh.run("sudo systemctl set-environment ES_KEYSTORE_PASSPHRASE_FILE=$ES_KEYSTORE_PASSPHRASE_FILE")
199-
)
200-
.forArchive(Platforms.NO_ACTION)
201-
.forDocker(/* TODO */ Platforms.NO_ACTION)
202-
.run();
189+
try {
190+
sh.run("sudo systemctl set-environment ES_KEYSTORE_PASSPHRASE_FILE=" + esKeystorePassphraseFile);
203191

204-
Files.createFile(esKeystorePassphraseFile);
205-
Files.write(esKeystorePassphraseFile,
206-
(password + System.lineSeparator()).getBytes(StandardCharsets.UTF_8),
207-
StandardOpenOption.WRITE);
192+
Files.createFile(esKeystorePassphraseFile);
193+
Files.write(esKeystorePassphraseFile,
194+
(password + System.lineSeparator()).getBytes(StandardCharsets.UTF_8),
195+
StandardOpenOption.WRITE);
208196

209-
startElasticsearch();
210-
ServerUtils.runElasticsearchTests();
211-
stopElasticsearch();
212-
213-
distribution().packagingConditional()
214-
.forPackage(
215-
() -> sh.run("sudo systemctl unset-environment ES_KEYSTORE_PASSPHRASE_FILE")
216-
)
217-
.forArchive(Platforms.NO_ACTION)
218-
.forDocker(/* TODO */ Platforms.NO_ACTION)
219-
.run();
197+
startElasticsearch();
198+
ServerUtils.runElasticsearchTests();
199+
stopElasticsearch();
200+
} finally {
201+
sh.run("sudo systemctl unset-environment ES_KEYSTORE_PASSPHRASE_FILE");
202+
}
220203
}
221204

222-
@Ignore /* Ignored for feature branch, awaits fix: https://github.com/elastic/elasticsearch/issues/50079 */
223205
public void test51WrongKeystorePasswordFromFile() throws Exception {
224206
assumeTrue("only for systemd", Platforms.isSystemd() && distribution().isPackage());
225207
Path esKeystorePassphraseFile = installation.config.resolve("eks");
226208

227209
assertPasswordProtectedKeystore();
228210

229-
sh.getEnv().put("ES_KEYSTORE_PASSPHRASE_FILE", esKeystorePassphraseFile.toString());
230-
distribution().packagingConditional()
231-
.forPackage(
232-
() -> sh.run("sudo systemctl set-environment ES_KEYSTORE_PASSPHRASE_FILE=$ES_KEYSTORE_PASSPHRASE_FILE")
233-
)
234-
.forArchive(Platforms.NO_ACTION)
235-
.forDocker(/* TODO */ Platforms.NO_ACTION)
236-
.run();
237-
238-
if (Files.exists(esKeystorePassphraseFile)) {
239-
rm(esKeystorePassphraseFile);
240-
}
211+
try {
212+
sh.run("sudo systemctl set-environment ES_KEYSTORE_PASSPHRASE_FILE=" + esKeystorePassphraseFile);
241213

242-
Files.createFile(esKeystorePassphraseFile);
243-
Files.write(esKeystorePassphraseFile,
244-
("wrongpassword" + System.lineSeparator()).getBytes(StandardCharsets.UTF_8),
245-
StandardOpenOption.WRITE);
214+
if (Files.exists(esKeystorePassphraseFile)) {
215+
rm(esKeystorePassphraseFile);
216+
}
246217

247-
Shell.Result result = runElasticsearchStartCommand();
248-
assertElasticsearchFailure(result, PASSWORD_ERROR_MESSAGE);
218+
Files.createFile(esKeystorePassphraseFile);
219+
Files.write(esKeystorePassphraseFile,
220+
("wrongpassword" + System.lineSeparator()).getBytes(StandardCharsets.UTF_8),
221+
StandardOpenOption.WRITE);
249222

250-
distribution().packagingConditional()
251-
.forPackage(
252-
() -> sh.run("sudo systemctl unset-environment ES_KEYSTORE_PASSPHRASE_FILE")
253-
)
254-
.forArchive(Platforms.NO_ACTION)
255-
.forDocker(/* TODO */ Platforms.NO_ACTION)
256-
.run();
223+
Shell.Result result = runElasticsearchStartCommand();
224+
assertElasticsearchFailure(result, PASSWORD_ERROR_MESSAGE);
225+
} finally {
226+
sh.run("sudo systemctl unset-environment ES_KEYSTORE_PASSPHRASE_FILE");
227+
}
257228
}
258229

259230
private void createKeystore() throws Exception {
260231
Path keystore = installation.config("elasticsearch.keystore");
261232
final Installation.Executables bin = installation.executables();
262-
Platforms.onLinux(() -> {
263-
distribution().packagingConditional()
264-
.forPackage(() -> sh.run(bin.elasticsearchKeystore + " create"))
265-
.forArchive(() -> sh.run("sudo -u " + ARCHIVE_OWNER + " " + bin.elasticsearchKeystore + " create"))
266-
.forDocker(/* TODO */ Platforms.NO_ACTION)
267-
.run();
268-
});
233+
bin.keystoreTool.run("create");
269234

270235
// this is a hack around the fact that we can't run a command in the same session as the same user but not as administrator.
271236
// the keystore ends up being owned by the Administrators group, so we manually set it to be owned by the vagrant user here.
272237
// from the server's perspective the permissions aren't really different, this is just to reflect what we'd expect in the tests.
273238
// when we run these commands as a role user we won't have to do this
274239
Platforms.onWindows(() -> {
275-
sh.run(bin.elasticsearchKeystore + " create");
276240
sh.chown(keystore);
277241
});
278242
}
@@ -288,31 +252,37 @@ private void setKeystorePassword(String password) throws Exception {
288252
final Installation.Executables bin = installation.executables();
289253

290254
// set the password by passing it to stdin twice
291-
Platforms.onLinux(() -> distribution().packagingConditional()
292-
.forPackage(() -> sh.run("( echo \'" + password + "\' ; echo \'" + password + "\' ) | " +
293-
bin.elasticsearchKeystore + " passwd"))
294-
.forArchive(() -> sh.run("( echo \'" + password + "\' ; echo \'" + password + "\' ) | " +
295-
"sudo -u " + ARCHIVE_OWNER + " " + bin.elasticsearchKeystore + " passwd"))
296-
.forDocker(/* TODO */ Platforms.NO_ACTION)
297-
.run()
298-
);
255+
Platforms.onLinux(() -> {
256+
bin.keystoreTool.run("passwd", password + "\n" + password + "\n");
257+
});
258+
299259
Platforms.onWindows(() -> {
300260
sh.run("Invoke-Command -ScriptBlock {echo \'" + password + "\'; echo \'" + password + "\'} | "
301-
+ bin.elasticsearchKeystore + " passwd");
261+
+ bin.keystoreTool + " passwd");
302262
});
303263
}
304264

305265
private void assertPasswordProtectedKeystore() {
306-
Shell.Result r = sh.runIgnoreExitCode(installation.executables().elasticsearchKeystore.toString() + " has-passwd");
266+
Shell.Result r = installation.executables().keystoreTool.run("has-passwd");
307267
assertThat("keystore should be password protected", r.exitCode, is(0));
308268
}
309269

310270
private void verifyKeystorePermissions() throws Exception {
311271
Path keystore = installation.config("elasticsearch.keystore");
312-
distribution().packagingConditional()
313-
.forPackage(() -> assertThat(keystore, file(File, "root", "elasticsearch", p660)))
314-
.forArchive(() -> assertThat(keystore, file(File, ARCHIVE_OWNER, ARCHIVE_OWNER, p660)))
315-
.forDocker(/* TODO */ Platforms.NO_ACTION)
316-
.run();
272+
switch (distribution.packaging) {
273+
case TAR:
274+
case ZIP:
275+
assertThat(keystore, file(File, ARCHIVE_OWNER, ARCHIVE_OWNER, p660));
276+
break;
277+
case DEB:
278+
case RPM:
279+
assertThat(keystore, file(File, "root", "elasticsearch", p660));
280+
break;
281+
case DOCKER:
282+
// TODO #49469
283+
break;
284+
default:
285+
throw new IllegalStateException("Unknown Elasticsearch packaging type.");
286+
}
317287
}
318288
}

qa/os/src/test/java/org/elasticsearch/packaging/util/Distribution.java

-44
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@
2020
package org.elasticsearch.packaging.util;
2121

2222
import java.nio.file.Path;
23-
import java.util.Arrays;
24-
import java.util.HashMap;
25-
import java.util.HashSet;
2623
import java.util.Locale;
27-
import java.util.Map;
2824

2925
public class Distribution {
3026

@@ -88,46 +84,6 @@ public enum Packaging {
8884
}
8985
}
9086

91-
public static class PackagingConditional {
92-
Distribution distribution;
93-
94-
public PackagingConditional(Distribution distribution) {
95-
this.distribution = distribution;
96-
}
97-
98-
private final Map<Packaging, Platforms.PlatformAction> conditions = new HashMap<>();
99-
100-
public PackagingConditional forArchive(Platforms.PlatformAction action) {
101-
conditions.put(Packaging.TAR, action);
102-
conditions.put(Packaging.ZIP, action);
103-
return this;
104-
}
105-
106-
public PackagingConditional forPackage(Platforms.PlatformAction action) {
107-
conditions.put(Packaging.RPM, action);
108-
conditions.put(Packaging.DEB, action);
109-
return this;
110-
}
111-
112-
public PackagingConditional forDocker(Platforms.PlatformAction action) {
113-
conditions.put(Packaging.DOCKER, action);
114-
return this;
115-
}
116-
117-
public void run() throws Exception {
118-
HashSet<Packaging> missingPackaging = new HashSet<>(Arrays.asList(Packaging.values()));
119-
missingPackaging.removeAll(conditions.keySet());
120-
if (missingPackaging.isEmpty() == false) {
121-
throw new IllegalArgumentException("No condition specified for " + missingPackaging);
122-
}
123-
conditions.get(this.distribution.packaging).run();
124-
}
125-
}
126-
127-
public PackagingConditional packagingConditional() {
128-
return new PackagingConditional(this);
129-
}
130-
13187
public enum Platform {
13288
LINUX,
13389
WINDOWS,

qa/os/src/test/java/org/elasticsearch/packaging/util/Packages.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ public static Shell.Result runElasticsearchStartCommand(Shell sh) throws IOExcep
286286
*/
287287
public static void clearJournal(Shell sh) {
288288
if (isSystemd()) {
289-
sh.run("rm -rf /run/log/journal/*");
289+
sh.run("rm -rf /run/log/journal/* /var/log/journal/*");
290290
final Result result = sh.runIgnoreExitCode("systemctl restart systemd-journald");
291291

292292
// Sometimes the restart fails on Debian 10 with:

0 commit comments

Comments
 (0)