From a58f1d55bc799c55deb7cfaa35ef5234e9da7ff3 Mon Sep 17 00:00:00 2001 From: jonjohnsonjr Date: Wed, 28 Apr 2021 11:01:26 -0700 Subject: [PATCH] Propagate remote options through schema 1 copies (#1007) The schema 1 copying code was very hacked together, but remote.Put simplifies things a bit. This extends some of the crane/gcrane options down through to legacy.CopySchema1. --- internal/legacy/copy.go | 53 +++--------------------------------- internal/legacy/copy_test.go | 5 ++-- pkg/crane/copy.go | 16 +---------- 3 files changed, 7 insertions(+), 67 deletions(-) diff --git a/internal/legacy/copy.go b/internal/legacy/copy.go index 557c1d1fa..10467ba10 100644 --- a/internal/legacy/copy.go +++ b/internal/legacy/copy.go @@ -18,20 +18,14 @@ package legacy import ( "bytes" "encoding/json" - "fmt" - "net/http" - "net/url" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/logs" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/google/go-containerregistry/pkg/v1/remote/transport" ) // CopySchema1 allows `[g]crane cp` to work with old images without adding // full support for schema 1 images to this package. -func CopySchema1(desc *remote.Descriptor, srcRef, dstRef name.Reference, srcAuth, dstAuth authn.Authenticator) error { +func CopySchema1(desc *remote.Descriptor, srcRef, dstRef name.Reference, opts ...remote.Option) error { m := schema1{} if err := json.NewDecoder(bytes.NewReader(desc.Manifest)).Decode(&m); err != nil { return err @@ -41,56 +35,17 @@ func CopySchema1(desc *remote.Descriptor, srcRef, dstRef name.Reference, srcAuth src := srcRef.Context().Digest(layer.BlobSum) dst := dstRef.Context().Digest(layer.BlobSum) - blob, err := remote.Layer(src, remote.WithAuth(srcAuth)) + blob, err := remote.Layer(src, opts...) if err != nil { return err } - if err := remote.WriteLayer(dst.Context(), blob, remote.WithAuth(dstAuth)); err != nil { + if err := remote.WriteLayer(dst.Context(), blob, opts...); err != nil { return err } } - return putManifest(desc, dstRef, dstAuth) -} - -// TODO: perhaps expose this in remote? -func putManifest(desc *remote.Descriptor, dstRef name.Reference, dstAuth authn.Authenticator) error { - reg := dstRef.Context().Registry - scopes := []string{dstRef.Scope(transport.PushScope)} - - // TODO(jonjohnsonjr): Use NewWithContext. - tr, err := transport.New(reg, dstAuth, http.DefaultTransport, scopes) - if err != nil { - return err - } - client := &http.Client{Transport: tr} - - u := url.URL{ - Scheme: dstRef.Context().Registry.Scheme(), - Host: dstRef.Context().RegistryStr(), - Path: fmt.Sprintf("/v2/%s/manifests/%s", dstRef.Context().RepositoryStr(), dstRef.Identifier()), - } - - req, err := http.NewRequest(http.MethodPut, u.String(), bytes.NewBuffer(desc.Manifest)) - if err != nil { - return err - } - req.Header.Set("Content-Type", string(desc.MediaType)) - - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if err := transport.CheckError(resp, http.StatusOK, http.StatusCreated, http.StatusAccepted); err != nil { - return err - } - - // The image was successfully pushed! - logs.Progress.Printf("%v: digest: %v size: %d", dstRef, desc.Digest, len(desc.Manifest)) - return nil + return remote.Put(dstRef, desc, opts...) } type fslayer struct { diff --git a/internal/legacy/copy_test.go b/internal/legacy/copy_test.go index 49c0c58f8..e7992aab6 100644 --- a/internal/legacy/copy_test.go +++ b/internal/legacy/copy_test.go @@ -21,7 +21,6 @@ import ( "strings" "testing" - "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/registry" v1 "github.com/google/go-containerregistry/pkg/v1" @@ -87,11 +86,11 @@ func TestCopySchema1(t *testing.T) { }, }, } - if err := putManifest(desc, dstRef, authn.Anonymous); err != nil { + if err := remote.Put(dstRef, desc); err != nil { t.Fatal(err) } - if err := CopySchema1(desc, srcRef, dstRef, authn.Anonymous, authn.Anonymous); err != nil { + if err := CopySchema1(desc, srcRef, dstRef); err != nil { t.Errorf("failed to copy schema 1: %v", err) } } diff --git a/pkg/crane/copy.go b/pkg/crane/copy.go index 969b3d074..b922b34a6 100644 --- a/pkg/crane/copy.go +++ b/pkg/crane/copy.go @@ -18,7 +18,6 @@ import ( "fmt" "github.com/google/go-containerregistry/internal/legacy" - "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/logs" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/remote" @@ -59,7 +58,7 @@ func Copy(src, dst string, opt ...Option) error { } case types.DockerManifestSchema1, types.DockerManifestSchema1Signed: // Handle schema 1 images separately. - if err := copySchema1(desc, srcRef, dstRef); err != nil { + if err := legacy.CopySchema1(desc, srcRef, dstRef, o.remote...); err != nil { return fmt.Errorf("failed to copy schema 1 image: %v", err) } default: @@ -87,16 +86,3 @@ func copyIndex(desc *remote.Descriptor, dstRef name.Reference, o options) error } return remote.WriteIndex(dstRef, idx, o.remote...) } - -func copySchema1(desc *remote.Descriptor, srcRef, dstRef name.Reference) error { - srcAuth, err := authn.DefaultKeychain.Resolve(srcRef.Context().Registry) - if err != nil { - return err - } - dstAuth, err := authn.DefaultKeychain.Resolve(dstRef.Context().Registry) - if err != nil { - return err - } - - return legacy.CopySchema1(desc, srcRef, dstRef, srcAuth, dstAuth) -}