provenance: derive provenance for attestation refs

Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
Justin Chadwell
2022-12-12 12:40:02 +00:00
parent 063056313f
commit 31e692519c
2 changed files with 53 additions and 20 deletions

View File

@@ -2,7 +2,6 @@ package llbsolver
import (
"context"
"encoding/json"
"sync"
"github.com/containerd/containerd/platforms"
@@ -59,7 +58,10 @@ func (b *provenanceBridge) allImages() []provenance.ImageSource {
}
func (b *provenanceBridge) requests(r *frontend.Result) (*resultRequests, error) {
reqs := &resultRequests{refs: make(map[string]*resultWithBridge)}
reqs := &resultRequests{
refs: make(map[string]*resultWithBridge),
atts: make(map[string][]*resultWithBridge),
}
if r.Ref != nil {
ref, ok := b.findByResult(r.Ref)
@@ -77,16 +79,25 @@ func (b *provenanceBridge) requests(r *frontend.Result) (*resultRequests, error)
reqs.refs[k] = r
}
if platformsBytes, ok := r.Metadata[exptypes.ExporterPlatformsKey]; ok {
var ps exptypes.Platforms
if len(platformsBytes) > 0 {
if err := json.Unmarshal(platformsBytes, &ps); err != nil {
return nil, errors.Wrapf(err, "failed to parse platforms passed to provenance processor")
for k, atts := range r.Attestations {
for _, att := range atts {
if att.Ref == nil {
continue
}
reqs.platforms = ps.Platforms
r, ok := b.findByResult(att.Ref)
if !ok {
return nil, errors.Errorf("could not find request for ref %s", att.Ref.ID())
}
reqs.atts[k] = append(reqs.atts[k], r)
}
}
ps, err := exptypes.ParsePlatforms(r.Metadata)
if err != nil {
return nil, err
}
reqs.platforms = ps.Platforms
return reqs, nil
}
@@ -97,15 +108,15 @@ func (b *provenanceBridge) findByResult(rp solver.ResultProxy) (*resultWithBridg
}
}
for _, bld := range b.builds {
if bld.res.Ref != nil {
if bld.res.Ref.ID() == rp.ID() {
return &bld, true
}
}
for _, ref := range bld.res.Refs {
if ref.ID() == rp.ID() {
return &bld, true
found := false
bld.res.EachRef(func(r solver.ResultProxy) error {
if r.ID() == rp.ID() {
found = true
}
return nil
})
if found {
return &bld, true
}
}
return nil, false
@@ -165,6 +176,7 @@ func (b *provenanceBridge) Solve(ctx context.Context, req frontend.SolveRequest,
type resultRequests struct {
ref *resultWithBridge
refs map[string]*resultWithBridge
atts map[string][]*resultWithBridge
platforms []exptypes.Platform
}
@@ -228,6 +240,11 @@ func (reqs *resultRequests) allRes() map[string]struct{} {
for _, r := range reqs.refs {
res[r.res.Ref.ID()] = struct{}{}
}
for _, rs := range reqs.atts {
for _, r := range rs {
res[r.res.Ref.ID()] = struct{}{}
}
}
return res
}

View File

@@ -412,6 +412,7 @@ func addProvenanceToResult(res *frontend.Result, br *provenanceBridge) (*Result,
Result: res,
Provenance: &provenance.Result{},
}
if res.Ref != nil {
cp, err := getProvenance(res.Ref, reqs.ref.bridge, "", reqs)
if err != nil {
@@ -425,11 +426,10 @@ func addProvenanceToResult(res *frontend.Result, br *provenanceBridge) (*Result,
return nil, err
}
}
if len(res.Refs) == 0 {
return out, nil
}
out.Provenance.Refs = make(map[string]*provenance.Capture, len(res.Refs))
if len(res.Refs) != 0 {
out.Provenance.Refs = make(map[string]*provenance.Capture, len(res.Refs))
}
for k, ref := range res.Refs {
cp, err := getProvenance(ref, reqs.refs[k].bridge, k, reqs)
if err != nil {
@@ -443,6 +443,22 @@ func addProvenanceToResult(res *frontend.Result, br *provenanceBridge) (*Result,
return nil, err
}
}
if len(res.Attestations) != 0 {
out.Provenance.Attestations = make(map[string][]result.Attestation[*provenance.Capture], len(res.Attestations))
}
for k, as := range res.Attestations {
for i, a := range as {
a2, err := result.ConvertAttestation(&a, func(r solver.ResultProxy) (*provenance.Capture, error) {
return getProvenance(r, reqs.atts[k][i].bridge, k, reqs)
})
if err != nil {
return nil, err
}
out.Provenance.Attestations[k] = append(out.Provenance.Attestations[k], *a2)
}
}
return out, nil
}