diff --git a/pkg/v1/remote/write.go b/pkg/v1/remote/write.go index 736c95590d..9eddeedb7c 100644 --- a/pkg/v1/remote/write.go +++ b/pkg/v1/remote/write.go @@ -849,11 +849,26 @@ func WriteLayer(repo name.Repository, layer v1.Layer, options ...Option) (rerr e // should ensure that all blobs or manifests that are referenced by t exist // in the target registry. func Tag(tag name.Tag, t Taggable, options ...Option) error { - o, err := makeOptions(tag.Context(), options...) + return Put(tag, t, options...) +} + +// Put adds a manifest from the given Taggable via PUT /v1/.../manifest/ +// +// Notable implementations of Taggable are v1.Image, v1.ImageIndex, and +// remote.Descriptor. +// +// If t implements MediaType, we will use that for the Content-Type, otherwise +// we will default to types.DockerManifestSchema2. +// +// Put does not attempt to write anything other than the manifest, so callers +// should ensure that all blobs or manifests that are referenced by t exist +// in the target registry. +func Put(ref name.Reference, t Taggable, options ...Option) error { + o, err := makeOptions(ref.Context(), options...) if err != nil { return err } - scopes := []string{tag.Scope(transport.PushScope)} + scopes := []string{ref.Scope(transport.PushScope)} // TODO: This *always* does a token exchange. For some registries, // that's pretty slow. Some ideas; @@ -861,15 +876,15 @@ func Tag(tag name.Tag, t Taggable, options ...Option) error { // * Allow callers to pass in a transport.Transport, typecheck // it to allow them to reuse the transport across multiple calls. // * WithTag option to do multiple manifest PUTs in commitManifest. - tr, err := transport.NewWithContext(o.context, tag.Context().Registry, o.auth, o.transport, scopes) + tr, err := transport.NewWithContext(o.context, ref.Context().Registry, o.auth, o.transport, scopes) if err != nil { return err } w := writer{ - repo: tag.Context(), + repo: ref.Context(), client: &http.Client{Transport: tr}, context: o.context, } - return w.commitManifest(t, tag) + return w.commitManifest(t, ref) }