Skip to content

Commit

Permalink
build: set record status in response
Browse files Browse the repository at this point in the history
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
  • Loading branch information
crazy-max committed Jun 18, 2024
1 parent 9435551 commit 415f88f
Show file tree
Hide file tree
Showing 12 changed files with 393 additions and 198 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ jobs:
endpoint: tcp://localhost:1234
- driver: docker-container
metadata-provenance: max
- driver: docker-container
metadata-status: max
exclude:
- driver: docker
multi-node: mnode-true
Expand Down Expand Up @@ -134,6 +136,9 @@ jobs:
if [ -n "${{ matrix.metadata-provenance }}" ]; then
echo "BUILDX_METADATA_PROVENANCE=${{ matrix.metadata-provenance }}" >> $GITHUB_ENV
fi
if [ -n "${{ matrix.metadata-status }}" ]; then
echo "BUILDX_METADATA_STATUS=${{ matrix.metadata-status }}" >> $GITHUB_ENV
fi
-
name: Install k3s
if: matrix.driver == 'kubernetes'
Expand Down
16 changes: 8 additions & 8 deletions build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ type Options struct {
Target string
Ulimits *opts.UlimitOpt

Session []session.Attachable
Linked bool // Linked marks this target as exclusively linked (not requested by the user).
PrintFunc *PrintFunc
WithProvenanceResponse bool
SourcePolicy *spb.Policy
GroupRef string
Session []session.Attachable
Linked bool // Linked marks this target as exclusively linked (not requested by the user).
PrintFunc *PrintFunc
WithDetailedResponse bool
SourcePolicy *spb.Policy
GroupRef string
}

type PrintFunc struct {
Expand Down Expand Up @@ -473,8 +473,8 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
rr.ExporterResponse[k] = string(v)
}
rr.ExporterResponse["buildx.build.ref"] = buildRef
if opt.WithProvenanceResponse && node.Driver.HistoryAPISupported(ctx) {
if err := setRecordProvenance(ctx, c, rr, so.Ref, pw); err != nil {
if opt.WithDetailedResponse && node.Driver.HistoryAPISupported(ctx) {
if err := setRecordMetadata(ctx, c, rr, so.Ref, pw); err != nil {
return err
}
}
Expand Down
84 changes: 80 additions & 4 deletions build/provenance.go → build/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,31 @@ import (
"golang.org/x/sync/errgroup"
)

const (
refMetadataBuildxProvenance = "buildx.build.provenance"
refMetadataBuildxStatus = "buildx.build.status"
)

func setRecordMetadata(ctx context.Context, c *client.Client, sr *client.SolveResponse, ref string, pw progress.Writer) error {
var mu sync.Mutex

cb := func(key string, value string) {
mu.Lock()
defer mu.Unlock()
sr.ExporterResponse[key] = value
}

eg, ctx := errgroup.WithContext(ctx)
eg.Go(func() error {
return setRecordProvenance(ctx, c, ref, cb, pw)
})
eg.Go(func() error {
return setRecordStatus(ctx, c, ref, cb, pw)
})

return eg.Wait()
}

type provenancePredicate struct {
Builder *provenanceBuilder `json:"builder,omitempty"`
provenancetypes.ProvenancePredicate
Expand All @@ -29,7 +54,7 @@ type provenanceBuilder struct {
ID string `json:"id,omitempty"`
}

func setRecordProvenance(ctx context.Context, c *client.Client, sr *client.SolveResponse, ref string, pw progress.Writer) error {
func setRecordProvenance(ctx context.Context, c *client.Client, ref string, updateExporterResponse func(key string, value string), pw progress.Writer) error {
mode := confutil.MetadataProvenance()
if mode == confutil.MetadataProvenanceModeDisabled {
return nil
Expand All @@ -41,7 +66,7 @@ func setRecordProvenance(ctx context.Context, c *client.Client, sr *client.Solve
return err
}
for k, v := range res {
sr.ExporterResponse[k] = v
updateExporterResponse(k, v)
}
return nil
})
Expand Down Expand Up @@ -87,7 +112,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
if out == nil {
out = make(map[string]string)
}
out["buildx.build.provenance"] = prv
out[refMetadataBuildxProvenance] = prv
mu.Unlock()
return nil
})
Expand All @@ -111,7 +136,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
if out == nil {
out = make(map[string]string)
}
out["buildx.build.provenance/"+platform] = prv
out[refMetadataBuildxProvenance+"/"+platform] = prv
mu.Unlock()
return nil
})
Expand Down Expand Up @@ -155,3 +180,54 @@ func encodeProvenance(dt []byte, mode confutil.MetadataProvenanceMode) (string,
}
return base64.StdEncoding.EncodeToString(dtprv), nil
}

func setRecordStatus(ctx context.Context, c *client.Client, ref string, updateExporterResponse func(key string, value string), pw progress.Writer) error {
mode := confutil.MetadataStatus()
if mode == confutil.MetadataStatusModeDisabled {
return nil
}
pw = progress.ResetTime(pw)
return progress.Wrap("resolving status for metadata file", pw.Write, func(l progress.SubLogger) error {
status, err := fetchStatus(ctx, c, ref)
if err != nil {
return err
} else if status == nil {
return nil
}

if mode == confutil.MetadataStatusModeWarnings {
if len(status.Warnings) == 0 {
return nil
}
// we just want warnings
status.Vertexes = nil
status.Statuses = nil
status.Logs = nil
}

dt, err := json.Marshal(status)
if err != nil {
return errors.Wrapf(err, "failed to marshal status")
}

updateExporterResponse(refMetadataBuildxStatus, base64.StdEncoding.EncodeToString(dt))
return nil
})
}

func fetchStatus(ctx context.Context, c *client.Client, ref string) (*client.SolveStatus, error) {
cl, err := c.ControlClient().Status(ctx, &controlapi.StatusRequest{
Ref: ref,
})
if err != nil {
return nil, err
}
resp, err := cl.Recv()
if err != nil {
if err == io.EOF {
return nil, nil
}
return nil, errors.Wrap(err, "failed to receive status")
}
return client.NewSolveStatus(resp), nil
}
2 changes: 1 addition & 1 deletion commands/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
for k, b := range bo {
b.Ref = identity.NewID()
b.GroupRef = groupRef
b.WithProvenanceResponse = len(in.metadataFile) > 0
b.WithDetailedResponse = len(in.metadataFile) > 0
refs = append(refs, b.Ref)
bo[k] = b
}
Expand Down
2 changes: 1 addition & 1 deletion commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (o *buildOptions) toControllerOptions() (*controllerapi.BuildOptions, error
return nil, err
}

opts.WithProvenanceResponse = opts.PrintFunc == nil && len(o.metadataFile) > 0
opts.WithDetailedResponse = opts.PrintFunc == nil && len(o.metadataFile) > 0

return &opts, nil
}
Expand Down
30 changes: 15 additions & 15 deletions controller/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,21 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
InStream: inStream,
NamedContexts: contexts,
},
Ref: in.Ref,
BuildArgs: in.BuildArgs,
CgroupParent: in.CgroupParent,
ExtraHosts: in.ExtraHosts,
Labels: in.Labels,
NetworkMode: in.NetworkMode,
NoCache: in.NoCache,
NoCacheFilter: in.NoCacheFilter,
Pull: in.Pull,
ShmSize: dockeropts.MemBytes(in.ShmSize),
Tags: in.Tags,
Target: in.Target,
Ulimits: controllerUlimitOpt2DockerUlimit(in.Ulimits),
GroupRef: in.GroupRef,
WithProvenanceResponse: in.WithProvenanceResponse,
Ref: in.Ref,
BuildArgs: in.BuildArgs,
CgroupParent: in.CgroupParent,
ExtraHosts: in.ExtraHosts,
Labels: in.Labels,
NetworkMode: in.NetworkMode,
NoCache: in.NoCache,
NoCacheFilter: in.NoCacheFilter,
Pull: in.Pull,
ShmSize: dockeropts.MemBytes(in.ShmSize),
Tags: in.Tags,
Target: in.Target,
Ulimits: controllerUlimitOpt2DockerUlimit(in.Ulimits),
GroupRef: in.GroupRef,
WithDetailedResponse: in.WithDetailedResponse,
}

platforms, err := platformutil.Parse(in.Platforms)
Expand Down
Loading

0 comments on commit 415f88f

Please sign in to comment.