Skip to content
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
102 changes: 101 additions & 1 deletion pkg/v1/daemon/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/types"
)

type image struct {
ref name.Reference
opener *imageOpener
tarballImage v1.Image
}

type imageOpener struct {
ref name.Reference
ctx context.Context
Expand Down Expand Up @@ -85,5 +92,98 @@ func Image(ref name.Reference, options ...Option) (v1.Image, error) {
ctx: o.ctx,
}

return tarball.Image(i.opener(), nil)
return &image{
ref: ref,
opener: i,
}, nil
}

func (i *image) initialize() error {
// Don't re-initialize tarball if already initialized.
if i.tarballImage == nil {
var err error
i.tarballImage, err = tarball.Image(i.opener.opener(), nil)
if err != nil {
return err
}
}
return nil
}

func (i *image) Layers() ([]v1.Layer, error) {
if err := i.initialize(); err != nil {
return nil, err
}
return i.tarballImage.Layers()
}

func (i image) MediaType() (types.MediaType, error) {
if err := i.initialize(); err != nil {
return "", err
}
return i.tarballImage.MediaType()
}

func (i *image) Size() (int64, error) {
if err := i.initialize(); err != nil {
return 0, err
}
return i.tarballImage.Size()
}

func (i *image) ConfigName() (v1.Hash, error) {
res, _, err := i.opener.client.ImageInspectWithRaw(i.opener.ctx, i.ref.String())
if err != nil {
return v1.Hash{}, err
}
return v1.NewHash(res.ID)
}

func (i image) ConfigFile() (*v1.ConfigFile, error) {
if err := i.initialize(); err != nil {
return nil, err
}
return i.tarballImage.ConfigFile()
}

func (i image) RawConfigFile() ([]byte, error) {
if err := i.initialize(); err != nil {
return nil, err
}
return i.tarballImage.RawConfigFile()
}

func (i image) Digest() (v1.Hash, error) {
if err := i.initialize(); err != nil {
return v1.Hash{}, err
}
return i.tarballImage.Digest()
}

func (i image) Manifest() (*v1.Manifest, error) {
if err := i.initialize(); err != nil {
return nil, err
}
return i.tarballImage.Manifest()
}

func (i image) RawManifest() ([]byte, error) {
if err := i.initialize(); err != nil {
return nil, err
}
return i.tarballImage.RawManifest()
}

func (i image) LayerByDigest(h v1.Hash) (v1.Layer, error) {
if err := i.initialize(); err != nil {
return nil, err
}
return i.tarballImage.LayerByDigest(h)
}

func (i image) LayerByDiffID(h v1.Hash) (v1.Layer, error) {
if err := i.initialize(); err != nil {
return nil, err
}
return i.tarballImage.LayerByDiffID(h)
}
27 changes: 24 additions & 3 deletions pkg/v1/daemon/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ import (
"strings"
"testing"

"github.com/docker/docker/api/types"
"github.com/google/go-containerregistry/internal/compare"
"github.com/google/go-containerregistry/pkg/name"

"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/validate"
)

var imagePath = "../tarball/testdata/test_image_1.tar"
Expand Down Expand Up @@ -62,6 +63,12 @@ func (m *MockClient) ImageSave(_ context.Context, _ []string) (io.ReadCloser, er
return m.saveBody, m.saveErr
}

func (m *MockClient) ImageInspectWithRaw(context.Context, string) (types.ImageInspect, []byte, error) {
return types.ImageInspect{
ID: "sha256:6e0b05049ed9c17d02e1a55e80d6599dbfcce7f4f4b022e3c673e685789c470e",
}, nil, nil
}

func TestImage(t *testing.T) {
for _, tc := range []struct {
name string
Expand Down Expand Up @@ -114,8 +121,22 @@ func TestImage(t *testing.T) {
}
return
}
if err := compare.Images(img, dmn); err != nil {
t.Errorf("compare.Images: %v", err)
err = compare.Images(img, dmn)
if err != nil {
if tc.wantErr == "" {
t.Errorf("compare.Images: %v", err)
} else if !strings.Contains(err.Error(), tc.wantErr) {
t.Errorf("wanted %s to contain %s", err.Error(), tc.wantErr)
}
}

err = validate.Image(dmn)
if err != nil {
if tc.wantErr == "" {
t.Errorf("validate.Image: %v", err)
} else if !strings.Contains(err.Error(), tc.wantErr) {
t.Errorf("wanted %s to contain %s", err.Error(), tc.wantErr)
}
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/v1/daemon/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,5 @@ type Client interface {
ImageSave(context.Context, []string) (io.ReadCloser, error)
ImageLoad(context.Context, io.Reader, bool) (types.ImageLoadResponse, error)
ImageTag(context.Context, string, string) error
ImageInspectWithRaw(context.Context, string) (types.ImageInspect, []byte, error)
}