diff --git a/remotes/docker/schema1/converter.go b/remotes/docker/schema1/converter.go index 6b74cd67e..e7d58acfd 100644 --- a/remotes/docker/schema1/converter.go +++ b/remotes/docker/schema1/converter.go @@ -103,8 +103,41 @@ func (c *Converter) Handle(ctx context.Context, desc ocispec.Descriptor) ([]ocis } } +// ConvertOptions provides options on converting a docker schema1 manifest. +type ConvertOptions struct { + // ManifestMediaType specifies the media type of the manifest OCI descriptor. + ManifestMediaType string + + // ConfigMediaType specifies the media type of the manifest config OCI + // descriptor. + ConfigMediaType string +} + +// ConvertOpt allows configuring a convert operation. +type ConvertOpt func(context.Context, *ConvertOptions) error + +// UseDockerSchema2 is used to indicate that a schema1 manifest should be +// converted into the media types for a docker schema2 manifest. +func UseDockerSchema2() ConvertOpt { + return func(ctx context.Context, o *ConvertOptions) error { + o.ManifestMediaType = images.MediaTypeDockerSchema2Manifest + o.ConfigMediaType = images.MediaTypeDockerSchema2Config + return nil + } +} + // Convert a docker manifest to an OCI descriptor -func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { +func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.Descriptor, error) { + co := ConvertOptions{ + ManifestMediaType: ocispec.MediaTypeImageManifest, + ConfigMediaType: ocispec.MediaTypeImageConfig, + } + for _, opt := range opts { + if err := opt(ctx, &co); err != nil { + return ocispec.Descriptor{}, err + } + } + history, diffIDs, err := c.schema1ManifestHistory() if err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "schema 1 conversion failed") @@ -121,13 +154,13 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { DiffIDs: diffIDs, } - b, err := json.Marshal(img) + b, err := json.MarshalIndent(img, "", " ") if err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image") } config := ocispec.Descriptor{ - MediaType: ocispec.MediaTypeImageConfig, + MediaType: co.ConfigMediaType, Digest: digest.Canonical.FromBytes(b), Size: int64(len(b)), } @@ -145,13 +178,13 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { Layers: layers, } - mb, err := json.Marshal(manifest) + mb, err := json.MarshalIndent(manifest, "", " ") if err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image") } desc := ocispec.Descriptor{ - MediaType: ocispec.MediaTypeImageManifest, + MediaType: co.ManifestMediaType, Digest: digest.Canonical.FromBytes(mb), Size: int64(len(mb)), }