Skip to content

Commit

Permalink
Return the full list of descriptors in build metadata
Browse files Browse the repository at this point in the history
Signed-off-by: Laurent Goderre <[email protected]>
  • Loading branch information
LaurentGoderre committed Nov 29, 2024
1 parent c234dd9 commit 604387d
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 17 deletions.
7 changes: 5 additions & 2 deletions cmd/buildctl/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,11 @@ func writeMetadataFile(filename string, exporterResponse map[string]string) erro
}
var raw map[string]interface{}
if err = json.Unmarshal(dt, &raw); err != nil || len(raw) == 0 {
out[k] = v
continue
var rawList []map[string]interface{}
if err = json.Unmarshal(dt, &rawList); err != nil || len(rawList) == 0 {
out[k] = v
continue
}
}
out[k] = json.RawMessage(dt)
}
Expand Down
12 changes: 8 additions & 4 deletions cmd/buildctl/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func testBuildMetadataFile(t *testing.T, sb integration.Sandbox) {
metadataBytes, err := os.ReadFile(metadataFile)
require.NoError(t, err)

var metadata map[string]interface{}
var metadata map[string]json.RawMessage
err = json.Unmarshal(metadataBytes, &metadata)
require.NoError(t, err)

Expand All @@ -153,13 +153,17 @@ func testBuildMetadataFile(t *testing.T, sb integration.Sandbox) {

require.Contains(t, metadata, exptypes.ExporterImageDescriptorKey)
var desc *ocispecs.Descriptor
dtdesc, err := json.Marshal(metadata[exptypes.ExporterImageDescriptorKey])
require.NoError(t, err)
err = json.Unmarshal(dtdesc, &desc)
err = json.Unmarshal(metadata[exptypes.ExporterImageDescriptorKey], &desc)
require.NoError(t, err)
require.NotEmpty(t, desc.MediaType)
require.NotEmpty(t, desc.Digest.String())

require.Contains(t, metadata, exptypes.ExporterImageDescriptorsKey)
var descList []*ocispecs.Descriptor
require.NoError(t, err)
err = json.Unmarshal(metadata[exptypes.ExporterImageDescriptorsKey], &descList)
require.NoError(t, err)

cdAddress := sb.ContainerdAddress()
if cdAddress == "" {
t.Log("no containerd worker, skipping digest verification")
Expand Down
9 changes: 8 additions & 1 deletion exporter/containerimage/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,11 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
}
}()

desc, err := e.opt.ImageWriter.Commit(ctx, src, sessionID, inlineCache, &opts)
descriptors, err := e.opt.ImageWriter.Commit(ctx, src, sessionID, inlineCache, &opts)
if err != nil {
return nil, nil, err
}
desc := descriptors[0]
defer func() {
if err == nil {
descref = NewDescriptorReference(*desc, done)
Expand Down Expand Up @@ -359,6 +360,12 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
}
resp[exptypes.ExporterImageDescriptorKey] = base64.StdEncoding.EncodeToString(dtdesc)

dtdesclist, err := json.Marshal(descriptors)
if err != nil {
return nil, nil, err
}
resp[exptypes.ExporterImageDescriptorsKey] = base64.StdEncoding.EncodeToString(dtdesclist)

return resp, nil, nil
}

Expand Down
1 change: 1 addition & 0 deletions exporter/containerimage/exptypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const (
ExporterImageConfigKey = "containerimage.config"
ExporterImageConfigDigestKey = "containerimage.config.digest"
ExporterImageDescriptorKey = "containerimage.descriptor"
ExporterImageDescriptorsKey = "containerimage.descriptors"
ExporterImageBaseConfigKey = "containerimage.base.config"
ExporterPlatformsKey = "refs.platforms"
)
Expand Down
25 changes: 16 additions & 9 deletions exporter/containerimage/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type ImageWriter struct {
opt WriterOpt
}

func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, sessionID string, inlineCache exptypes.InlineCache, opts *ImageCommitOpts) (*ocispecs.Descriptor, error) {
func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, sessionID string, inlineCache exptypes.InlineCache, opts *ImageCommitOpts) ([]*ocispecs.Descriptor, error) {
if _, ok := inp.Metadata[exptypes.ExporterPlatformsKey]; len(inp.Refs) > 0 && !ok {
return nil, errors.Errorf("unable to export multiple refs, missing platforms mapping")
}
Expand Down Expand Up @@ -180,7 +180,10 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
}
mfstDesc.Annotations[exptypes.ExporterConfigDigestKey] = configDesc.Digest.String()

return mfstDesc, nil
return []*ocispecs.Descriptor{
mfstDesc,
configDesc,
}, nil
}

if len(inp.Attestations) > 0 {
Expand Down Expand Up @@ -225,6 +228,7 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session

labels := map[string]string{}

var descriptors []*ocispecs.Descriptor
var attestationManifests []ocispecs.Descriptor

for i, p := range ps.Platforms {
Expand Down Expand Up @@ -261,15 +265,16 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
inlineCacheEntry, _ = inlineCacheResult.FindRef(p.ID)
}

desc, _, err := ic.commitDistributionManifest(ctx, opts, r, config, remote, opts.Annotations.Platform(&p.Platform), inlineCacheEntry, opts.Epoch, session.NewGroup(sessionID), baseImg)
mfstDesc, configDesc, err := ic.commitDistributionManifest(ctx, opts, r, config, remote, opts.Annotations.Platform(&p.Platform), inlineCacheEntry, opts.Epoch, session.NewGroup(sessionID), baseImg)
if err != nil {
return nil, err
}
dp := p.Platform
desc.Platform = &dp
idx.Manifests = append(idx.Manifests, *desc)
mfstDesc.Platform = &dp
idx.Manifests = append(idx.Manifests, *mfstDesc)
descriptors = append(descriptors, mfstDesc, configDesc)

labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = desc.Digest.String()
labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = mfstDesc.Digest.String()

if attestations, ok := inp.Attestations[p.ID]; ok {
attestations, err := attestation.Unbundle(ctx, session.NewGroup(sessionID), attestations)
Expand Down Expand Up @@ -304,15 +309,15 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
}
defaultSubjects = append(defaultSubjects, intoto.Subject{
Name: pl,
Digest: result.ToDigestMap(desc.Digest),
Digest: result.ToDigestMap(mfstDesc.Digest),
})
}
stmts, err := attestation.MakeInTotoStatements(ctx, session.NewGroup(sessionID), attestations, defaultSubjects)
if err != nil {
return nil, err
}

desc, err := ic.commitAttestationsManifest(ctx, opts, desc.Digest.String(), stmts)
desc, err := ic.commitAttestationsManifest(ctx, opts, mfstDesc.Digest.String(), stmts)
if err != nil {
return nil, err
}
Expand All @@ -323,6 +328,7 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session

for i, mfst := range attestationManifests {
idx.Manifests = append(idx.Manifests, mfst)
descriptors = append(descriptors, &mfst)
labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", len(ps.Platforms)+i)] = mfst.Digest.String()
}

Expand All @@ -344,8 +350,9 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
return nil, idxDone(errors.Wrapf(err, "error writing manifest list blob %s", idxDigest))
}
idxDone(nil)
descriptors = append([]*ocispecs.Descriptor{&idxDesc}, descriptors...)

return &idxDesc, nil
return descriptors, nil
}

func (ic *ImageWriter) exportLayers(ctx context.Context, refCfg cacheconfig.RefConfig, s session.Group, refs ...cache.ImmutableRef) ([]solver.Remote, error) {
Expand Down
9 changes: 8 additions & 1 deletion exporter/oci/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,11 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
}
}()

desc, err := e.opt.ImageWriter.Commit(ctx, src, sessionID, inlineCache, &opts)
descriptors, err := e.opt.ImageWriter.Commit(ctx, src, sessionID, inlineCache, &opts)
if err != nil {
return nil, nil, err
}
desc := descriptors[0]
defer func() {
if err == nil {
descref = containerimage.NewDescriptorReference(*desc, done)
Expand Down Expand Up @@ -194,6 +195,12 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
}
resp[exptypes.ExporterImageDescriptorKey] = base64.StdEncoding.EncodeToString(dtdesc)

dtdesclist, err := json.Marshal(descriptors)
if err != nil {
return nil, nil, err
}
resp[exptypes.ExporterImageDescriptorsKey] = base64.StdEncoding.EncodeToString(dtdesclist)

if n, ok := src.Metadata["image.name"]; e.opts.ImageName == "*" && ok {
e.opts.ImageName = string(n)
}
Expand Down

0 comments on commit 604387d

Please sign in to comment.