Skip to content

Commit

Permalink
refactor: refactor unexported pack methods (#573)
Browse files Browse the repository at this point in the history
Signed-off-by: Lixia (Sylvia) Lei <lixlei@microsoft.com>
  • Loading branch information
Wwwsylvia authored Aug 24, 2023
1 parent e6d40b6 commit 60da91b
Showing 1 changed file with 56 additions and 27 deletions.
83 changes: 56 additions & 27 deletions pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,13 @@ type PackManifestOptions struct {
// of the manifest to be packed is determined by packManifestVersion
// (Recommended value: PackManifestVersion1_1_RC4).
//
// - If packManifestVersion is [PackManifestVersion1_1_RC4],
// - If packManifestVersion is [PackManifestVersion1_1_RC4]:
// artifactType MUST NOT be empty unless opts.ConfigDescriptor is specified.
// - If packManifestVersion is [PackManifestVersion1_0],
// artifactType will be used as the the config media type unless
// opts.ConfigDescriptor is specified. If artifactType is empty,
// - If packManifestVersion is [PackManifestVersion1_0]:
// if opts.ConfigDescriptor is nil, artifactType will be used as the
// config media type; if artifactType is empty,
// "application/vnd.unknown.config.v1+json" will be used.
// if opts.ConfigDescriptor is NOT nil, artifactType will be ignored.
//
// If succeeded, returns a descriptor of the packed manifest.
func PackManifest(ctx context.Context, pusher content.Pusher, packManifestVersion PackManifestVersion, artifactType string, opts PackManifestOptions) (ocispec.Descriptor, error) {
Expand Down Expand Up @@ -161,14 +162,7 @@ type PackOptions struct {
// Use [PackManifest] instead.
func Pack(ctx context.Context, pusher content.Pusher, artifactType string, blobs []ocispec.Descriptor, opts PackOptions) (ocispec.Descriptor, error) {
if opts.PackImageManifest {
packOpts := PackManifestOptions{
Layers: blobs,
Subject: opts.Subject,
ManifestAnnotations: opts.ManifestAnnotations,
ConfigDescriptor: opts.ConfigDescriptor,
ConfigAnnotations: opts.ConfigAnnotations,
}
return packManifestV1_1_RC2(ctx, pusher, artifactType, packOpts)
return packManifestV1_1_RC2(ctx, pusher, artifactType, blobs, opts)
}
return packArtifact(ctx, pusher, artifactType, blobs, opts)
}
Expand All @@ -194,10 +188,12 @@ func packArtifact(ctx context.Context, pusher content.Pusher, artifactType strin
return pushManifest(ctx, pusher, manifest, manifest.MediaType, manifest.ArtifactType, manifest.Annotations)
}

// packManifestV1_1_RC2 packs an image manifest as defined in image-spec
// v1.1.0-rc2.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc2/manifest.md
func packManifestV1_1_RC2(ctx context.Context, pusher content.Pusher, configMediaType string, opts PackManifestOptions) (ocispec.Descriptor, error) {
// packManifestV1_0 packs an image manifest defined in image-spec v1.0.2.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.0.2/manifest.md
func packManifestV1_0(ctx context.Context, pusher content.Pusher, configMediaType string, opts PackManifestOptions) (ocispec.Descriptor, error) {
if opts.Subject != nil {
return ocispec.Descriptor{}, fmt.Errorf("subject is not supported for manifest version %v: %w", PackManifestVersion1_0, errdef.ErrUnsupported)
}
if configMediaType == "" {
configMediaType = MediaTypeUnknownConfig
}
Expand Down Expand Up @@ -233,6 +229,50 @@ func packManifestV1_1_RC2(ctx context.Context, pusher content.Pusher, configMedi
Config: configDesc,
MediaType: ocispec.MediaTypeImageManifest,
Layers: opts.Layers,
Annotations: annotations,
}
return pushManifest(ctx, pusher, manifest, manifest.MediaType, manifest.Config.MediaType, manifest.Annotations)
}

// packManifestV1_1_RC2 packs an image manifest as defined in image-spec
// v1.1.0-rc2.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc2/manifest.md
func packManifestV1_1_RC2(ctx context.Context, pusher content.Pusher, configMediaType string, layers []ocispec.Descriptor, opts PackOptions) (ocispec.Descriptor, error) {
if configMediaType == "" {
configMediaType = MediaTypeUnknownConfig
}

var configDesc ocispec.Descriptor
if opts.ConfigDescriptor != nil {
configDesc = *opts.ConfigDescriptor
} else {
// Use an empty JSON object here, because some registries may not accept
// empty config blob.
// As of September 2022, GAR is known to return 400 on empty blob upload.
// See https://github.com/oras-project/oras-go/issues/294 for details.
configBytes := []byte("{}")
configDesc = content.NewDescriptorFromBytes(configMediaType, configBytes)
configDesc.Annotations = opts.ConfigAnnotations
// push config
if err := pushIfNotExist(ctx, pusher, configDesc, configBytes); err != nil {
return ocispec.Descriptor{}, fmt.Errorf("failed to push config: %w", err)
}
}

annotations, err := ensureAnnotationCreated(opts.ManifestAnnotations, ocispec.AnnotationCreated)
if err != nil {
return ocispec.Descriptor{}, err
}
if layers == nil {
layers = []ocispec.Descriptor{} // make it an empty array to prevent potential server-side bugs
}
manifest := ocispec.Manifest{
Versioned: specs.Versioned{
SchemaVersion: 2, // historical value. does not pertain to OCI or docker version
},
Config: configDesc,
MediaType: ocispec.MediaTypeImageManifest,
Layers: layers,
Subject: opts.Subject,
Annotations: annotations,
}
Expand Down Expand Up @@ -293,17 +333,6 @@ func packManifestV1_1_RC4(ctx context.Context, pusher content.Pusher, artifactTy
return pushManifest(ctx, pusher, manifest, manifest.MediaType, manifest.ArtifactType, manifest.Annotations)
}

// packManifestV1_0 packs an image manifest defined in image-spec v1.0.2.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.0.2/manifest.md
func packManifestV1_0(ctx context.Context, pusher content.Pusher, configMediaType string, opts PackManifestOptions) (ocispec.Descriptor, error) {
if opts.Subject != nil {
return ocispec.Descriptor{}, fmt.Errorf("subject is not supported for manifest version %v: %w", PackManifestVersion1_0, errdef.ErrUnsupported)
}

// manifest v1.0 is equivalent to manifest v1.1.0-rc2 without subject
return packManifestV1_1_RC2(ctx, pusher, configMediaType, opts)
}

// pushIfNotExist pushes data described by desc if it does not exist in the
// target.
func pushIfNotExist(ctx context.Context, pusher content.Pusher, desc ocispec.Descriptor, data []byte) error {
Expand Down

0 comments on commit 60da91b

Please sign in to comment.