Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix packaging tests after addition of new wolfi-based image #112831

Merged
merged 21 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .buildkite/hooks/pre-command
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,33 @@ if [[ "${USE_PROD_DOCKER_CREDENTIALS:-}" == "true" ]]; then

DOCKER_REGISTRY_PASSWORD="$(vault read -field=password secret/ci/elastic-elasticsearch/migrated/prod_docker_registry_credentials)"
export DOCKER_REGISTRY_PASSWORD

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you just do docker login --username "$DOCKER_REGISTRY_USERNAME" --password "$DOCKER_REGISTRY_PASSWORD" docker.elastic.co instead of all of this stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(and by "can you" I mean: do you know if it works?)

Copy link
Contributor

Choose a reason for hiding this comment

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

@brianseeders I tried that and the problem with that is, that we run this logic on all OS types, even those which don't have docker installed. using this file only approach allows not failing on those systems. Alternatively we could just not fail if docker is not available but that approach did not seem better than this file based one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In that case, I would do:

if which docker > /dev/null 2>&1; then
  docker login --username "$DOCKER_REGISTRY_USERNAME" --password "$DOCKER_REGISTRY_PASSWORD" docker.elastic.co
fi

which has the advantage of not blowing away the existing docker config if there is one.

And probably move the vault lookups into the if as well, since they're useless on OSes that don't have docker, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

applied your suggestion

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would approve the PR but you'll have to since I opened it

# Base64 encode the username:password
ENCODED_AUTH=$(echo -n "${DOCKER_REGISTRY_USERNAME}:${DOCKER_REGISTRY_PASSWORD}" | base64)

DOCKER_REGISTRY_URL="docker.elastic.co"

# Create the config.json file with the necessary structure
CONFIG_JSON=$(cat <<EOF
{
"auths": {
"${DOCKER_REGISTRY_URL}": {
"auth": "${ENCODED_AUTH}"
}
}
}
EOF
)

# Define the Docker config directory path (default is ~/.docker)
DOCKER_CONFIG_PATH="${HOME}/.docker"

# Create the Docker config directory if it doesn't exist
mkdir -p ${DOCKER_CONFIG_PATH}

# Write the config.json to the Docker config directory
echo "${CONFIG_JSON}" > ${DOCKER_CONFIG_PATH}/config.json
export DOCKER_CONFIG_PATH
fi

if [[ "$BUILDKITE_AGENT_META_DATA_PROVIDER" != *"k8s"* ]]; then
Expand Down
3 changes: 2 additions & 1 deletion .buildkite/pipelines/periodic-packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ steps:
image: family/elasticsearch-{{matrix.image}}
diskSizeGb: 350
machineType: n1-standard-8
env: {}
env:
USE_PROD_DOCKER_CREDENTIALS: "true"
- group: packaging-tests-upgrade
steps:
- label: "{{matrix.image}} / 8.0.1 / packaging-tests-upgrade"
Expand Down
1 change: 1 addition & 0 deletions .ci/scripts/packaging-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,6 @@ sudo -E env \
--unset=ES_JAVA_HOME \
--unset=JAVA_HOME \
SYSTEM_JAVA_HOME=`readlink -f -n $BUILD_JAVA_HOME` \
DOCKER_CONFIG="${HOME}/.docker" \
./gradlew -g $HOME/.gradle --scan --parallel --build-cache -Dorg.elasticsearch.build.cache.url=https://gradle-enterprise.elastic.co/cache/ --continue $@

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.TaskAction;
import org.gradle.process.ExecOperations;
import org.gradle.process.ExecSpec;
import org.gradle.workers.WorkAction;
import org.gradle.workers.WorkParameters;
import org.gradle.workers.WorkerExecutor;
Expand Down Expand Up @@ -166,6 +167,7 @@ private void pullBaseImage(String baseImage) {
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
try {
LoggedExec.exec(execOperations, spec -> {
maybeConfigureDockerConfig(spec);
spec.executable("docker");
spec.args("pull");
spec.args(baseImage);
Expand All @@ -181,6 +183,13 @@ private void pullBaseImage(String baseImage) {
throw new GradleException("Failed to pull Docker base image [" + baseImage + "], all attempts failed");
}

private void maybeConfigureDockerConfig(ExecSpec spec) {
String dockerConfig = System.getenv("DOCKER_CONFIG");
if (dockerConfig != null) {
spec.environment("DOCKER_CONFIG", dockerConfig);
}
}

@Override
public void execute() {
final Parameters parameters = getParameters();
Expand All @@ -193,6 +202,8 @@ public void execute() {
final boolean isCrossPlatform = isCrossPlatform();

LoggedExec.exec(execOperations, spec -> {
maybeConfigureDockerConfig(spec);

spec.executable("docker");

if (isCrossPlatform) {
Expand Down
13 changes: 11 additions & 2 deletions distribution/docker/src/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,16 @@ RUN <%= retry.loop(package_manager,
" ${package_manager} update && \n" +
" ${package_manager} upgrade && \n" +
" ${package_manager} add --no-cache \n" +
" bash ca-certificates curl libsystemd netcat-openbsd p11-kit p11-kit-trust shadow tini unzip zip zstd && \n" +
" bash java-cacerts curl libstdc++ libsystemd netcat-openbsd p11-kit p11-kit-trust posix-libc-utils shadow tini unzip zip zstd && \n" +
" rm -rf /var/cache/apk/* "
) %>

# Set Bash as the default shell for future commands
SHELL ["/bin/bash", "-c"]

# Optionally set Bash as the default shell in the container at runtime
CMD ["/bin/bash"]

<% } else if (docker_base == "default" || docker_base == "cloud") { %>

# Change default shell to bash, then install required packages with retries.
Expand Down Expand Up @@ -224,7 +231,7 @@ COPY --from=builder --chown=0:0 /opt /opt
<% } %>

ENV PATH /usr/share/elasticsearch/bin:\$PATH

ENV SHELL /bin/bash
COPY ${bin_dir}/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh

# 1. Sync the user and group permissions of /etc/passwd
Expand All @@ -249,6 +256,8 @@ RUN chmod g=u /etc/passwd && \\
# stays up-to-date with changes to Ubuntu's store)
COPY bin/docker-openjdk /etc/ca-certificates/update.d/docker-openjdk
RUN /etc/ca-certificates/update.d/docker-openjdk
<% } else if (docker_base == 'wolfi') { %>
RUN ln -sf /etc/ssl/certs/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
<% } else { %>
RUN ln -sf /etc/pki/ca-trust/extracted/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
<% } %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,9 @@ public void test040JavaUsesTheOsProvidedKeystore() {
if (distribution.packaging == Packaging.DOCKER_UBI || distribution.packaging == Packaging.DOCKER_IRON_BANK) {
// In these images, the `cacerts` file ought to be a symlink here
assertThat(path, equalTo("/etc/pki/ca-trust/extracted/java/cacerts"));
} else if (distribution.packaging == Packaging.DOCKER_WOLFI) {
// In these images, the `cacerts` file ought to be a symlink here
assertThat(path, equalTo("/etc/ssl/certs/java/cacerts"));
} else {
// Whereas on other images, it's a real file so the real path is the same
assertThat(path, equalTo("/usr/share/elasticsearch/jdk/lib/security/cacerts"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,10 @@ private void verifyKeystorePermissions() {
switch (distribution.packaging) {
case TAR, ZIP -> assertThat(keystore, file(File, ARCHIVE_OWNER, ARCHIVE_OWNER, p660));
case DEB, RPM -> assertThat(keystore, file(File, "root", "elasticsearch", p660));
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS -> assertThat(keystore, DockerFileMatcher.file(p660));
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> assertThat(
keystore,
DockerFileMatcher.file(p660)
);
default -> throw new IllegalStateException("Unknown Elasticsearch packaging type.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ protected static void install() throws Exception {
installation = Packages.installPackage(sh, distribution);
Packages.verifyPackageInstallation(installation, distribution, sh);
}
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS -> {
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> {
installation = Docker.runContainer(distribution);
Docker.verifyContainerInstallation(installation);
}
Expand Down Expand Up @@ -337,6 +337,7 @@ public Shell.Result runElasticsearchStartCommand(String password, boolean daemon
case DOCKER_IRON_BANK:
case DOCKER_CLOUD:
case DOCKER_CLOUD_ESS:
case DOCKER_WOLFI:
// nothing, "installing" docker image is running it
return Shell.NO_OP;
default:
Expand All @@ -359,6 +360,7 @@ public void stopElasticsearch() throws Exception {
case DOCKER_IRON_BANK:
case DOCKER_CLOUD:
case DOCKER_CLOUD_ESS:
case DOCKER_WOLFI:
// nothing, "installing" docker image is running it
break;
default:
Expand All @@ -371,7 +373,7 @@ public void awaitElasticsearchStartup(Shell.Result result) throws Exception {
switch (distribution.packaging) {
case TAR, ZIP -> Archives.assertElasticsearchStarted(installation);
case DEB, RPM -> Packages.assertElasticsearchStarted(sh, installation);
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS -> Docker.waitForElasticsearchToStart();
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> Docker.waitForElasticsearchToStart();
default -> throw new IllegalStateException("Unknown Elasticsearch packaging type.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public Distribution(Path path) {
this.packaging = Packaging.DOCKER_CLOUD;
} else if (filename.endsWith(".cloud-ess.tar")) {
this.packaging = Packaging.DOCKER_CLOUD_ESS;
} else if (filename.endsWith(".wolfi.tar")) {
this.packaging = Packaging.DOCKER_WOLFI;
} else {
int lastDot = filename.lastIndexOf('.');
this.packaging = Packaging.valueOf(filename.substring(lastDot + 1).toUpperCase(Locale.ROOT));
Expand All @@ -61,7 +63,7 @@ public boolean isPackage() {
*/
public boolean isDocker() {
return switch (packaging) {
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS -> true;
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> true;
default -> false;
};
}
Expand All @@ -76,7 +78,8 @@ public enum Packaging {
DOCKER_UBI(".ubi.tar", Platforms.isDocker()),
DOCKER_IRON_BANK(".ironbank.tar", Platforms.isDocker()),
DOCKER_CLOUD(".cloud.tar", Platforms.isDocker()),
DOCKER_CLOUD_ESS(".cloud-ess.tar", Platforms.isDocker());
DOCKER_CLOUD_ESS(".cloud-ess.tar", Platforms.isDocker()),
DOCKER_WOLFI(".wolfi.tar", Platforms.isDocker());

/** The extension of this distribution's file */
public final String extension;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,9 @@ public static void verifyContainerInstallation(Installation es) {
// Ensure the `elasticsearch` user and group exist.
// These lines will both throw an exception if the command fails
dockerShell.run("id elasticsearch");
dockerShell.run("getent group elasticsearch");
dockerShell.run("grep -E '^elasticsearch:' /etc/group");

final Shell.Result passwdResult = dockerShell.run("getent passwd elasticsearch");
final Shell.Result passwdResult = dockerShell.run("grep -E '^elasticsearch:' /etc/passwd");
final String homeDir = passwdResult.stdout().trim().split(":")[5];
assertThat("elasticsearch user's home directory is incorrect", homeDir, equalTo("/usr/share/elasticsearch"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public static String getImageName(Distribution distribution) {
case DOCKER_IRON_BANK -> "-ironbank";
case DOCKER_CLOUD -> "-cloud";
case DOCKER_CLOUD_ESS -> "-cloud-ess";
case DOCKER_WOLFI -> "-wolfi";
default -> throw new IllegalStateException("Unexpected distribution packaging type: " + distribution.packaging);
};

Expand Down
Loading