diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java index 680acdccf2f39..2c4b86b0d721b 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java @@ -54,6 +54,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.UUID; @@ -146,7 +147,7 @@ public Node( this.repoDir = baseWorkingDir.resolve("repo"); this.dataDir = workingDir.resolve("data"); this.logsDir = workingDir.resolve("logs"); - this.configDir = workingDir.resolve("config"); + this.configDir = Optional.ofNullable(spec.getConfigDir()).orElse(workingDir.resolve("config")); this.tempDir = workingDir.resolve("tmp"); // elasticsearch temporary directory this.debugPort = DefaultLocalClusterHandle.NEXT_DEBUG_PORT.getAndIncrement(); } @@ -294,6 +295,10 @@ Path getWorkingDir() { return workingDir; } + Path getConfigDir() { + return configDir; + } + public void waitUntilReady() { try { Retry.retryUntilTrue(NODE_UP_TIMEOUT, Duration.ofMillis(500), () -> { @@ -426,7 +431,7 @@ private void writeConfiguration() { try (Stream configFiles = Files.walk(distributionDir.resolve("config"))) { for (Path file : configFiles.toList()) { Path relativePath = distributionDir.resolve("config").relativize(file); - Path dest = configDir.resolve(relativePath); + Path dest = configDir.resolve(relativePath.toFile().getPath()); if (Files.exists(dest) == false) { Files.createDirectories(dest.getParent()); Files.copy(file, dest); @@ -640,7 +645,7 @@ private void configureSecurity() { if (operators.isEmpty() == false) { // TODO: Support service accounts here final String operatorUsersFileName = "operator_users.yml"; - final Path destination = workingDir.resolve("config").resolve(operatorUsersFileName); + final Path destination = configDir.resolve(operatorUsersFileName); if (Files.exists(destination)) { throw new IllegalStateException( "Operator users file [" @@ -667,7 +672,7 @@ private void configureSecurity() { } private void writeRolesFile() { - Path destination = workingDir.resolve("config").resolve("roles.yml"); + Path destination = configDir.resolve("roles.yml"); spec.getRolesFiles().forEach(rolesFile -> { try ( Writer writer = Files.newBufferedWriter(destination, StandardOpenOption.APPEND); @@ -857,7 +862,7 @@ private void startElasticsearch() { private Map getEnvironmentVariables() { Map environment = new HashMap<>(spec.resolveEnvironment()); - environment.put("ES_PATH_CONF", workingDir.resolve("config").toString()); + environment.put("ES_PATH_CONF", configDir.toString()); environment.put("ES_TMPDIR", workingDir.resolve("tmp").toString()); // Windows requires this as it defaults to `c:\windows` despite ES_TMPDIR environment.put("TMP", workingDir.resolve("tmp").toString()); diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java index 7f1a384ebb43d..73c5afdec5b9f 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java @@ -212,7 +212,8 @@ private LocalNodeSpec build(LocalClusterSpec cluster, int nodeIndex) { getExtraConfigFiles(), getSystemPropertyProviders(), getSystemProperties(), - getJvmArgs() + getJvmArgs(), + Optional.ofNullable(getConfigDirSupplier()).map(Supplier::get).orElse(null) ); } } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java index 9617cb633aa9b..d8dba4e51ac42 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java @@ -17,6 +17,7 @@ import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.cluster.util.resource.Resource; +import java.nio.file.Path; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; @@ -47,6 +48,7 @@ public abstract class AbstractLocalSpecBuilder> im private DistributionType distributionType; private Version version; private String keystorePassword; + private Supplier configDirSupplier; protected AbstractLocalSpecBuilder(AbstractLocalSpecBuilder parent) { this.parent = parent; @@ -270,6 +272,16 @@ public String getKeystorePassword() { return inherit(() -> parent.getKeystorePassword(), keystorePassword); } + @Override + public T withConfigDir(Supplier configDirSupplier) { + this.configDirSupplier = configDirSupplier; + return cast(this); + } + + public Supplier getConfigDirSupplier() { + return inherit(() -> parent.getConfigDirSupplier(), configDirSupplier); + } + @Override public T version(Version version) { this.version = version; diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java index 4331728aedb1e..f2e2245e7321e 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java @@ -237,15 +237,15 @@ private WaitForHttpResource configureWaitForReady() throws MalformedURLException private void configureWaitSecurity(WaitForHttpResource wait, Node node) { String caFile = node.getSpec().getSetting("xpack.security.http.ssl.certificate_authorities", null); if (caFile != null) { - wait.setCertificateAuthorities(node.getWorkingDir().resolve("config").resolve(caFile).toFile()); + wait.setCertificateAuthorities(node.getConfigDir().resolve(caFile).toFile()); } String sslCertFile = node.getSpec().getSetting("xpack.security.http.ssl.certificate", null); if (sslCertFile != null) { - wait.setCertificateAuthorities(node.getWorkingDir().resolve("config").resolve(sslCertFile).toFile()); + wait.setCertificateAuthorities(node.getConfigDir().resolve(sslCertFile).toFile()); } String sslKeystoreFile = node.getSpec().getSetting("xpack.security.http.ssl.keystore.path", null); if (sslKeystoreFile != null && caFile == null) { // Can not set both trust stores and CA - wait.setTrustStoreFile(node.getWorkingDir().resolve("config").resolve(sslKeystoreFile).toFile()); + wait.setTrustStoreFile(node.getConfigDir().resolve(sslKeystoreFile).toFile()); } String keystorePassword = node.getSpec().getSetting("xpack.security.http.ssl.keystore.secure_password", null); if (keystorePassword != null) { @@ -254,7 +254,7 @@ private void configureWaitSecurity(WaitForHttpResource wait, Node node) { } private boolean isSecurityAutoConfigured(Node node) { - Path configFile = node.getWorkingDir().resolve("config").resolve("elasticsearch.yml"); + Path configFile = node.getConfigDir().resolve("elasticsearch.yml"); try (Stream lines = Files.lines(configFile)) { return lines.anyMatch(l -> l.contains("BEGIN SECURITY AUTO CONFIGURATION")); } catch (IOException e) { @@ -273,7 +273,7 @@ private void writeUnicastHostsFile() { LOGGER.info("Skipping writing unicast hosts file for node {}", node.getName()); return; } - Path hostsFile = node.getWorkingDir().resolve("config").resolve("unicast_hosts.txt"); + Path hostsFile = node.getConfigDir().resolve("unicast_hosts.txt"); LOGGER.info("Writing unicast hosts file {} for node {}", hostsFile, node.getName()); Files.writeString(hostsFile, transportUris); } catch (IOException e) { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java index ed5c0c5d1bbc0..cccf2a95234c9 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java @@ -19,6 +19,7 @@ import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.cluster.util.resource.Resource; +import java.nio.file.Path; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -103,6 +104,7 @@ public static class LocalNodeSpec { private final List systemPropertyProviders; private final Map systemProperties; private final List jvmArgs; + private final Path configDir; private Version version; public LocalNodeSpec( @@ -124,7 +126,8 @@ public LocalNodeSpec( Map extraConfigFiles, List systemPropertyProviders, Map systemProperties, - List jvmArgs + List jvmArgs, + Path configDir ) { this.cluster = cluster; this.name = name; @@ -145,6 +148,7 @@ public LocalNodeSpec( this.systemPropertyProviders = systemPropertyProviders; this.systemProperties = systemProperties; this.jvmArgs = jvmArgs; + this.configDir = configDir; } void setVersion(Version version) { @@ -203,6 +207,10 @@ public List getJvmArgs() { return jvmArgs; } + public Path getConfigDir() { + return configDir; + } + public boolean isSecurityEnabled() { return Boolean.parseBoolean(getSetting("xpack.security.enabled", getVersion().onOrAfter("8.0.0") ? "true" : "false")); } @@ -339,7 +347,8 @@ private LocalNodeSpec getFilteredSpec(SettingsProvider filteredProvider, Setting n.extraConfigFiles, n.systemPropertyProviders, n.systemProperties, - n.jvmArgs + n.jvmArgs, + n.configDir ) ) .toList(); diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java index 20c92dc2b11d7..2f4e64b368589 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java @@ -18,6 +18,7 @@ import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.cluster.util.resource.Resource; +import java.nio.file.Path; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; @@ -155,4 +156,10 @@ interface LocalSpecBuilder> { * Adds an additional command line argument to node JVM arguments. */ T jvmArg(String arg); + + /** + * Register a supplier to provide the config directory. The default config directory + * is used when the supplier is null or the return value of the supplier is null. + */ + T withConfigDir(Supplier configDirSupplier); }