From e9f1696834331d189159f402e086a27a86e796b8 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 11 Oct 2024 10:06:36 -0700 Subject: [PATCH] fix: copy volumes and labels from spec (#398) * fix: copy volumes and labels from spec Signed-off-by: Brian Goff Co-authored-by: Danny Brito <54994380+DannyBrito@users.noreply.github.com> --- image.go | 14 +++++++ test/azlinux_test.go | 89 ++++++++++++++++++++++++++++++++++++++++++++ test/windows_test.go | 7 ++++ 3 files changed, 110 insertions(+) diff --git a/image.go b/image.go index df92c0948..7fcc4b5fe 100644 --- a/image.go +++ b/image.go @@ -101,5 +101,19 @@ func MergeImageConfig(dst *DockerImageConfig, src *ImageConfig) error { dst.User = src.User } + for k, v := range src.Volumes { + if dst.Volumes == nil { + dst.Volumes = make(map[string]struct{}, len(src.Volumes)) + } + dst.Volumes[k] = v + } + + for k, v := range src.Labels { + if dst.Labels == nil { + dst.Labels = make(map[string]string, len(src.Labels)) + } + dst.Labels[k] = v + } + return nil } diff --git a/test/azlinux_test.go b/test/azlinux_test.go index 9da203cf2..182309470 100644 --- a/test/azlinux_test.go +++ b/test/azlinux_test.go @@ -2,14 +2,18 @@ package test import ( "context" + "encoding/json" "errors" "fmt" "path/filepath" + "strings" "testing" "github.com/Azure/dalec" "github.com/Azure/dalec/frontend/azlinux" + "github.com/google/go-cmp/cmp" "github.com/moby/buildkit/client/llb" + "github.com/moby/buildkit/exporter/containerimage/exptypes" gwclient "github.com/moby/buildkit/frontend/gateway/client" moby_buildkit_v1_frontend "github.com/moby/buildkit/frontend/gateway/pb" "gotest.tools/v3/assert" @@ -1253,6 +1257,11 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot ctx := startTestSpan(baseCtx, t) testLinuxSymlinkArtifacts(ctx, t, testConfig) }) + t.Run("test image configs", func(t *testing.T) { + t.Parallel() + ctx := startTestSpan(baseCtx, t) + testImageConfig(ctx, t, testConfig.Target.Container) + }) } func testCustomLinuxWorker(ctx context.Context, t *testing.T, targetCfg targetConfig, workerCfg workerConfig) { @@ -1685,3 +1694,83 @@ func testLinuxSymlinkArtifacts(ctx context.Context, t *testing.T, cfg testLinuxC assert.NilError(t, err) }) } + +func testImageConfig(ctx context.Context, t *testing.T, target string, opts ...srOpt) { + spec := &dalec.Spec{ + Name: "test-image-config", + Version: "0.0.1", + Revision: "42", + Description: "Test to make sure image configs are copied over", + License: "MIT", + Image: &dalec.ImageConfig{ + Entrypoint: "some-entrypoint", + Cmd: "some-cmd", + Env: []string{ + "ENV1=VAL1", + "ENV2=VAL2", + }, + Labels: map[string]string{ + "label.1": "value1", + "label.2": "value2", + }, + Volumes: map[string]struct{}{ + "/some/volume": {}, + }, + WorkingDir: "/some/work/dir", + StopSignal: "SOME-SIG", + User: "some-user", + }, + } + + envToMap := func(envs []string) map[string]string { + out := make(map[string]string, len(envs)) + for _, env := range envs { + k, v, _ := strings.Cut(env, "=") + out[k] = v + } + return out + } + + testEnv.RunTest(ctx, t, func(ctx context.Context, gwc gwclient.Client) { + opts = append(opts, withSpec(ctx, t, spec)) + opts = append(opts, withBuildTarget(target)) + sr := newSolveRequest(opts...) + res := solveT(ctx, t, gwc, sr) + + dt, ok := res.Metadata[exptypes.ExporterImageConfigKey] + assert.Assert(t, ok, "missing image config in result metadata") + + var img dalec.DockerImageSpec + err := json.Unmarshal(dt, &img) + assert.NilError(t, err) + + assert.Check(t, cmp.Equal(strings.Join(img.Config.Entrypoint, " "), spec.Image.Entrypoint)) + assert.Check(t, cmp.Equal(strings.Join(img.Config.Cmd, " "), spec.Image.Cmd)) + + // Envs are merged together with the base image + // So we need to validate that the values we've set are what we expect + // Often there will be at least one other env for `PATH` we won't check + expectEnv := envToMap(spec.Image.Env) + actualEnv := envToMap(img.Config.Env) + for k, v := range expectEnv { + assert.Check(t, cmp.Equal(actualEnv[k], v)) + } + + // Labels are merged with the base image + // So we need to check that the labels we've set are added + for k, v := range spec.Image.Labels { + assert.Check(t, cmp.Equal(v, img.Config.Labels[k])) + } + + // Volumes are merged with the base image + // So we need to check that the volumes we've set are added + for k := range spec.Image.Volumes { + _, ok := img.Config.Volumes[k] + assert.Check(t, ok, k) + } + + assert.Check(t, cmp.Equal(img.Config.WorkingDir, spec.Image.WorkingDir)) + assert.Check(t, cmp.Equal(img.Config.StopSignal, spec.Image.StopSignal)) + assert.Check(t, cmp.Equal(img.Config.User, spec.Image.User)) + }) +} diff --git a/test/windows_test.go b/test/windows_test.go index 9d4d13fd7..a5b37176a 100644 --- a/test/windows_test.go +++ b/test/windows_test.go @@ -367,6 +367,13 @@ echo "$BAR" > bar.txt solveT(ctx, t, client, req) }) }) + + t.Run("test image configs", func(t *testing.T) { + t.Parallel() + + ctx := startTestSpan(baseCtx, t) + testImageConfig(ctx, t, buildTarget, withWindowsAmd64) + }) } func runBuild(ctx context.Context, t *testing.T, gwc gwclient.Client, spec *dalec.Spec, srOpts ...srOpt) {