Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,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 = spec.getConfigDir() == null ? workingDir.resolve("config") : spec.getConfigDir();
this.tempDir = workingDir.resolve("tmp"); // elasticsearch temporary directory
this.debugPort = DefaultLocalClusterHandle.NEXT_DEBUG_PORT.getAndIncrement();
}
Expand Down Expand Up @@ -294,6 +294,10 @@ Path getWorkingDir() {
return workingDir;
}

Path getConfigDir() {
return configDir;
}

public void waitUntilReady() {
try {
Retry.retryUntilTrue(NODE_UP_TIMEOUT, Duration.ofMillis(500), () -> {
Expand Down Expand Up @@ -426,7 +430,7 @@ private void writeConfiguration() {
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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to do this path -> file -> path conversion?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last conversion gives a String. The reason is that temporary directory created by Lucene temporariy directory, e.g. LuceneTestCase#createTempDir returns a Lucene FilterDirectory which always works for resolve(String) but throws for resolve(Path) if the given Path argument is not also a FilterDirectory. Since I changed the other PR to use Junit's TemporaryDirectory, this is no longer an issue for now. But I think it might be worthwhile to keep the change so that it does not just break if someone decides to use Lucene temporary in future?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have super strong feelings about working around idiosyncrasies with lucene types. Can this be simplified to relativePath.toString()?

if (Files.exists(dest) == false) {
Files.createDirectories(dest.getParent());
Files.copy(file, dest);
Expand Down Expand Up @@ -640,7 +644,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 ["
Expand All @@ -667,7 +671,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);
Expand Down Expand Up @@ -857,7 +861,7 @@ private void startElasticsearch() {

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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ private LocalNodeSpec build(LocalClusterSpec cluster, int nodeIndex) {
getExtraConfigFiles(),
getSystemPropertyProviders(),
getSystemProperties(),
getJvmArgs()
getJvmArgs(),
getConfigDir()
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -47,6 +48,7 @@ public abstract class AbstractLocalSpecBuilder<T extends LocalSpecBuilder<?>> im
private DistributionType distributionType;
private Version version;
private String keystorePassword;
private Path configDir;

protected AbstractLocalSpecBuilder(AbstractLocalSpecBuilder<?> parent) {
this.parent = parent;
Expand Down Expand Up @@ -270,6 +272,16 @@ public String getKeystorePassword() {
return inherit(() -> parent.getKeystorePassword(), keystorePassword);
}

@Override
public T withConfigDir(Path configDir) {
this.configDir = configDir;
return cast(this);
}

public Path getConfigDir() {
return inherit(() -> parent.getConfigDir(), configDir);
}

@Override
public T version(Version version) {
this.version = version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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<String> lines = Files.lines(configFile)) {
return lines.anyMatch(l -> l.contains("BEGIN SECURITY AUTO CONFIGURATION"));
} catch (IOException e) {
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -103,6 +104,7 @@ public static class LocalNodeSpec {
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(
Expand All @@ -124,7 +126,8 @@ public LocalNodeSpec(
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;
Expand All @@ -145,6 +148,7 @@ public LocalNodeSpec(
this.systemPropertyProviders = systemPropertyProviders;
this.systemProperties = systemProperties;
this.jvmArgs = jvmArgs;
this.configDir = configDir;
}

void setVersion(Version version) {
Expand Down Expand Up @@ -203,6 +207,10 @@ public List<String> 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"));
}
Expand Down Expand Up @@ -339,7 +347,8 @@ private LocalNodeSpec getFilteredSpec(SettingsProvider filteredProvider, Setting
n.extraConfigFiles,
n.systemPropertyProviders,
n.systemProperties,
n.jvmArgs
n.jvmArgs,
n.configDir
)
)
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 function to compute config directory based on the node name. The default config directory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to update this javadoc now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. updated in d8bb5cd

* is used when the function is null or the return value of the function is null.
*/
T withConfigDir(Path configDir);
}
Loading