diff --git a/pkg/adapter/annotation/annotation.go b/pkg/adapter/annotation/annotation.go index 7e425302..810d3bd8 100644 --- a/pkg/adapter/annotation/annotation.go +++ b/pkg/adapter/annotation/annotation.go @@ -23,13 +23,15 @@ import ( "github.com/pkg/errors" providerContent "github.com/goharbor/acceleration-service/pkg/content" + nydusutils "github.com/goharbor/acceleration-service/pkg/driver/nydus/utils" "github.com/goharbor/acceleration-service/pkg/utils" ) type Appended struct { - DriverName string - DriverVersion string - SourceDigest string + DriverName string + DriverVersion string + SourceDigest string + ExtraAnnotations map[string]string } const ( @@ -55,7 +57,13 @@ func annotate(annotations map[string]string, appended Appended) map[string]strin if appended.DriverVersion != "" { annotations[AnnotationAccelerationDriverVersion] = appended.DriverVersion } - annotations[AnnotationAccelerationSourceDigest] = appended.SourceDigest + if appended.SourceDigest != "" { + annotations[AnnotationAccelerationSourceDigest] = appended.SourceDigest + } + + for k, v := range appended.ExtraAnnotations { + annotations[k] = v + } return annotations } @@ -65,7 +73,8 @@ func Append(ctx context.Context, provider providerContent.Provider, desc *ocispe var err error switch desc.MediaType { - case ocispec.MediaTypeImageManifest: + // Refer: https://github.com/goharbor/harbor/blob/main/src/controller/artifact/abstractor.go#L75 + case ocispec.MediaTypeImageManifest, images.MediaTypeDockerSchema2Manifest: var manifest ocispec.Manifest labels, err = utils.ReadJSON(ctx, provider.ContentStore(), &manifest, *desc) if err != nil { @@ -80,23 +89,36 @@ func Append(ctx context.Context, provider providerContent.Provider, desc *ocispe return desc, nil - case ocispec.MediaTypeImageIndex: + // Refer: https://github.com/goharbor/harbor/blob/main/src/controller/artifact/abstractor.go#L79 + case ocispec.MediaTypeImageIndex, images.MediaTypeDockerSchema2ManifestList: var index ocispec.Index labels, err = utils.ReadJSON(ctx, provider.ContentStore(), &index, *desc) if err != nil { return nil, errors.Wrap(err, "read manifest index") } - index.Annotations = annotate(index.Annotations, appended) + for idx, maniDesc := range index.Manifests { + if maniDesc.Platform != nil && maniDesc.Platform.OSFeatures[0] == nydusutils.ManifestOSFeatureNydus { + var manifest ocispec.Manifest + labels, err = utils.ReadJSON(ctx, provider.ContentStore(), &manifest, maniDesc) + if err != nil { + return nil, errors.Wrap(err, "read manifest") + } + + manifest.Annotations = annotate(maniDesc.Annotations, appended) + newManiDesc, err := utils.WriteJSON(ctx, provider.ContentStore(), manifest, maniDesc, "", labels) + if err != nil { + return nil, errors.Wrap(err, "write manifest") + } + index.Manifests[idx] = *newManiDesc + } + } desc, err := utils.WriteJSON(ctx, provider.ContentStore(), index, *desc, "", labels) if err != nil { return nil, errors.Wrap(err, "write manifest index") } return desc, nil - - case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList: - return nil, fmt.Errorf("docker manifest not support to append annotation") } return nil, fmt.Errorf("invalid mediatype %s", desc.MediaType) diff --git a/pkg/converter/converter.go b/pkg/converter/converter.go index 8127fd25..fc93c55b 100644 --- a/pkg/converter/converter.go +++ b/pkg/converter/converter.go @@ -24,6 +24,7 @@ import ( "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/reference/docker" + "github.com/goharbor/acceleration-service/pkg/adapter/annotation" "github.com/goharbor/acceleration-service/pkg/content" "github.com/goharbor/acceleration-service/pkg/driver" "github.com/goharbor/acceleration-service/pkg/errdefs" @@ -123,6 +124,14 @@ func (cvt *Converter) Convert(ctx context.Context, source, target string) (*Metr if err != nil { return nil, errors.Wrap(err, "convert image") } + desc, err = annotation.Append(ctx, cvt.provider, desc, annotation.Appended{ + DriverName: cvt.driver.Name(), + DriverVersion: cvt.driver.Version(), + ExtraAnnotations: desc.Annotations, + }) + if err != nil { + return nil, errors.Wrap(err, "append annotation") + } metric.ConversionElapsed = time.Since(start) if err := metric.SetTargetImageSize(ctx, cvt, desc); err != nil { return nil, errors.Wrap(err, "get target image size") diff --git a/pkg/driver/nydus/nydus.go b/pkg/driver/nydus/nydus.go index 31f2b94b..9cee7191 100644 --- a/pkg/driver/nydus/nydus.go +++ b/pkg/driver/nydus/nydus.go @@ -21,21 +21,27 @@ import ( "os" "strconv" + "github.com/goharbor/acceleration-service/pkg/adapter/annotation" + accelcontent "github.com/goharbor/acceleration-service/pkg/content" + "github.com/goharbor/acceleration-service/pkg/driver/nydus/parser" + nydusutils "github.com/goharbor/acceleration-service/pkg/driver/nydus/utils" + "github.com/goharbor/acceleration-service/pkg/errdefs" + "github.com/goharbor/acceleration-service/pkg/utils" + "github.com/containerd/containerd/content" "github.com/containerd/containerd/images/converter" "github.com/containerd/containerd/platforms" "github.com/containerd/nydus-snapshotter/pkg/backend" nydusify "github.com/containerd/nydus-snapshotter/pkg/converter" - "github.com/goharbor/acceleration-service/pkg/driver/nydus/parser" - "github.com/goharbor/acceleration-service/pkg/errdefs" "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" +) - accelcontent "github.com/goharbor/acceleration-service/pkg/content" - nydusutils "github.com/goharbor/acceleration-service/pkg/driver/nydus/utils" - "github.com/goharbor/acceleration-service/pkg/utils" +const ( + // annotationNydusFlag is used to indicate a image which is nydus format. + annotationNydusFlag = "containerd.io/snapshot/nydus" ) type chunkDictInfo struct { @@ -177,6 +183,10 @@ func (d *Driver) Convert(ctx context.Context, provider accelcontent.Provider, so if err != nil { return nil, err } + desc.Annotations = map[string]string{ + annotationNydusFlag: "true", + annotation.AnnotationAccelerationSourceDigest: image.Digest.String(), + } if d.mergeManifest { return d.makeManifestIndex(ctx, provider.ContentStore(), *image, *desc) }