From 62be7898b27b0341fc6fbd29355e9895894f81cb Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Wed, 16 Feb 2022 19:57:13 +0100 Subject: [PATCH] buildinfo: export metadata without exporter Signed-off-by: CrazyMax --- client/client_test.go | 39 +++++++++++++++ solver/llbsolver/solver.go | 99 ++++++++++++++++++++------------------ 2 files changed, 90 insertions(+), 48 deletions(-) diff --git a/client/client_test.go b/client/client_test.go index 13454cd8098d9..ad7f92d851ae9 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -152,6 +152,7 @@ func TestIntegration(t *testing.T) { testBuildExportWithForeignLayer, testBuildInfoExporter, testBuildInfoInline, + testBuildInfoNoExport, ) tests = append(tests, diffOpTestCases()...) integration.Run(t, tests, mirrors) @@ -5188,6 +5189,44 @@ func testBuildInfoInline(t *testing.T, sb integration.Sandbox) { } } +func testBuildInfoNoExport(t *testing.T, sb integration.Sandbox) { + requiresLinux(t) + c, err := New(sb.Context(), sb.Address()) + require.NoError(t, err) + defer c.Close() + + frontend := func(ctx context.Context, c gateway.Client) (*gateway.Result, error) { + st := llb.Image("busybox:latest").Run( + llb.Args([]string{"/bin/sh", "-c", `echo hello`}), + ) + def, err := st.Marshal(sb.Context()) + if err != nil { + return nil, err + } + return c.Solve(ctx, gateway.SolveRequest{ + Definition: def.ToPB(), + FrontendOpt: map[string]string{"build-arg:foo": "bar"}, + }) + } + + res, err := c.Build(sb.Context(), SolveOpt{}, "", frontend, nil) + require.NoError(t, err) + + require.Contains(t, res.ExporterResponse, exptypes.ExporterBuildInfo) + decbi, err := base64.StdEncoding.DecodeString(res.ExporterResponse[exptypes.ExporterBuildInfo]) + require.NoError(t, err) + + var exbi binfotypes.BuildInfo + err = json.Unmarshal(decbi, &exbi) + require.NoError(t, err) + + attrval := "bar" + require.Equal(t, exbi.Attrs, map[string]*string{"build-arg:foo": &attrval}) + require.Equal(t, len(exbi.Sources), 1) + require.Equal(t, exbi.Sources[0].Type, binfotypes.SourceTypeDockerImage) + require.Equal(t, exbi.Sources[0].Ref, "docker.io/library/busybox:latest") +} + func tmpdir(appliers ...fstest.Applier) (string, error) { tmpdir, err := ioutil.TempDir("", "buildkit-client") if err != nil { diff --git a/solver/llbsolver/solver.go b/solver/llbsolver/solver.go index de9ab8f671cd8..6a91a8c6aee85 100644 --- a/solver/llbsolver/solver.go +++ b/solver/llbsolver/solver.go @@ -158,31 +158,30 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro } var exporterResponse map[string]string - if e := exp.Exporter; e != nil { - inp := exporter.Source{ - Metadata: res.Metadata, + inp := exporter.Source{ + Metadata: res.Metadata, + } + if inp.Metadata == nil { + inp.Metadata = make(map[string][]byte) + } + if res := res.Ref; res != nil { + r, err := res.Result(ctx) + if err != nil { + return nil, err } - if inp.Metadata == nil { - inp.Metadata = make(map[string][]byte) + workerRef, ok := r.Sys().(*worker.WorkerRef) + if !ok { + return nil, errors.Errorf("invalid reference: %T", r.Sys()) } - if res := res.Ref; res != nil { - r, err := res.Result(ctx) - if err != nil { - return nil, err - } - workerRef, ok := r.Sys().(*worker.WorkerRef) - if !ok { - return nil, errors.Errorf("invalid reference: %T", r.Sys()) - } - inp.Ref = workerRef.ImmutableRef - dtbi, err := buildinfo.Encode(ctx, inp.Metadata[exptypes.ExporterBuildInfo], res.BuildSources()) - if err != nil { - return nil, err - } - if dtbi != nil && len(dtbi) > 0 { - inp.Metadata[exptypes.ExporterBuildInfo] = dtbi - } - + inp.Ref = workerRef.ImmutableRef + dtbi, err := buildinfo.Encode(ctx, inp.Metadata[exptypes.ExporterBuildInfo], res.BuildSources()) + if err != nil { + return nil, err + } + if dtbi != nil && len(dtbi) > 0 { + inp.Metadata[exptypes.ExporterBuildInfo] = dtbi + } + if e := exp.Exporter; e != nil { dtic, err := inlineCache(ctx, exp.CacheExporter, r, e.Config().Compression, session.NewGroup(sessionID)) if err != nil { return nil, err @@ -191,29 +190,30 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro inp.Metadata[exptypes.ExporterInlineCache] = dtic } } - if res.Refs != nil { - m := make(map[string]cache.ImmutableRef, len(res.Refs)) - for k, res := range res.Refs { - if res == nil { - m[k] = nil - } else { - r, err := res.Result(ctx) - if err != nil { - return nil, err - } - workerRef, ok := r.Sys().(*worker.WorkerRef) - if !ok { - return nil, errors.Errorf("invalid reference: %T", r.Sys()) - } - m[k] = workerRef.ImmutableRef - dtbi, err := buildinfo.Encode(ctx, inp.Metadata[fmt.Sprintf("%s/%s", exptypes.ExporterBuildInfo, k)], res.BuildSources()) - if err != nil { - return nil, err - } - if dtbi != nil && len(dtbi) > 0 { - inp.Metadata[fmt.Sprintf("%s/%s", exptypes.ExporterBuildInfo, k)] = dtbi - } - + } + if res.Refs != nil { + m := make(map[string]cache.ImmutableRef, len(res.Refs)) + for k, res := range res.Refs { + if res == nil { + m[k] = nil + } else { + r, err := res.Result(ctx) + if err != nil { + return nil, err + } + workerRef, ok := r.Sys().(*worker.WorkerRef) + if !ok { + return nil, errors.Errorf("invalid reference: %T", r.Sys()) + } + m[k] = workerRef.ImmutableRef + dtbi, err := buildinfo.Encode(ctx, inp.Metadata[fmt.Sprintf("%s/%s", exptypes.ExporterBuildInfo, k)], res.BuildSources()) + if err != nil { + return nil, err + } + if dtbi != nil && len(dtbi) > 0 { + inp.Metadata[fmt.Sprintf("%s/%s", exptypes.ExporterBuildInfo, k)] = dtbi + } + if e := exp.Exporter; e != nil { dtic, err := inlineCache(ctx, exp.CacheExporter, r, e.Config().Compression, session.NewGroup(sessionID)) if err != nil { return nil, err @@ -223,15 +223,18 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro } } } - inp.Refs = m } - + inp.Refs = m + } + if e := exp.Exporter; e != nil { if err := inBuilderContext(ctx, j, e.Name(), "", func(ctx context.Context, _ session.Group) error { exporterResponse, err = e.Export(ctx, inp, j.SessionID) return err }); err != nil { return nil, err } + } else { + res.Metadata = inp.Metadata } g := session.NewGroup(j.SessionID)