build: fix buildx.build.provenance metadata
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
+20
-26
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/containerd/containerd/v2/core/content/proxy"
|
||||
"github.com/docker/buildx/util/confutil"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1"
|
||||
controlapi "github.com/moby/buildkit/api/services/control"
|
||||
"github.com/moby/buildkit/client"
|
||||
provenancetypes "github.com/moby/buildkit/solver/llbsolver/provenance/types"
|
||||
@@ -22,15 +23,6 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
type provenancePredicate struct {
|
||||
Builder *provenanceBuilder `json:"builder,omitempty"`
|
||||
provenancetypes.ProvenancePredicateSLSA02
|
||||
}
|
||||
|
||||
type provenanceBuilder struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func setRecordProvenance(ctx context.Context, c *client.Client, sr *client.SolveResponse, ref string, mode confutil.MetadataProvenanceMode, pw progress.Writer) error {
|
||||
if mode == confutil.MetadataProvenanceModeDisabled {
|
||||
return nil
|
||||
@@ -69,7 +61,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
|
||||
continue
|
||||
}
|
||||
if ev.Record.Result != nil {
|
||||
desc := lookupProvenance(ev.Record.Result)
|
||||
desc, predicateType := lookupProvenance(ev.Record.Result)
|
||||
if desc == nil {
|
||||
continue
|
||||
}
|
||||
@@ -78,7 +70,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to load provenance blob from build record")
|
||||
}
|
||||
prv, err := encodeProvenance(dt, mode)
|
||||
prv, err := encodeProvenance(dt, predicateType, mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,7 +84,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
|
||||
})
|
||||
} else if ev.Record.Results != nil {
|
||||
for platform, res := range ev.Record.Results {
|
||||
desc := lookupProvenance(res)
|
||||
desc, predicateType := lookupProvenance(res)
|
||||
if desc == nil {
|
||||
continue
|
||||
}
|
||||
@@ -101,7 +93,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to load provenance blob from build record")
|
||||
}
|
||||
prv, err := encodeProvenance(dt, mode)
|
||||
prv, err := encodeProvenance(dt, predicateType, mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -119,7 +111,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
|
||||
return out, eg.Wait()
|
||||
}
|
||||
|
||||
func lookupProvenance(res *controlapi.BuildResultInfo) *ocispecs.Descriptor {
|
||||
func lookupProvenance(res *controlapi.BuildResultInfo) (*ocispecs.Descriptor, string) {
|
||||
for _, a := range res.Attestations {
|
||||
if a.MediaType == "application/vnd.in-toto+json" && strings.HasPrefix(a.Annotations["in-toto.io/predicate-type"], "https://slsa.dev/provenance/") {
|
||||
return &ocispecs.Descriptor{
|
||||
@@ -127,27 +119,29 @@ func lookupProvenance(res *controlapi.BuildResultInfo) *ocispecs.Descriptor {
|
||||
Size: a.Size,
|
||||
MediaType: a.MediaType,
|
||||
Annotations: a.Annotations,
|
||||
}
|
||||
}, a.Annotations["in-toto.io/predicate-type"]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
func encodeProvenance(dt []byte, mode confutil.MetadataProvenanceMode) (string, error) {
|
||||
var prv provenancePredicate
|
||||
if err := json.Unmarshal(dt, &prv); err != nil {
|
||||
func encodeProvenance(dt []byte, predicateType string, mode confutil.MetadataProvenanceMode) (string, error) {
|
||||
var pred *provenancetypes.ProvenancePredicateSLSA02
|
||||
if predicateType == slsa1.PredicateSLSAProvenance {
|
||||
var pred1 *provenancetypes.ProvenancePredicateSLSA1
|
||||
if err := json.Unmarshal(dt, &pred1); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to unmarshal provenance")
|
||||
}
|
||||
pred = pred1.ConvertToSLSA02()
|
||||
} else if err := json.Unmarshal(dt, &pred); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to unmarshal provenance")
|
||||
}
|
||||
if prv.Builder != nil && prv.Builder.ID == "" {
|
||||
// reset builder if id is empty
|
||||
prv.Builder = nil
|
||||
}
|
||||
if mode == confutil.MetadataProvenanceModeMin {
|
||||
// reset fields for minimal provenance
|
||||
prv.BuildConfig = nil
|
||||
prv.Metadata = nil
|
||||
pred.BuildConfig = nil
|
||||
pred.Metadata = nil
|
||||
}
|
||||
dtprv, err := json.Marshal(prv)
|
||||
dtprv, err := json.Marshal(pred)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to marshal provenance")
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ workers0:
|
||||
if err := json.Unmarshal(dt, &pred02); err != nil {
|
||||
return errors.Errorf("failed to unmarshal provenance %s: %v", prov.descr.Digest, err)
|
||||
}
|
||||
pred = provenancetypes.ConvertSLSA02ToSLSA1(pred02)
|
||||
pred = pred02.ConvertToSLSA1()
|
||||
} else if err := json.Unmarshal(dt, &pred); err != nil {
|
||||
return errors.Errorf("failed to unmarshal provenance %s: %v", prov.descr.Digest, err)
|
||||
}
|
||||
|
||||
+1
-1
@@ -1398,7 +1398,7 @@ target "default" {
|
||||
|
||||
var prv provenancetypes.ProvenancePredicateSLSA02
|
||||
require.NoError(t, json.Unmarshal(dtprv, &prv))
|
||||
require.Equal(t, provenancetypes.BuildKitBuildType, prv.BuildType)
|
||||
require.Equal(t, provenancetypes.BuildKitBuildType02, prv.BuildType)
|
||||
}
|
||||
|
||||
func testBakeMetadataWarnings(t *testing.T, sb integration.Sandbox) {
|
||||
|
||||
+1
-1
@@ -835,7 +835,7 @@ func buildMetadataProvenance(t *testing.T, sb integration.Sandbox, metadataMode
|
||||
|
||||
var prv provenancetypes.ProvenancePredicateSLSA02
|
||||
require.NoError(t, json.Unmarshal(dtprv, &prv))
|
||||
require.Equal(t, provenancetypes.BuildKitBuildType, prv.BuildType)
|
||||
require.Equal(t, provenancetypes.BuildKitBuildType02, prv.BuildType)
|
||||
}
|
||||
|
||||
func testBuildMetadataWarnings(t *testing.T, sb integration.Sandbox) {
|
||||
|
||||
Reference in New Issue
Block a user