diff --git a/bake/bake.go b/bake/bake.go index 6df872f3a..3c8d90b7e 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -1544,12 +1544,12 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { return nil, err } - annotations, err := buildflags.ParseAnnotations(t.Annotations) + bo.Annotations, err = buildflags.ParseAnnotations(t.Annotations) if err != nil { return nil, err } for _, e := range bo.Exports { - for k, v := range annotations { + for k, v := range bo.Annotations { e.Attrs[k.String()] = v } } diff --git a/build/build.go b/build/build.go index 8317dd64a..9f14fa08f 100644 --- a/build/build.go +++ b/build/build.go @@ -93,6 +93,7 @@ type Options struct { ProvenanceResponseMode confutil.MetadataProvenanceMode SourcePolicy *spb.Policy GroupRef string + Annotations map[exptypes.AnnotationKey]string // Not used during build, annotations are already set in Exports. Just used to check for support with drivers. } type CallFunc struct { diff --git a/build/opt.go b/build/opt.go index 841037427..56879b379 100644 --- a/build/opt.go +++ b/build/opt.go @@ -28,6 +28,7 @@ import ( "github.com/moby/buildkit/client" "github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/ociindex" + "github.com/moby/buildkit/exporter/containerimage/exptypes" gateway "github.com/moby/buildkit/frontend/gateway/client" "github.com/moby/buildkit/identity" "github.com/moby/buildkit/session" @@ -187,6 +188,20 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt *O } } + // check if index annotations are supported by docker driver + if len(opt.Exports) > 0 && opt.CallFunc == nil && len(opt.Annotations) > 0 && nodeDriver.IsMobyDriver() && !nodeDriver.Features(ctx)[driver.MultiPlatform] { + for _, exp := range opt.Exports { + if exp.Type == "image" || exp.Type == "docker" { + for ak := range opt.Annotations { + switch ak.Type { + case exptypes.AnnotationIndex, exptypes.AnnotationIndexDescriptor: + return nil, nil, errors.New("index annotations not supported for single platform export") + } + } + } + } + } + // fill in image exporter names from tags if len(opt.Tags) > 0 { tags := make([]string, len(opt.Tags)) diff --git a/commands/build.go b/commands/build.go index 7a174413c..ea022076b 100644 --- a/commands/build.go +++ b/commands/build.go @@ -1062,13 +1062,13 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in *BuildOptions, inSt } } - annotations, err := buildflags.ParseAnnotations(in.Annotations) + opts.Annotations, err = buildflags.ParseAnnotations(in.Annotations) if err != nil { return nil, nil, errors.Wrap(err, "parse annotations") } for _, o := range outputs { - for k, v := range annotations { + for k, v := range opts.Annotations { o.Attrs[k.String()] = v } } diff --git a/tests/build.go b/tests/build.go index adbdd6f4f..b77b4e42e 100644 --- a/tests/build.go +++ b/tests/build.go @@ -78,6 +78,7 @@ var buildTests = []func(t *testing.T, sb integration.Sandbox){ testBuildCall, testBuildCheckCallOutput, testBuildExtraHosts, + testBuildIndexAnnotationsLoadDocker, } func testBuild(t *testing.T, sb integration.Sandbox) { @@ -1341,6 +1342,17 @@ RUN cat /etc/hosts | grep myhostmulti | grep 162.242.195.82 require.NoError(t, err, string(out)) } +func testBuildIndexAnnotationsLoadDocker(t *testing.T, sb integration.Sandbox) { + if sb.DockerAddress() == "" { + t.Skip("only testing with docker available") + } + skipNoCompatBuildKit(t, sb, ">= 0.11.0-0", "annotations") + dir := createTestProject(t) + out, err := buildCmd(sb, withArgs("--annotation", "index:foo=bar", "--provenance", "false", "--output", "type=docker", dir)) + require.Error(t, err, out) + require.Contains(t, out, "index annotations not supported for single platform export") +} + func createTestProject(t *testing.T) string { dockerfile := []byte(` FROM busybox:latest AS base