Skip to content

Commit

Permalink
Propagate remote options through schema 1 copies (#1007)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jonjohnsonjr committed Apr 28, 2021
1 parent 5a37827 commit a58f1d5
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 67 deletions.
53 changes: 4 additions & 49 deletions internal/legacy/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down
5 changes: 2 additions & 3 deletions internal/legacy/copy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
}
16 changes: 1 addition & 15 deletions pkg/crane/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
}

0 comments on commit a58f1d5

Please sign in to comment.