Skip to content

Commit 54ecb2c

Browse files
authored
Add wolfi ess docker image (#113810) (#114111)
(cherry picked from commit 54c83d7)
1 parent 821212f commit 54ecb2c

File tree

20 files changed

+220
-61
lines changed

20 files changed

+220
-61
lines changed

.buildkite/pipelines/periodic-packaging.template.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ steps:
33
steps:
44
- label: "{{matrix.image}} / packaging-tests-unix"
55
command: ./.ci/scripts/packaging-test.sh destructivePackagingTest
6-
timeout_in_minutes: 300
6+
timeout_in_minutes: 420
77
matrix:
88
setup:
99
image:

.buildkite/pipelines/periodic-packaging.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ steps:
44
steps:
55
- label: "{{matrix.image}} / packaging-tests-unix"
66
command: ./.ci/scripts/packaging-test.sh destructivePackagingTest
7-
timeout_in_minutes: 300
7+
timeout_in_minutes: 420
88
matrix:
99
setup:
1010
image:

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ public enum DockerBase {
3333
"docker.elastic.co/wolfi/chainguard-base:latest@sha256:c16d3ad6cebf387e8dd2ad769f54320c4819fbbaa21e729fad087c7ae223b4d0",
3434
"-wolfi",
3535
"apk"
36-
);
36+
),
37+
38+
// Based on WOLFI above, with more extras. We don't set a base image because
39+
// we programmatically extend from the Wolfi image.
40+
WOLFI_ESS(null, "-wolfi-ess", "apk");
3741

3842
private final String image;
3943
private final String suffix;

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ private static String distributionProjectName(ElasticsearchDistribution distribu
181181
if (distribution.getType() == InternalElasticsearchDistributionTypes.DOCKER_WOLFI) {
182182
return projectName + "wolfi-docker" + archString + "-export";
183183
}
184+
if (distribution.getType() == InternalElasticsearchDistributionTypes.DOCKER_WOLFI_ESS) {
185+
return projectName + "wolfi-ess-docker" + archString + "-export";
186+
}
184187
return projectName + distribution.getType().getName();
185188
}
186189

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.gradle.internal.distribution;
11+
12+
import org.elasticsearch.gradle.ElasticsearchDistributionType;
13+
14+
public class DockerWolfiEssElasticsearchDistributionType implements ElasticsearchDistributionType {
15+
16+
DockerWolfiEssElasticsearchDistributionType() {}
17+
18+
@Override
19+
public String getName() {
20+
return "dockerWolfiEss";
21+
}
22+
23+
@Override
24+
public boolean isDocker() {
25+
return true;
26+
}
27+
}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/distribution/InternalElasticsearchDistributionTypes.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class InternalElasticsearchDistributionTypes {
2222
public static ElasticsearchDistributionType DOCKER_CLOUD = new DockerCloudElasticsearchDistributionType();
2323
public static ElasticsearchDistributionType DOCKER_CLOUD_ESS = new DockerCloudEssElasticsearchDistributionType();
2424
public static ElasticsearchDistributionType DOCKER_WOLFI = new DockerWolfiElasticsearchDistributionType();
25+
public static ElasticsearchDistributionType DOCKER_WOLFI_ESS = new DockerWolfiEssElasticsearchDistributionType();
2526

2627
public static List<ElasticsearchDistributionType> ALL_INTERNAL = List.of(
2728
DEB,
@@ -31,6 +32,7 @@ public class InternalElasticsearchDistributionTypes {
3132
DOCKER_IRONBANK,
3233
DOCKER_CLOUD,
3334
DOCKER_CLOUD_ESS,
34-
DOCKER_WOLFI
35+
DOCKER_WOLFI,
36+
DOCKER_WOLFI_ESS
3537
);
3638
}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/DistroTestPlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import static org.elasticsearch.gradle.internal.distribution.InternalElasticsearchDistributionTypes.DOCKER_IRONBANK;
5555
import static org.elasticsearch.gradle.internal.distribution.InternalElasticsearchDistributionTypes.DOCKER_UBI;
5656
import static org.elasticsearch.gradle.internal.distribution.InternalElasticsearchDistributionTypes.DOCKER_WOLFI;
57+
import static org.elasticsearch.gradle.internal.distribution.InternalElasticsearchDistributionTypes.DOCKER_WOLFI_ESS;
5758
import static org.elasticsearch.gradle.internal.distribution.InternalElasticsearchDistributionTypes.RPM;
5859

5960
/**
@@ -152,6 +153,7 @@ private static Map<ElasticsearchDistributionType, TaskProvider<?>> lifecycleTask
152153
lifecyleTasks.put(DOCKER_CLOUD, project.getTasks().register(taskPrefix + ".docker-cloud"));
153154
lifecyleTasks.put(DOCKER_CLOUD_ESS, project.getTasks().register(taskPrefix + ".docker-cloud-ess"));
154155
lifecyleTasks.put(DOCKER_WOLFI, project.getTasks().register(taskPrefix + ".docker-wolfi"));
156+
lifecyleTasks.put(DOCKER_WOLFI_ESS, project.getTasks().register(taskPrefix + ".docker-wolfi-ess"));
155157
lifecyleTasks.put(ARCHIVE, project.getTasks().register(taskPrefix + ".archives"));
156158
lifecyleTasks.put(DEB, project.getTasks().register(taskPrefix + ".packages"));
157159
lifecyleTasks.put(RPM, lifecyleTasks.get(DEB));

distribution/docker/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ the [DockerBase] enum.
77
* UBI - the same as the default image, but based upon [RedHat's UBI
88
images][ubi], specifically their minimal flavour.
99
* Wolfi - the same as the default image, but based upon [Wolfi](https://github.com/wolfi-dev)
10+
* Wolfi ESS - this directly extends the Wolfi image, and adds all ES plugins
11+
that the ES build generates in an archive directory. It also sets an
12+
environment variable that points at this directory. This allows plugins to
13+
be installed from the archive instead of the internet, speeding up
14+
deployment times. Furthermore this image has
15+
* `filebeat` and `metricbeat` included
16+
* `wget` included
17+
* The `ENTRYPOINT` is just `/sbin/tini`, and the `CMD` is
18+
`/app/elasticsearch.sh`. In normal use this file would be bind-mounted
19+
in, but the image ships a stub version of this file so that the image
20+
can still be tested.
1021
* Iron Bank - this is the US Department of Defence's repository of digitally
1122
signed, binary container images including both Free and Open-Source
1223
software (FOSS) and Commercial off-the-shelf (COTS). In practice, this is
@@ -17,7 +28,7 @@ the [DockerBase] enum.
1728
* `filebeat` and `metricbeat` are included
1829
* `wget` is included
1930
* The `ENTRYPOINT` is just `/bin/tini`, and the `CMD` is
20-
`/app/elasticsearc.sh`. In normal use this file would be bind-mounted
31+
`/app/elasticsearch.sh`. In normal use this file would be bind-mounted
2132
in, but the image ships a stub version of this file so that the image
2233
can still be tested.
2334
* Cloud ESS - this directly extends the Cloud image, and adds all ES plugins

distribution/docker/build.gradle

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import org.elasticsearch.gradle.Architecture
21
import org.elasticsearch.gradle.LoggedExec
32
import org.elasticsearch.gradle.VersionProperties
43
import org.elasticsearch.gradle.internal.DockerBase
@@ -8,8 +7,10 @@ import org.elasticsearch.gradle.internal.docker.DockerSupportPlugin
87
import org.elasticsearch.gradle.internal.docker.DockerSupportService
98
import org.elasticsearch.gradle.internal.docker.ShellRetry
109
import org.elasticsearch.gradle.internal.docker.TransformLog4jConfigFilter
10+
import org.elasticsearch.gradle.internal.docker.*
1111
import org.elasticsearch.gradle.internal.info.BuildParams
1212
import org.elasticsearch.gradle.util.GradleUtils
13+
import org.elasticsearch.gradle.Architecture
1314
import java.nio.file.Path
1415
import java.time.temporal.ChronoUnit
1516

@@ -99,9 +100,9 @@ String tiniArch = Architecture.current() == Architecture.AARCH64 ? 'arm64' : 'am
99100

100101
dependencies {
101102
aarch64DockerSource project(":distribution:archives:linux-aarch64-tar")
102-
aarch64DockerSourceTar project(path: ":distribution:archives:linux-aarch64-tar", configuration:"default")
103+
aarch64DockerSourceTar project(path: ":distribution:archives:linux-aarch64-tar", configuration: "default")
103104
dockerSource project(":distribution:archives:linux-tar")
104-
dockerSourceTar project(path: ":distribution:archives:linux-tar", configuration:"default")
105+
dockerSourceTar project(path: ":distribution:archives:linux-tar", configuration: "default")
105106
log4jConfig project(path: ":distribution", configuration: 'log4jConfig')
106107
tini "krallin:tini:0.19.0:${tiniArch}"
107108
allPlugins project(path: ':plugins', configuration: 'allPlugins')
@@ -112,7 +113,7 @@ dependencies {
112113
}
113114

114115
ext.expansions = { Architecture architecture, DockerBase base ->
115-
def (major,minor) = VersionProperties.elasticsearch.split("\\.")
116+
def (major, minor) = VersionProperties.elasticsearch.split("\\.")
116117

117118
// We tag our Docker images with various pieces of information, including a timestamp
118119
// for when the image was built. However, this makes it impossible completely cache
@@ -216,7 +217,8 @@ elasticsearch_distributions {
216217
}
217218

218219
interface Injected {
219-
@Inject FileSystemOperations getFs()
220+
@Inject
221+
FileSystemOperations getFs()
220222
}
221223

222224
tasks.named("preProcessFixture").configure {
@@ -300,7 +302,10 @@ void addBuildDockerContextTask(Architecture architecture, DockerBase base) {
300302
// For some reason, the artifact name can differ depending on what repository we used.
301303
rename ~/((?:file|metric)beat)-.*\.tar\.gz$/, "\$1-${VersionProperties.elasticsearch}.tar.gz"
302304
}
303-
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(project.gradle.sharedServices, DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME)
305+
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(
306+
project.gradle.sharedServices,
307+
DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME
308+
)
304309
onlyIf("$architecture supported") { serviceProvider.get().isArchitectureSupported(architecture) }
305310
}
306311

@@ -337,9 +342,9 @@ void addTransformDockerContextTask(Architecture architecture, DockerBase base) {
337342
into "${project.buildDir}/docker-context/${archiveName}"
338343

339344
// Since we replaced the remote URL in the Dockerfile, copy in the required file
340-
if(base == DockerBase.IRON_BANK) {
345+
if (base == DockerBase.IRON_BANK) {
341346
from(architecture == Architecture.AARCH64 ? configurations.aarch64DockerSourceTar : configurations.dockerSourceTar)
342-
from (configurations.tini) {
347+
from(configurations.tini) {
343348
rename { _ -> 'tini' }
344349
}
345350
} else {
@@ -349,7 +354,10 @@ void addTransformDockerContextTask(Architecture architecture, DockerBase base) {
349354
expansions(architecture, base).findAll { it.key != 'build_date' }.each { k, v ->
350355
inputs.property(k, { v.toString() })
351356
}
352-
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(project.gradle.sharedServices, DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME)
357+
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(
358+
project.gradle.sharedServices,
359+
DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME
360+
)
353361
onlyIf("$architecture supported") { serviceProvider.get().isArchitectureSupported(architecture) }
354362
}
355363

@@ -373,7 +381,7 @@ private static List<String> generateTags(DockerBase base, Architecture architect
373381
String image = "elasticsearch${base.suffix}"
374382

375383
String namespace = 'elasticsearch'
376-
if (base == DockerBase.CLOUD || base == DockerBase.CLOUD_ESS) {
384+
if (base == DockerBase.CLOUD || base == DockerBase.CLOUD_ESS || base == DockerBase.WOLFI_ESS) {
377385
namespace += '-ci'
378386
}
379387

@@ -423,7 +431,10 @@ void addBuildDockerImageTask(Architecture architecture, DockerBase base) {
423431
baseImages = [base.image]
424432
}
425433

426-
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(project.gradle.sharedServices, DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME)
434+
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(
435+
project.gradle.sharedServices,
436+
DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME
437+
)
427438
onlyIf("$architecture supported") { serviceProvider.get().isArchitectureSupported(architecture) }
428439

429440
}
@@ -435,13 +446,12 @@ void addBuildDockerImageTask(Architecture architecture, DockerBase base) {
435446
}
436447
}
437448

438-
void addBuildEssDockerImageTask(Architecture architecture) {
439-
DockerBase base = DockerBase.CLOUD_ESS
449+
void addBuildEssDockerImageTask(Architecture architecture, DockerBase dockerBase) {
440450
String arch = architecture == Architecture.AARCH64 ? '-aarch64' : ''
441-
String contextDir = "${project.buildDir}/docker-context/elasticsearch${base.suffix}-${VersionProperties.elasticsearch}-docker-build-context${arch}"
451+
String contextDir = "${project.buildDir}/docker-context/elasticsearch${dockerBase.suffix}-${VersionProperties.elasticsearch}-docker-build-context${arch}"
442452

443453
final TaskProvider<Sync> buildContextTask =
444-
tasks.register(taskName('build', architecture, base, 'DockerContext'), Sync) {
454+
tasks.register(taskName('build', architecture, dockerBase, 'DockerContext'), Sync) {
445455
into contextDir
446456

447457
final Path projectDir = project.projectDir.toPath()
@@ -450,28 +460,54 @@ void addBuildEssDockerImageTask(Architecture architecture) {
450460
from configurations.allPlugins
451461
}
452462

453-
from(projectDir.resolve("src/docker/Dockerfile.cloud-ess")) {
454-
expand([
455-
base_image: "elasticsearch${DockerBase.CLOUD.suffix}:${architecture.classifier}"
456-
])
463+
if (dockerBase == DockerBase.WOLFI_ESS) {
464+
// If we're performing a release build, but `build.id` hasn't been set, we can
465+
// infer that we're not at the Docker building stage of the build, and therefore
466+
// we should skip the beats part of the build.
467+
String buildId = providers.systemProperty('build.id').getOrNull()
468+
boolean includeBeats = VersionProperties.isElasticsearchSnapshot() == true || buildId != null || useDra
469+
470+
if (includeBeats) {
471+
from configurations.getByName("filebeat_${architecture.classifier}")
472+
from configurations.getByName("metricbeat_${architecture.classifier}")
473+
}
474+
// For some reason, the artifact name can differ depending on what repository we used.
475+
rename ~/((?:file|metric)beat)-.*\.tar\.gz$/, "\$1-${VersionProperties.elasticsearch}.tar.gz"
476+
}
477+
478+
String baseSuffix = dockerBase == DockerBase.CLOUD_ESS ? DockerBase.CLOUD.suffix : DockerBase.WOLFI.suffix
479+
from(projectDir.resolve("src/docker/Dockerfile.ess")) {
480+
expand(
481+
[
482+
base_image: "elasticsearch${baseSuffix}:${architecture.classifier}",
483+
docker_base: "${dockerBase.name().toLowerCase()}",
484+
version: "${VersionProperties.elasticsearch}",
485+
retry: ShellRetry
486+
]
487+
)
457488
filter SquashNewlinesFilter
458-
rename ~/Dockerfile\.cloud-ess$/, 'Dockerfile'
489+
rename ~/Dockerfile\.ess$/, 'Dockerfile'
459490
}
460491
}
461492

462493
final TaskProvider<DockerBuildTask> buildDockerImageTask =
463-
tasks.register(taskName("build", architecture, base, "DockerImage"), DockerBuildTask) {
494+
tasks.register(taskName("build", architecture, dockerBase, "DockerImage"), DockerBuildTask) {
464495

465-
TaskProvider<DockerBuildTask> buildCloudTask = tasks.named(taskName("build", architecture, DockerBase.CLOUD, "DockerImage"))
466-
inputs.files(buildCloudTask)
496+
DockerBase base = dockerBase == DockerBase.CLOUD_ESS ? DockerBase.CLOUD : DockerBase.WOLFI
497+
498+
TaskProvider<DockerBuildTask> buildBaseTask = tasks.named(taskName("build", architecture, base, "DockerImage"))
499+
inputs.files(buildBaseTask)
467500

468501
dockerContext.fileProvider(buildContextTask.map { it.getDestinationDir() })
469502

470503
noCache = BuildParams.isCi()
471504
baseImages = []
472-
tags = generateTags(base, architecture)
505+
tags = generateTags(dockerBase, architecture)
473506
platforms.add(architecture.dockerPlatform)
474-
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(project.gradle.sharedServices, DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME)
507+
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(
508+
project.gradle.sharedServices,
509+
DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME
510+
)
475511
onlyIf("$architecture supported") { serviceProvider.get().isArchitectureSupported(architecture) }
476512

477513
}
@@ -483,15 +519,16 @@ void addBuildEssDockerImageTask(Architecture architecture) {
483519

484520
for (final Architecture architecture : Architecture.values()) {
485521
for (final DockerBase base : DockerBase.values()) {
486-
if (base == DockerBase.CLOUD_ESS) {
522+
if (base == DockerBase.CLOUD_ESS || base == DockerBase.WOLFI_ESS) {
487523
continue
488524
}
489525
addBuildDockerContextTask(architecture, base)
490526
addTransformDockerContextTask(architecture, base)
491527
addBuildDockerImageTask(architecture, base)
492528
}
493529

494-
addBuildEssDockerImageTask(architecture)
530+
addBuildEssDockerImageTask(architecture, DockerBase.CLOUD_ESS)
531+
addBuildEssDockerImageTask(architecture, DockerBase.WOLFI_ESS)
495532
}
496533

497534
def exportDockerImages = tasks.register("exportDockerImages")
@@ -515,6 +552,8 @@ subprojects { Project subProject ->
515552
base = DockerBase.CLOUD_ESS
516553
} else if (subProject.name.contains('cloud-')) {
517554
base = DockerBase.CLOUD
555+
} else if (subProject.name.contains('wolfi-ess')) {
556+
base = DockerBase.WOLFI_ESS
518557
} else if (subProject.name.contains('wolfi-')) {
519558
base = DockerBase.WOLFI
520559
}
@@ -525,7 +564,8 @@ subprojects { Project subProject ->
525564
(base == DockerBase.CLOUD ? 'cloud.tar' :
526565
(base == DockerBase.CLOUD_ESS ? 'cloud-ess.tar' :
527566
(base == DockerBase.WOLFI ? 'wolfi.tar' :
528-
'docker.tar'))))
567+
(base == DockerBase.WOLFI_ESS ? 'wolfi-ess.tar' :
568+
'docker.tar')))))
529569
final String artifactName = "elasticsearch${arch}${base.suffix}_test"
530570

531571
final String exportTaskName = taskName("export", architecture, base, 'DockerImage')
@@ -541,7 +581,10 @@ subprojects { Project subProject ->
541581
tarFile,
542582
"elasticsearch${base.suffix}:${architecture.classifier}"
543583
dependsOn(parent.path + ":" + buildTaskName)
544-
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(project.gradle.sharedServices, DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME)
584+
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(
585+
project.gradle.sharedServices,
586+
DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME
587+
)
545588
onlyIf("$architecture supported") { serviceProvider.get().isArchitectureSupported(architecture) }
546589
}
547590

distribution/docker/src/docker/Dockerfile.cloud-ess

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)