diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/docker/DockerSupportService.java b/buildSrc/src/main/java/org/elasticsearch/gradle/docker/DockerSupportService.java index abc8219efd086..bc455a6e0608d 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/docker/DockerSupportService.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/docker/DockerSupportService.java @@ -311,7 +311,7 @@ public static class DockerAvailability { * */ diff --git a/qa/os/src/test/java/org/elasticsearch/packaging/test/DockerTests.java b/qa/os/src/test/java/org/elasticsearch/packaging/test/DockerTests.java index 535fdff69b290..833b448cd8ba2 100644 --- a/qa/os/src/test/java/org/elasticsearch/packaging/test/DockerTests.java +++ b/qa/os/src/test/java/org/elasticsearch/packaging/test/DockerTests.java @@ -34,6 +34,7 @@ import java.util.stream.Collectors; import static java.nio.file.attribute.PosixFilePermissions.fromString; +import static org.elasticsearch.packaging.util.Docker.assertPermissionsAndOwnership; import static org.elasticsearch.packaging.util.Docker.chownWithPrivilegeEscalation; import static org.elasticsearch.packaging.util.Docker.copyFromContainer; import static org.elasticsearch.packaging.util.Docker.existsInContainer; @@ -97,9 +98,7 @@ public void teardownTest() { /** * Checks that the Docker image can be run, and that it passes various checks. */ - public void test010Install() throws Exception { - // Wait for the container to come up, because we assert the state of some files that Elasticsearch creates on startup. - waitForElasticsearch(installation); + public void test010Install() { verifyContainerInstallation(installation, distribution()); } @@ -146,6 +145,15 @@ public void test041AmazonCaCertsAreInTheKeystore() { assertTrue("Expected Amazon trusted cert in cacerts", matches); } + /** + * Check that when the keystore is created on startup, it is created with the correct permissions. + */ + public void test042KeystorePermissionsAreCorrect() throws Exception { + waitForElasticsearch(installation); + + assertPermissionsAndOwnership(installation.config("elasticsearch.keystore"), p660); + } + /** * Send some basic index, count and delete requests, in order to check that the installation * is minimally functional. @@ -183,7 +191,7 @@ public void test070BindMountCustomPathConfAndJvmOptions() throws Exception { waitForElasticsearch(installation); - final JsonNode nodes = getJson("_nodes").get("nodes"); + final JsonNode nodes = getJson("/_nodes").get("nodes"); final String nodeId = nodes.fieldNames().next(); final int heapSize = nodes.at("/" + nodeId + "/jvm/mem/heap_init_in_bytes").intValue(); @@ -211,7 +219,7 @@ public void test071BindMountCustomPathWithDifferentUID() throws Exception { waitForElasticsearch(installation); - final JsonNode nodes = getJson("_nodes"); + final JsonNode nodes = getJson("/_nodes"); assertThat(nodes.at("/_nodes/total").intValue(), equalTo(1)); assertThat(nodes.at("/_nodes/successful").intValue(), equalTo(1)); @@ -718,7 +726,7 @@ public void test131InitProcessHasCorrectPID() { public void test140CgroupOsStatsAreAvailable() throws Exception { waitForElasticsearch(installation); - final JsonNode nodes = getJson("_nodes/stats/os").get("nodes"); + final JsonNode nodes = getJson("/_nodes/stats/os").get("nodes"); final String nodeId = nodes.fieldNames().next(); diff --git a/qa/os/src/test/java/org/elasticsearch/packaging/test/PackagingTestCase.java b/qa/os/src/test/java/org/elasticsearch/packaging/test/PackagingTestCase.java index 98d92861778cd..7ca448dd5d767 100644 --- a/qa/os/src/test/java/org/elasticsearch/packaging/test/PackagingTestCase.java +++ b/qa/os/src/test/java/org/elasticsearch/packaging/test/PackagingTestCase.java @@ -58,7 +58,6 @@ import static org.elasticsearch.packaging.util.Cleanup.cleanEverything; import static org.elasticsearch.packaging.util.Docker.ensureImageIsLoaded; import static org.elasticsearch.packaging.util.Docker.removeContainer; -import static org.elasticsearch.packaging.util.Docker.waitForElasticsearch; import static org.elasticsearch.packaging.util.FileExistenceMatchers.fileExists; import static org.elasticsearch.packaging.util.FileUtils.append; import static org.hamcrest.CoreMatchers.anyOf; @@ -214,7 +213,6 @@ protected static void install() throws Exception { case DOCKER: case DOCKER_UBI: installation = Docker.runContainer(distribution); - waitForElasticsearch(installation); Docker.verifyContainerInstallation(installation, distribution); break; default: diff --git a/qa/os/src/test/java/org/elasticsearch/packaging/util/Docker.java b/qa/os/src/test/java/org/elasticsearch/packaging/util/Docker.java index 46a2b5dc85dfa..7a42679744114 100644 --- a/qa/os/src/test/java/org/elasticsearch/packaging/util/Docker.java +++ b/qa/os/src/test/java/org/elasticsearch/packaging/util/Docker.java @@ -23,12 +23,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.stream.Stream; import static java.nio.file.attribute.PosixFilePermissions.fromString; import static org.elasticsearch.packaging.util.FileMatcher.p644; -import static org.elasticsearch.packaging.util.FileMatcher.p660; import static org.elasticsearch.packaging.util.FileMatcher.p664; import static org.elasticsearch.packaging.util.FileMatcher.p755; import static org.elasticsearch.packaging.util.FileMatcher.p770; @@ -81,6 +81,7 @@ public static void ensureImageIsLoaded(Distribution distribution) { * successfully. * * @param distribution details about the docker image being tested + * @return an installation that models the running container */ public static Installation runContainer(Distribution distribution) { return runContainer(distribution, DockerRun.builder()); @@ -92,6 +93,7 @@ public static Installation runContainer(Distribution distribution) { * * @param distribution details about the docker image being tested * @param builder the command to run + * @return an installation that models the running container */ public static Installation runContainer(Distribution distribution, DockerRun builder) { executeDockerRun(distribution, builder); @@ -289,6 +291,8 @@ public Result run(String script) { /** * Checks whether a path exists in the Docker container. + * @param path the path that ought to exist + * @return whether the path exists */ public static boolean existsInContainer(Path path) { return existsInContainer(path.toString()); @@ -296,6 +300,8 @@ public static boolean existsInContainer(Path path) { /** * Checks whether a path exists in the Docker container. + * @param path the path that ought to exist + * @return whether the path exists */ public static boolean existsInContainer(String path) { logger.debug("Checking whether file " + path + " exists in container"); @@ -394,6 +400,8 @@ public static void chownWithPrivilegeEscalation(Path localPath, String ownership /** * Checks that the specified path's permissions and ownership match those specified. + * @param path the path to check + * @param expectedPermissions the unix permissions that the path ought to have */ public static void assertPermissionsAndOwnership(Path path, Set expectedPermissions) { logger.debug("Checking permissions and ownership of [" + path + "]"); @@ -415,6 +423,7 @@ public static void assertPermissionsAndOwnership(Path path, Set assertPermissionsAndOwnership(dir, p755)); - assertPermissionsAndOwnership(es.config("elasticsearch.keystore"), p660); - Stream.of("elasticsearch.yml", "jvm.options", "log4j2.properties") .forEach(configFile -> assertPermissionsAndOwnership(es.config(configFile), p664)); @@ -538,14 +547,31 @@ public static String getContainerId() { return containerId; } + /** + * Performs an HTTP GET to http://localhost:9200/ with the supplied path. + * @param path the path to fetch, which must start with / + * @return the parsed response + */ public static JsonNode getJson(String path) throws Exception { - final String pluginsResponse = makeRequest(Request.Get("http://localhost:9200/" + path)); + path = Objects.requireNonNull(path).trim(); + if (path.isEmpty()) { + throw new IllegalArgumentException("path must be supplied"); + } + if (path.startsWith("/") == false) { + throw new IllegalArgumentException("path must start with /"); + } + final String pluginsResponse = makeRequest(Request.Get("http://localhost:9200" + path)); ObjectMapper mapper = new ObjectMapper(); return mapper.readTree(pluginsResponse); } + /** + * Fetches all the labels for a Docker image + * @param distribution required to derive the image name + * @return a mapping from label name to value + */ public static Map getImageLabels(Distribution distribution) throws Exception { // The format below extracts the .Config.Labels value, and prints it as json. Without the json // modifier, a stringified Go map is printed instead, which isn't helpful.