Sfoglia il codice sorgente

[Test] Allow configuring configDir for the Java test cluster (#125094)

For creating and deleting projects in multi-project tests, we need
create and delete settings and secrets files on the fly. This PR adds
such feature to the Java test cluster with an option to specify the
config directory.
Yang Wang 7 mesi fa
parent
commit
a1b0ed104b

+ 10 - 5
test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java

@@ -54,6 +54,7 @@ import java.util.List;
 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 abstract class AbstractLocalClusterFactory<S extends LocalClusterSpec, H
             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 @@ public abstract class AbstractLocalClusterFactory<S extends LocalClusterSpec, H
             return workingDir;
         }
 
+        Path getConfigDir() {
+            return configDir;
+        }
+
         public void waitUntilReady() {
             try {
                 Retry.retryUntilTrue(NODE_UP_TIMEOUT, Duration.ofMillis(500), () -> {
@@ -426,7 +431,7 @@ public abstract class AbstractLocalClusterFactory<S extends LocalClusterSpec, H
                 try (Stream<Path> 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 @@ public abstract class AbstractLocalClusterFactory<S extends LocalClusterSpec, H
                 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 @@ public abstract class AbstractLocalClusterFactory<S extends LocalClusterSpec, H
         }
 
         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 @@ public abstract class AbstractLocalClusterFactory<S extends LocalClusterSpec, H
 
         private Map<String, String> getEnvironmentVariables() {
             Map<String, String> 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());

+ 2 - 1
test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java

@@ -212,7 +212,8 @@ public abstract class AbstractLocalClusterSpecBuilder<T extends ElasticsearchClu
                 getExtraConfigFiles(),
                 getSystemPropertyProviders(),
                 getSystemProperties(),
-                getJvmArgs()
+                getJvmArgs(),
+                Optional.ofNullable(getConfigDirSupplier()).map(Supplier::get).orElse(null)
             );
         }
     }

+ 12 - 0
test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java

@@ -17,6 +17,7 @@ import org.elasticsearch.test.cluster.local.distribution.DistributionType;
 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<T extends LocalSpecBuilder<?>> im
     private DistributionType distributionType;
     private Version version;
     private String keystorePassword;
+    private Supplier<Path> configDirSupplier;
 
     protected AbstractLocalSpecBuilder(AbstractLocalSpecBuilder<?> parent) {
         this.parent = parent;
@@ -270,6 +272,16 @@ public abstract class AbstractLocalSpecBuilder<T extends LocalSpecBuilder<?>> im
         return inherit(() -> parent.getKeystorePassword(), keystorePassword);
     }
 
+    @Override
+    public T withConfigDir(Supplier<Path> configDirSupplier) {
+        this.configDirSupplier = configDirSupplier;
+        return cast(this);
+    }
+
+    public Supplier<Path> getConfigDirSupplier() {
+        return inherit(() -> parent.getConfigDirSupplier(), configDirSupplier);
+    }
+
     @Override
     public T version(Version version) {
         this.version = version;

+ 5 - 5
test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java

@@ -237,15 +237,15 @@ public class DefaultLocalClusterHandle implements LocalClusterHandle {
     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 @@ public class DefaultLocalClusterHandle implements LocalClusterHandle {
     }
 
     private boolean isSecurityAutoConfigured(Node node) {
-        Path configFile = node.getWorkingDir().resolve("config").resolve("elasticsearch.yml");
+        Path configFile = node.getConfigDir().resolve("elasticsearch.yml");
         try (Stream<String> lines = Files.lines(configFile)) {
             return lines.anyMatch(l -> l.contains("BEGIN SECURITY AUTO CONFIGURATION"));
         } catch (IOException e) {
@@ -273,7 +273,7 @@ public class DefaultLocalClusterHandle implements LocalClusterHandle {
                     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) {

+ 11 - 2
test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java

@@ -19,6 +19,7 @@ import org.elasticsearch.test.cluster.local.model.User;
 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 class LocalClusterSpec implements ClusterSpec {
         private final List<SystemPropertyProvider> systemPropertyProviders;
         private final Map<String, String> systemProperties;
         private final List<String> jvmArgs;
+        private final Path configDir;
         private Version version;
 
         public LocalNodeSpec(
@@ -124,7 +126,8 @@ public class LocalClusterSpec implements ClusterSpec {
             Map<String, Resource> extraConfigFiles,
             List<SystemPropertyProvider> systemPropertyProviders,
             Map<String, String> systemProperties,
-            List<String> jvmArgs
+            List<String> jvmArgs,
+            Path configDir
         ) {
             this.cluster = cluster;
             this.name = name;
@@ -145,6 +148,7 @@ public class LocalClusterSpec implements ClusterSpec {
             this.systemPropertyProviders = systemPropertyProviders;
             this.systemProperties = systemProperties;
             this.jvmArgs = jvmArgs;
+            this.configDir = configDir;
         }
 
         void setVersion(Version version) {
@@ -203,6 +207,10 @@ public class LocalClusterSpec implements ClusterSpec {
             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 @@ public class LocalClusterSpec implements ClusterSpec {
                         n.extraConfigFiles,
                         n.systemPropertyProviders,
                         n.systemProperties,
-                        n.jvmArgs
+                        n.jvmArgs,
+                        n.configDir
                     )
                 )
                 .toList();

+ 7 - 0
test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java

@@ -18,6 +18,7 @@ import org.elasticsearch.test.cluster.local.distribution.DistributionType;
 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<T extends 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<Path> configDirSupplier);
 }