Use official checksums to verify Tini (#55717)
Firstly, backport the use of tini as the Docker entrypoint. This was supposed to have been done following #50277, but was missed. It isn't a direct backport as this branch will continue using root as the initial Docker user. Secondly, backport #55491 to use the official checksums when downloading tini.
This commit is contained in:
parent
e0a8adb5b2
commit
c2c14e8875
|
@ -28,22 +28,32 @@ dependencies {
|
|||
}
|
||||
|
||||
ext.expansions = { architecture, oss, local ->
|
||||
String base_image = null
|
||||
String tini_arch = null
|
||||
String classifier = null
|
||||
switch (architecture) {
|
||||
case "aarch64":
|
||||
base_image = "arm64v8/centos:7"
|
||||
tini_arch = "arm64"
|
||||
classifier = "linux-aarch64"
|
||||
break;
|
||||
case "x64":
|
||||
base_image = "amd64/centos:7"
|
||||
tini_arch = "amd64"
|
||||
classifier = "linux-x86_64"
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unrecongized architecture [" + architecture + "], must be one of (aarch64|x64)")
|
||||
}
|
||||
final String classifier = "aarch64".equals(architecture) ? "linux-aarch64" : "linux-x86_64"
|
||||
final String elasticsearch = oss ? "elasticsearch-oss-${VersionProperties.elasticsearch}-${classifier}.tar.gz" : "elasticsearch-${VersionProperties.elasticsearch}-${classifier}.tar.gz"
|
||||
return [
|
||||
'base_image' : "aarch64".equals(architecture) ? "arm64v8/centos:7" : "centos:7",
|
||||
'base_image' : base_image,
|
||||
'build_date' : BuildParams.buildDate,
|
||||
'elasticsearch' : elasticsearch,
|
||||
'git_revision' : BuildParams.gitRevision,
|
||||
'license' : oss ? 'Apache-2.0' : 'Elastic-License',
|
||||
'source_elasticsearch': local ? "COPY $elasticsearch /opt/" : "RUN cd /opt && curl --retry 8 -s -L -O https://artifacts.elastic.co/downloads/elasticsearch/${elasticsearch} && cd -",
|
||||
'tini_arch' : tini_arch,
|
||||
'version' : VersionProperties.elasticsearch
|
||||
]
|
||||
}
|
||||
|
@ -227,6 +237,7 @@ subprojects { Project subProject ->
|
|||
def tarFile = "${parent.projectDir}/build/elasticsearch${"aarch64".equals(architecture) ? '-aarch64' : ''}${oss ? '-oss' : ''}_test.${VersionProperties.elasticsearch}.docker.tar"
|
||||
|
||||
final Task exportDockerImageTask = task(exportTaskName, type: LoggedExec) {
|
||||
inputs.file("${parent.projectDir}/build/markers/${buildTaskName}.marker")
|
||||
executable 'docker'
|
||||
outputs.file(tarFile)
|
||||
args "save",
|
||||
|
|
|
@ -14,10 +14,22 @@
|
|||
FROM ${base_image} AS builder
|
||||
|
||||
RUN for iter in {1..10}; do yum update --setopt=tsflags=nodocs -y && \
|
||||
yum install --setopt=tsflags=nodocs -y gzip shadow-utils tar && \
|
||||
yum install --setopt=tsflags=nodocs -y wget gzip shadow-utils tar && \
|
||||
yum clean all && exit_code=0 && break || exit_code=\$? && echo "yum error: retry \$iter in 10s" && sleep 10; done; \
|
||||
(exit \$exit_code)
|
||||
|
||||
# `tini` is a tiny but valid init for containers. This is used to cleanly
|
||||
# control how ES and any child processes are shut down.
|
||||
#
|
||||
# The tini GitHub page gives instructions for verifying the binary using
|
||||
# gpg, but the keyservers are slow to return the key and this can fail the
|
||||
# build. Instead, we check the binary against a checksum that they provide.
|
||||
RUN wget --no-cookies --quiet https://github.com/krallin/tini/releases/download/v0.19.0/tini-${tini_arch} \
|
||||
&& wget --no-cookies --quiet https://github.com/krallin/tini/releases/download/v0.19.0/tini-${tini_arch}.sha256sum \
|
||||
&& sha256sum -c tini-${tini_arch}.sha256sum \
|
||||
&& mv tini-${tini_arch} /tini \
|
||||
&& chmod +x /tini
|
||||
|
||||
ENV PATH /usr/share/elasticsearch/bin:\$PATH
|
||||
|
||||
RUN groupadd -g 1000 elasticsearch && \
|
||||
|
@ -45,6 +57,8 @@ FROM ${base_image}
|
|||
|
||||
ENV ELASTIC_CONTAINER true
|
||||
|
||||
COPY --from=builder /tini /tini
|
||||
|
||||
RUN for iter in {1..10}; do yum update --setopt=tsflags=nodocs -y && \
|
||||
yum install --setopt=tsflags=nodocs -y nc shadow-utils zip unzip && \
|
||||
yum clean all && exit_code=0 && break || exit_code=\$? && echo "yum error: retry \$iter in 10s" && sleep 10; done; \
|
||||
|
@ -65,17 +79,14 @@ RUN ln -sf /etc/pki/ca-trust/extracted/java/cacerts /usr/share/elasticsearch/jdk
|
|||
|
||||
ENV PATH /usr/share/elasticsearch/bin:\$PATH
|
||||
|
||||
COPY --chown=1000:0 bin/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
COPY bin/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
RUN chmod g=u /etc/passwd && \
|
||||
chmod 0775 /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Ensure that there are no files with setuid or setgid, in order to mitigate "stackclash" attacks.
|
||||
RUN find / -xdev -perm -4000 -exec chmod ug-s {} +
|
||||
|
||||
# Openshift overrides USER and uses ones with randomly uid>1024 and gid=0
|
||||
# Allow ENTRYPOINT (and ES) to run even with a different user
|
||||
RUN chgrp 0 /usr/local/bin/docker-entrypoint.sh && \
|
||||
chmod g=u /etc/passwd && \
|
||||
chmod 0775 /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
EXPOSE 9200 9300
|
||||
|
||||
LABEL org.label-schema.build-date="${build_date}" \
|
||||
|
@ -98,7 +109,7 @@ LABEL org.label-schema.build-date="${build_date}" \
|
|||
org.opencontainers.image.vendor="Elastic" \
|
||||
org.opencontainers.image.version="${version}"
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||
ENTRYPOINT ["/tini", "--", "/usr/local/bin/docker-entrypoint.sh"]
|
||||
# Dummy overridable parameter parsed by entrypoint
|
||||
CMD ["eswrapper"]
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ import static org.hamcrest.Matchers.hasSize;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
|
@ -139,7 +140,7 @@ public class DockerTests extends PackagingTestCase {
|
|||
/**
|
||||
* Checks that there are Amazon trusted certificates in the cacaerts keystore.
|
||||
*/
|
||||
public void test043AmazonCaCertsAreInTheKeystore() {
|
||||
public void test041AmazonCaCertsAreInTheKeystore() {
|
||||
final boolean matches = Arrays.stream(
|
||||
sh.run("jdk/bin/keytool -cacerts -storepass changeit -list | grep trustedCertEntry").stdout.split("\n")
|
||||
).anyMatch(line -> line.contains("amazonrootca"));
|
||||
|
@ -251,8 +252,8 @@ public class DockerTests extends PackagingTestCase {
|
|||
waitForElasticsearch("green", null, installation, "elastic", "hunter2");
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(
|
||||
"Failed to check whether Elasticsearch had started. This could be because authentication isn't working properly. "
|
||||
+ "Check the container logs",
|
||||
"Failed to check whether Elasticsearch had started. This could be because "
|
||||
+ "authentication isn't working properly. Check the container logs",
|
||||
e
|
||||
);
|
||||
}
|
||||
|
@ -335,8 +336,7 @@ public class DockerTests extends PackagingTestCase {
|
|||
|
||||
Files.write(tempDir.resolve(passwordFilename), "hunter2\n".getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
Map<String, String> envVars = new HashMap<>();
|
||||
envVars.put("ELASTIC_PASSWORD_FILE", "/run/secrets/" + passwordFilename);
|
||||
Map<String, String> envVars = singletonMap("ELASTIC_PASSWORD_FILE", "/run/secrets/" + passwordFilename);
|
||||
|
||||
// Set invalid file permissions
|
||||
Files.setPosixFilePermissions(tempDir.resolve(passwordFilename), p660);
|
||||
|
@ -484,7 +484,6 @@ public class DockerTests extends PackagingTestCase {
|
|||
|
||||
/**
|
||||
* Check that the Docker image has the expected "Label Schema" labels.
|
||||
*
|
||||
* @see <a href="http://label-schema.org/">Label Schema website</a>
|
||||
*/
|
||||
public void test110OrgLabelSchemaLabels() throws Exception {
|
||||
|
@ -526,7 +525,6 @@ public class DockerTests extends PackagingTestCase {
|
|||
|
||||
/**
|
||||
* Check that the Docker image has the expected "Open Containers Annotations" labels.
|
||||
*
|
||||
* @see <a href="https://github.com/opencontainers/image-spec/blob/master/annotations.md">Open Containers Annotations</a>
|
||||
*/
|
||||
public void test110OrgOpencontainersLabels() throws Exception {
|
||||
|
@ -577,10 +575,10 @@ public class DockerTests extends PackagingTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check that the Java process running inside the container has the expect PID, UID and username.
|
||||
* Check that the Java process running inside the container has the expected UID, GID and username.
|
||||
*/
|
||||
public void test130JavaHasCorrectPidAndOwnership() {
|
||||
final List<String> processes = Arrays.stream(sh.run("ps -o pid,uid,user -C java").stdout.split("\n"))
|
||||
public void test130JavaHasCorrectOwnership() {
|
||||
final List<String> processes = Arrays.stream(sh.run("ps -o uid,gid,user -C java").stdout.split("\n"))
|
||||
.skip(1)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
@ -589,11 +587,34 @@ public class DockerTests extends PackagingTestCase {
|
|||
final String[] fields = processes.get(0).trim().split("\\s+");
|
||||
|
||||
assertThat(fields, arrayWithSize(3));
|
||||
assertThat("Incorrect PID", fields[0], equalTo("1"));
|
||||
assertThat("Incorrect UID", fields[1], equalTo("1000"));
|
||||
assertThat("Incorrect UID", fields[0], equalTo("1000"));
|
||||
assertThat("Incorrect GID", fields[1], equalTo("0"));
|
||||
assertThat("Incorrect username", fields[2], equalTo("elasticsearch"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the init process running inside the container has the expected PID, UID, GID and user.
|
||||
* The PID is particularly important because PID 1 handles signal forwarding and child reaping.
|
||||
*/
|
||||
public void test131InitProcessHasCorrectPID() {
|
||||
final List<String> processes = Arrays.stream(sh.run("ps -o pid,uid,gid,command -p 1").stdout.split("\n"))
|
||||
.skip(1)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat("Expected a single process", processes, hasSize(1));
|
||||
|
||||
final String[] fields = processes.get(0).trim().split("\\s+", 4);
|
||||
|
||||
assertThat(fields, arrayWithSize(4));
|
||||
assertThat("Incorrect PID", fields[0], equalTo("1"));
|
||||
assertThat("Incorrect UID", fields[1], equalTo("0"));
|
||||
assertThat("Incorrect GID", fields[2], equalTo("0"));
|
||||
assertThat("Incorrect init command", fields[3], startsWith("/tini"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that Elasticsearch reports per-node cgroup information.
|
||||
*/
|
||||
public void test140CgroupOsStatsAreAvailable() throws Exception {
|
||||
waitForElasticsearch(installation);
|
||||
|
||||
|
|
Loading…
Reference in New Issue