Skip to content

Commit fd477ec

Browse files
authored
Add ability to select docker variant. (#5338)
1 parent 6bb6b1e commit fd477ec

File tree

8 files changed

+149
-35
lines changed

8 files changed

+149
-35
lines changed

dev-tools/mage/crossbuild.go

+16
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ var Platforms = BuildPlatforms.Defaults()
3333
// are considered to be selected (see isPackageTypeSelected).
3434
var SelectedPackageTypes []PackageType
3535

36+
// SelectedDockerVariants is the list of docker variants. If empty, all docker variants
37+
// are considered to be selected (see isDockerVariantSelected).
38+
var SelectedDockerVariants []DockerVariant
39+
3640
func init() {
3741
// Allow overriding via PLATFORMS.
3842
if expression := os.Getenv("PLATFORMS"); len(expression) > 0 {
@@ -50,6 +54,18 @@ func init() {
5054
SelectedPackageTypes = append(SelectedPackageTypes, p)
5155
}
5256
}
57+
58+
// Allow overriding via DOCKER_VARIANTS.
59+
if dockerVariants := os.Getenv("DOCKER_VARIANTS"); len(dockerVariants) > 0 {
60+
for _, docvariant := range strings.Split(dockerVariants, ",") {
61+
var v DockerVariant
62+
err := v.UnmarshalText([]byte(docvariant))
63+
if err != nil {
64+
continue
65+
}
66+
SelectedDockerVariants = append(SelectedDockerVariants, v)
67+
}
68+
}
5369
}
5470

5571
// CrossBuildOption defines an option to the CrossBuild target.

dev-tools/mage/dockerbuilder.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,12 @@ type dockerBuilder struct {
2828
}
2929

3030
func newDockerBuilder(spec PackageSpec) (*dockerBuilder, error) {
31-
imageName, err := spec.ImageName()
32-
if err != nil {
33-
return nil, err
34-
}
35-
3631
buildDir := filepath.Join(spec.packageDir, "docker-build")
3732
beatDir := filepath.Join(buildDir, "beat")
3833

3934
return &dockerBuilder{
4035
PackageSpec: spec,
41-
imageName: imageName,
36+
imageName: spec.ImageName(),
4237
buildDir: buildDir,
4338
beatDir: beatDir,
4439
}, nil
@@ -117,6 +112,7 @@ func (b *dockerBuilder) prepareBuild() error {
117112
data := map[string]interface{}{
118113
"ExposePorts": b.exposePorts(),
119114
"ModulesDirs": b.modulesDirs(),
115+
"Variant": b.DockerVariant.String(),
120116
}
121117

122118
err = filepath.Walk(templatesDir, func(path string, info os.FileInfo, _ error) error {

dev-tools/mage/dockervariants.go

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package mage
6+
7+
import (
8+
"fmt"
9+
"strings"
10+
)
11+
12+
const (
13+
undefined = "undefined"
14+
basic = "basic"
15+
ubi = "ubi"
16+
wolfi = "wolfi"
17+
complete = "complete"
18+
cloud = "cloud"
19+
)
20+
21+
// DockerVariant defines the docker variant to build.
22+
type DockerVariant int
23+
24+
// List of possible docker variants.
25+
const (
26+
Undefined = iota
27+
Basic
28+
UBI
29+
Wolfi
30+
Complete
31+
Cloud
32+
)
33+
34+
// String returns the name of the docker variant type.
35+
func (typ DockerVariant) String() string {
36+
switch typ {
37+
case Undefined:
38+
return undefined
39+
case Basic:
40+
return basic
41+
case UBI:
42+
return ubi
43+
case Wolfi:
44+
return wolfi
45+
case Complete:
46+
return complete
47+
case Cloud:
48+
return cloud
49+
default:
50+
return invalid
51+
}
52+
}
53+
54+
// MarshalText returns the text representation of DockerVariant.
55+
func (typ DockerVariant) MarshalText() ([]byte, error) {
56+
return []byte(typ.String()), nil
57+
}
58+
59+
// UnmarshalText returns a DockerVariant based on the given text.
60+
func (typ *DockerVariant) UnmarshalText(text []byte) error {
61+
switch strings.ToLower(string(text)) {
62+
case "":
63+
*typ = Undefined
64+
case basic:
65+
*typ = Basic
66+
case ubi:
67+
*typ = UBI
68+
case wolfi:
69+
*typ = Wolfi
70+
case complete:
71+
*typ = Complete
72+
case cloud:
73+
*typ = Cloud
74+
default:
75+
return fmt.Errorf("unknown docker variant: %v", string(text))
76+
}
77+
return nil
78+
}

dev-tools/mage/pkg.go

+20
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ func Package() error {
4747
continue
4848
}
4949

50+
if pkgType == Docker && !isDockerVariantSelected(pkg.Spec.DockerVariant) {
51+
log.Printf("Skipping %s docker variant type because it is not selected", pkg.Spec.DockerVariant)
52+
continue
53+
}
54+
5055
if target.Name == "linux/arm64" && pkgType == Docker && runtime.GOARCH != "arm64" {
5156
log.Printf("Skipping Docker package type because build host isn't arm")
5257
continue
@@ -121,6 +126,21 @@ func isPackageTypeSelected(pkgType PackageType) bool {
121126
return false
122127
}
123128

129+
// isDockerVariantSelected returns true if SelectedDockerVariants is empty or if
130+
// docVariant is present on SelectedDockerVariants. It returns false otherwise.
131+
func isDockerVariantSelected(docVariant DockerVariant) bool {
132+
if len(SelectedDockerVariants) == 0 {
133+
return true
134+
}
135+
136+
for _, v := range SelectedDockerVariants {
137+
if v == docVariant {
138+
return true
139+
}
140+
}
141+
return false
142+
}
143+
124144
type packageBuilder struct {
125145
Platform BuildPlatform
126146
Spec PackageSpec

dev-tools/mage/pkgspecs.go

+11
Original file line numberDiff line numberDiff line change
@@ -154,5 +154,16 @@ func LoadSpecs(files ...string) (map[string][]OSPackageArgs, error) {
154154
return nil, fmt.Errorf("failed to unmarshal spec data: %w", err)
155155
}
156156

157+
// verify that the package specification sets the docker variant
158+
for specName, specs := range packages.Specs {
159+
for _, spec := range specs {
160+
for _, pkgType := range spec.Types {
161+
if pkgType == Docker && spec.Spec.DockerVariant == Undefined {
162+
return nil, fmt.Errorf("%s defined a package spec for docker without a docker_variant set", specName)
163+
}
164+
}
165+
}
166+
}
167+
157168
return packages.Specs, nil
158169
}

dev-tools/mage/pkgtypes.go

+8-15
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ type PackageSpec struct {
9191
License string `yaml:"license,omitempty"`
9292
URL string `yaml:"url,omitempty"`
9393
Description string `yaml:"description,omitempty"`
94+
DockerVariant DockerVariant `yaml:"docker_variant,omitempty"`
9495
PreInstallScript string `yaml:"pre_install_script,omitempty"`
9596
PostInstallScript string `yaml:"post_install_script,omitempty"`
9697
PostRmScript string `yaml:"post_rm_script,omitempty"`
@@ -271,11 +272,7 @@ func (typ PackageType) AddFileExtension(file string) string {
271272
func (typ PackageType) PackagingDir(home string, target BuildPlatform, spec PackageSpec) (string, error) {
272273
root := home
273274
if typ == Docker {
274-
imageName, err := spec.ImageName()
275-
if err != nil {
276-
return "", err
277-
}
278-
root = filepath.Join(root, imageName)
275+
root = filepath.Join(root, spec.ImageName())
279276
}
280277

281278
targetPath := typ.AddFileExtension(spec.Name + "-" + target.GOOS() + "-" + target.Arch())
@@ -467,17 +464,13 @@ func (s PackageSpec) Evaluate(args ...map[string]interface{}) PackageSpec {
467464
return s
468465
}
469466

470-
// ImageName computes the image name from the spec. A template for the image
471-
// name can be configured by adding image_name to extra_vars.
472-
func (s PackageSpec) ImageName() (string, error) {
473-
if name := s.ExtraVars["image_name"]; name != "" {
474-
imageName, err := s.Expand(name)
475-
if err != nil {
476-
return "", fmt.Errorf("failed to expand image_name: %w", err)
477-
}
478-
return imageName, nil
467+
// ImageName computes the image name from the spec.
468+
func (s PackageSpec) ImageName() string {
469+
if s.DockerVariant == Basic {
470+
// no suffix for basic docker variant
471+
return s.Name
479472
}
480-
return s.Name, nil
473+
return fmt.Sprintf("%s-%s", s.Name, s.DockerVariant)
481474
}
482475

483476
func copyInstallScript(spec PackageSpec, script string, local *string) error {

dev-tools/packaging/packages.yml

+10-10
Original file line numberDiff line numberDiff line change
@@ -223,31 +223,31 @@ shared:
223223
buildFrom: '--platform=linux/arm64 cgr.dev/chainguard/wolfi-base'
224224

225225
- &docker_ubuntu_spec
226+
docker_variant: 'basic'
226227
extra_vars:
227228
from: '--platform=linux/amd64 ubuntu:20.04'
228-
image_name: '{{.BeatName}}'
229229
- &docker_ubuntu_arm_spec
230+
docker_variant: 'basic'
230231
extra_vars:
231232
from: '--platform=linux/arm64 ubuntu:20.04'
232-
image_name: '{{.BeatName}}'
233233

234234
- &docker_ubi_spec
235+
docker_variant: 'ubi'
235236
extra_vars:
236237
from: '--platform=linux/amd64 docker.elastic.co/ubi9/ubi-minimal'
237-
image_name: '{{.BeatName}}-ubi'
238238
- &docker_ubi_arm_spec
239+
docker_variant: 'ubi'
239240
extra_vars:
240241
from: '--platform=linux/arm64 docker.elastic.co/ubi9/ubi-minimal'
241-
image_name: '{{.BeatName}}-ubi'
242242

243243
- &docker_wolfi_spec
244+
docker_variant: 'wolfi'
244245
extra_vars:
245246
from: '--platform=linux/amd64 cgr.dev/chainguard/wolfi-base'
246-
image_name: '{{.BeatName}}-wolfi'
247247
- &docker_wolfi_arm_spec
248+
docker_variant: 'wolfi'
248249
extra_vars:
249250
from: '--platform=linux/arm64 cgr.dev/chainguard/wolfi-base'
250-
image_name: '{{.BeatName}}-wolfi'
251251

252252
- &docker_elastic_spec
253253
extra_vars:
@@ -275,9 +275,10 @@ shared:
275275
{{ commit }}
276276
mode: 0644
277277

278+
# cloud build to beats-ci repository
278279
- &agent_docker_cloud_spec
280+
docker_variant: 'cloud'
279281
extra_vars:
280-
image_name: '{{.BeatName}}-cloud'
281282
repository: 'docker.elastic.co/beats-ci'
282283
files:
283284
'data/cloud_downloads/filebeat.sh':
@@ -290,11 +291,10 @@ shared:
290291
source: '{{.AgentDropPath}}/archives/{{.GOOS}}-{{.AgentArchName}}.tar.gz/agentbeat-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}-{{.GOOS}}-{{.AgentArchName}}.tar.gz'
291292
mode: 0755
292293

293-
# not different to the default image, kept for backwards-compatibility
294+
# includes nodejs with @elastic/synthetics
294295
- &agent_docker_complete_spec
295296
<<: *agent_docker_spec
296-
extra_vars:
297-
image_name: '{{.BeatName}}-complete'
297+
docker_variant: 'complete'
298298

299299
# Deb/RPM spec for community beats.
300300
- &deb_rpm_spec

dev-tools/packaging/templates/docker/Dockerfile.elastic-agent.tmpl

+4-4
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ RUN true && \
4343
chmod 0775 {{ $beatHome}}/{{ $modulesd }} && \
4444
{{- end }}
4545

46-
{{- if contains .image_name "-cloud" }}
46+
{{- if eq .Variant "cloud" }}
4747
mkdir -p /opt/agentbeat /opt/filebeat /opt/metricbeat && \
4848
cp -f {{ $beatHome }}/data/cloud_downloads/filebeat.sh /opt/filebeat/filebeat && \
4949
chmod +x /opt/filebeat/filebeat && \
@@ -170,14 +170,14 @@ RUN mkdir /licenses
170170
COPY --from=home {{ $beatHome }}/LICENSE.txt /licenses
171171
COPY --from=home {{ $beatHome }}/NOTICE.txt /licenses
172172

173-
{{- if contains .image_name "-cloud" }}
173+
{{- if eq .Variant "cloud" }}
174174
COPY --from=home /opt /opt
175175
# Generate folder for a stub command that will be overwritten at runtime
176176
RUN mkdir /app && \
177177
chown {{ .user }}:{{ .user }} /app
178178
{{- end }}
179179

180-
{{- if (and (contains .image_name "-complete") (contains .from "ubuntu")) }}
180+
{{- if (and (eq .Variant "complete") (contains .from "ubuntu")) }}
181181
USER root
182182
ENV NODE_PATH={{ $beatHome }}/.node
183183
RUN echo \
@@ -254,7 +254,7 @@ ENV LIBBEAT_MONITORING_CGROUPS_HIERARCHY_OVERRIDE=/
254254

255255
WORKDIR {{ $beatHome }}
256256

257-
{{- if contains .image_name "-cloud" }}
257+
{{- if eq .Variant "cloud" }}
258258
ENTRYPOINT ["/usr/bin/tini", "--"]
259259
CMD ["/app/apm.sh"]
260260
# Generate a stub command that will be overwritten at runtime

0 commit comments

Comments
 (0)