Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

Revert reading images from the docker daemon #21

Merged
merged 1 commit into from
Aug 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ The Go packages provided by this repository include:

For details, please refer to the [package documentation](https://godoc.org/github.com/pivotal/image-relocation).

### Docker daemon

This repository reads images directly from their repositories and does not attempt to read images
from the Docker daemon. This is primarily because the daemon doesn't guarantee to provide the
same digest of an image as when the image has been pushed to a repository.

## Command line interface

A CLI, `irel`, is provided for manual use and experimentation. Issue `make irel` to build it.
Expand Down
14 changes: 1 addition & 13 deletions pkg/registry/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,16 @@ package registry

import (
"errors"
"fmt"
"net/http"

"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/pivotal/image-relocation/pkg/image"
)

var (
daemonImageFunc = daemon.Image
repoImageFunc = remote.Image
resolveFunc = authn.DefaultKeychain.Resolve
repoWriteFunc = remote.Write
Expand All @@ -54,16 +51,7 @@ func readRemoteImage(n image.Name) (v1.Image, error) {
return nil, err
}

img, err := daemonImageFunc(ref)
if err != nil {
var remoteErr error
img, remoteErr = repoImageFunc(ref, remote.WithAuth(auth))
if remoteErr != nil {
return nil, fmt.Errorf("reading remote image %s failed: %v; attempting to read from daemon also failed: %v", n.String(), remoteErr, err)
}
}

return img, nil
return remote.Image(ref, remote.WithAuth(auth))
}

func writeRemoteImage(i v1.Image, n image.Name) error {
Expand Down
89 changes: 1 addition & 88 deletions pkg/registry/remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/google/go-containerregistry/pkg/v1/remote"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -36,107 +35,21 @@ var _ = Describe("remote utilities", func() {
})

Describe("readRemoteImage", func() {
var (
mockImage2 *imagefakes.FakeImage

img v1.Image
)

JustBeforeEach(func() {
img, err = readRemoteImage(imageName)
_, err = readRemoteImage(imageName)
})

BeforeEach(func() {
var err error
imageName, err = image.NewName("imagename")
Expect(err).NotTo(HaveOccurred())

mockImage2 = &imagefakes.FakeImage{}
h2, err := v1.NewHash("sha256:1111111111111111111111111111111111111111111111111111111111111111")
Expect(err).NotTo(HaveOccurred())
mockImage2.DigestReturns(h2, nil)

Expect(mockImage).NotTo(Equal(mockImage2)) // crucial for the correctness of certain tests

// In most tests, keychain resolution succeeds
resolveFunc = func(registry name.Registry) (authn.Authenticator, error) {
return nil, nil
}
})

Context("when the daemon returns an image", func() {
BeforeEach(func() {
daemonImageFunc = func(ref name.Reference, options ...daemon.ImageOption) (v1.Image, error) {
return mockImage, nil
}
})

It("should return the image", func() {
Expect(err).NotTo(HaveOccurred())
Expect(img).To(Equal(mockImage))
})

Context("when the remote repository returns an image", func() {
BeforeEach(func() {
repoImageFunc = func(ref name.Reference, options ...remote.Option) (v1.Image, error) {
return mockImage2, nil
}
})

It("should return the image from the daemon", func() {
Expect(err).NotTo(HaveOccurred())
Expect(img).To(Equal(mockImage))
})
})

Context("when the remote repository returns an error", func() {
BeforeEach(func() {
repoImageFunc = func(ref name.Reference, options ...remote.Option) (v1.Image, error) {
return nil, testError
}
})

It("should return the image from the daemon", func() {
Expect(err).NotTo(HaveOccurred())
Expect(img).To(Equal(mockImage))
})
})

})

Context("when the daemon returns an error", func() {
BeforeEach(func() {
daemonImageFunc = func(ref name.Reference, options ...daemon.ImageOption) (v1.Image, error) {
return nil, testError
}
})

Context("when the remote repository returns an image", func() {
BeforeEach(func() {
repoImageFunc = func(ref name.Reference, options ...remote.Option) (v1.Image, error) {
return mockImage, nil
}
})

It("should return the image", func() {
Expect(err).NotTo(HaveOccurred())
Expect(img).To(Equal(mockImage))
})
})

Context("when the remote repository returns an error", func() {
BeforeEach(func() {
repoImageFunc = func(ref name.Reference, options ...remote.Option) (v1.Image, error) {
return nil, errors.New("repo error")
}
})

It("should return a combined error", func() {
Expect(err).To(MatchError("reading remote image docker.io/library/imagename:latest failed: repo error; attempting to read from daemon also failed: hard cheese"))
})
})
})

Context("when keychain resolution fails", func() {
BeforeEach(func() {
resolveFunc = func(registry name.Registry) (authn.Authenticator, error) {
Expand Down