diff --git a/exporter/containerimage/annotations.go b/exporter/containerimage/annotations.go index 880d815a745a2..4b1295bd7a31d 100644 --- a/exporter/containerimage/annotations.go +++ b/exporter/containerimage/annotations.go @@ -60,6 +60,17 @@ func ParseAnnotations(data map[string][]byte) (AnnotationsGroup, map[string][]by return ag, rest, nil } +func (ag AnnotationsGroup) Platforms() []ocispecs.Platform { + var ps []ocispecs.Platform + for pk := range ag { + p, err := platforms.Parse(pk) + if err == nil { + ps = append(ps, p) + } + } + return ps +} + func (ag AnnotationsGroup) Platform(p *ocispecs.Platform) *Annotations { res := &Annotations{ IndexDescriptor: make(map[string]string), diff --git a/exporter/containerimage/export.go b/exporter/containerimage/export.go index 15350a361ca15..10cff01931946 100644 --- a/exporter/containerimage/export.go +++ b/exporter/containerimage/export.go @@ -208,6 +208,15 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source return nil, err } opts.AddAnnotations(as) + for _, p := range opts.Annotations.Platforms() { + pk := platforms.Format(p) + if src.Refs == nil { + return nil, errors.Errorf("invalid annotation: no platform %s found in source", pk) + } + if _, ok := src.Refs[pk]; !ok { + return nil, errors.Errorf("invalid annotation: no platform %s found in source", pk) + } + } ctx, done, err := leaseutil.WithLease(ctx, e.opt.LeaseManager, leaseutil.MakeTemporary) if err != nil { diff --git a/exporter/oci/export.go b/exporter/oci/export.go index 3728abd2704d1..cc42416a93254 100644 --- a/exporter/oci/export.go +++ b/exporter/oci/export.go @@ -10,6 +10,7 @@ import ( archiveexporter "github.com/containerd/containerd/images/archive" "github.com/containerd/containerd/leases" + "github.com/containerd/containerd/platforms" "github.com/docker/distribution/reference" "github.com/moby/buildkit/cache" cacheconfig "github.com/moby/buildkit/cache/config" @@ -109,6 +110,15 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source return nil, err } opts.AddAnnotations(as) + for _, p := range opts.Annotations.Platforms() { + pk := platforms.Format(p) + if src.Refs == nil { + return nil, errors.Errorf("invalid annotation: no platform %s found in source", pk) + } + if _, ok := src.Refs[pk]; !ok { + return nil, errors.Errorf("invalid annotation: no platform %s found in source", pk) + } + } ctx, done, err := leaseutil.WithLease(ctx, e.opt.LeaseManager, leaseutil.MakeTemporary) if err != nil {