Skip to content

Commit

Permalink
Rebase uses new Image interface
Browse files Browse the repository at this point in the history
* Eventually we will refactor all command to use this new abstraction

Signed-off-by: Emily Casey <ecasey@pivotal.io>
Signed-off-by: Dave Goddard <dave@goddard.id.au>
  • Loading branch information
ekcasey authored and dgodd committed Oct 25, 2018
1 parent 4e05716 commit 5f97064
Show file tree
Hide file tree
Showing 15 changed files with 1,366 additions and 479 deletions.
8 changes: 4 additions & 4 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
Labels: map[string]string{"io.buildpacks.stack.id": "some.stack.id"},
},
}, nil, nil)
mockRunImage := mocks.NewMockImage(mockController)
mockRunImage := mocks.NewMockV1Image(mockController)
mockImages.EXPECT().ReadImage("some/run", false).Return(mockRunImage, nil)
mockRunImage.EXPECT().ConfigFile().Return(&v1.ConfigFile{
Config: v1.Config{
Expand All @@ -178,7 +178,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
Labels: map[string]string{"io.buildpacks.stack.id": "some.stack.id"},
},
}, nil, nil)
mockRunImage := mocks.NewMockImage(mockController)
mockRunImage := mocks.NewMockV1Image(mockController)
mockImages.EXPECT().ReadImage("override/run", false).Return(mockRunImage, nil)
mockRunImage.EXPECT().ConfigFile().Return(&v1.ConfigFile{
Config: v1.Config{
Expand All @@ -205,7 +205,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
Labels: map[string]string{"io.buildpacks.stack.id": "some.stack.id"},
},
}, nil, nil)
mockRunImage := mocks.NewMockImage(mockController)
mockRunImage := mocks.NewMockV1Image(mockController)
mockImages.EXPECT().ReadImage("override/run", false).Return(mockRunImage, nil)
mockRunImage.EXPECT().ConfigFile().Return(&v1.ConfigFile{
Config: v1.Config{
Expand All @@ -231,7 +231,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
Labels: map[string]string{"io.buildpacks.stack.id": "some.stack.id"},
},
}, nil, nil)
mockRunImage := mocks.NewMockImage(mockController)
mockRunImage := mocks.NewMockV1Image(mockController)
mockImages.EXPECT().ReadImage("override/run", false).Return(mockRunImage, nil)
mockRunImage.EXPECT().ConfigFile().Return(&v1.ConfigFile{
Config: v1.Config{
Expand Down
9 changes: 4 additions & 5 deletions cmd/pack/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func rebaseCommand() *cobra.Command {
cmd.SilenceUsage = true
flags.RepoName = args[0]

docker, err := docker.New()
imageFactory, err := image.DefaultFactory()
if err != nil {
return err
}
Expand All @@ -113,10 +113,9 @@ func rebaseCommand() *cobra.Command {
return err
}
factory := pack.RebaseFactory{
Log: log.New(os.Stdout, "", log.LstdFlags),
Docker: docker,
Config: cfg,
Images: &image.Client{},
Log: log.New(os.Stdout, "", log.LstdFlags),
Config: cfg,
ImageFactory: imageFactory,
}
rebaseConfig, err := factory.RebaseConfigFromFlags(flags)
if err != nil {
Expand Down
22 changes: 11 additions & 11 deletions create_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestCreateBuilder(t *testing.T) {
spec.Run(t, "create-builder", testCreateBuilder, spec.Sequential(), spec.Report(report.Terminal{}))
}

//go:generate mockgen -package mocks -destination mocks/img.go github.com/google/go-containerregistry/pkg/v1 Image
//go:generate mockgen -package mocks -destination mocks/img.go -mock_names Image=MockV1Image github.com/google/go-containerregistry/pkg/v1 Image
//go:generate mockgen -package mocks -destination mocks/store.go github.com/buildpack/lifecycle/img Store

func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
Expand Down Expand Up @@ -92,7 +92,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {

when("#BuilderConfigFromFlags", func() {
it("uses default stack build image as base image", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)
mockDocker.EXPECT().PullImage("default/build")
mockImages.EXPECT().ReadImage("default/build", true).Return(mockBaseImage, nil)
Expand All @@ -114,7 +114,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
})

it("select the build image with matching registry", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)
mockDocker.EXPECT().PullImage("registry.com/build/image")
mockImages.EXPECT().ReadImage("registry.com/build/image", true).Return(mockBaseImage, nil)
Expand All @@ -136,7 +136,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
})

it("doesn't pull base a new image when --no-pull flag is provided", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)
mockImages.EXPECT().ReadImage("default/build", true).Return(mockBaseImage, nil)
mockImages.EXPECT().RepoStore("some/image", true).Return(mockImageStore, nil)
Expand Down Expand Up @@ -202,7 +202,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {

when("-s flag is provided", func() {
it("used the build image from the selected stack", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)
mockDocker.EXPECT().PullImage("other/build")
mockImages.EXPECT().ReadImage("other/build", true).Return(mockBaseImage, nil)
Expand Down Expand Up @@ -235,7 +235,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {

when("--publish is passed", func() {
it("uses a registry store and doesn't pull base image", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)
mockImages.EXPECT().ReadImage("default/build", false).Return(mockBaseImage, nil)
mockImages.EXPECT().RepoStore("some/image", false).Return(mockImageStore, nil)
Expand All @@ -260,7 +260,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
when("#Create", func() {
when("successful", func() {
it("logs usage tip", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)

mockBaseImage.EXPECT().Manifest().Return(&v1.Manifest{}, nil)
Expand All @@ -284,7 +284,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
})
when("a buildpack location uses no scheme uris", func() {
it("supports relative directories as well as archives", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)

mockImages.EXPECT().ReadImage("default/build", true).Return(mockBaseImage, nil)
Expand All @@ -305,7 +305,7 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
assertDirContainsFileWithContents(t, builderConfig.Buildpacks[1].Dir, "bin/build", "I come from an archive")
})
it("supports absolute directories as well as archives", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)

mockImages.EXPECT().ReadImage("default/build", true).Return(mockBaseImage, nil)
Expand Down Expand Up @@ -353,7 +353,7 @@ buildpacks = [
})
when("a buildpack location uses file:// uris", func() {
it("supports absolute directories as well as archives", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)

mockImages.EXPECT().ReadImage("default/build", true).Return(mockBaseImage, nil)
Expand Down Expand Up @@ -428,7 +428,7 @@ buildpacks = [
}
})
it("downloads and extracts the archive", func() {
mockBaseImage := mocks.NewMockImage(mockController)
mockBaseImage := mocks.NewMockV1Image(mockController)
mockImageStore := mocks.NewMockStore(mockController)

mockImages.EXPECT().ReadImage("default/build", true).Return(mockBaseImage, nil)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/sclevine/spec v1.0.0
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 // indirect
github.com/stretchr/testify v1.2.2
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 // indirect
golang.org/x/sys v0.0.0-20181025063200-d989b31c8746 // indirect
)
Expand Down
88 changes: 88 additions & 0 deletions image/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package image

import (
"context"
"github.com/buildpack/lifecycle/img"
"github.com/buildpack/pack/docker"
"github.com/buildpack/pack/fs"
"github.com/buildpack/packs"
"github.com/docker/docker/api/types"
"github.com/google/go-containerregistry/pkg/v1"
"io"
"log"
"os"
)

type Image interface {
Label(string) (string, error)
Name() string
Digest() (string, error)
Rebase(string, Image) error
SetLabel(string, string) error
TopLayer() (string, error)
Save() (string, error)
}

type Docker interface {
PullImage(ref string) error
ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error)
ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
ImageRemove(ctx context.Context, ref string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error)
}

type Factory struct {
Docker Docker
Log *log.Logger
Stdout io.Writer
FS *fs.FS
}

func DefaultFactory() (*Factory, error) {
f := &Factory{
Stdout: os.Stdout,
Log: log.New(os.Stdout, "", log.LstdFlags),
FS: &fs.FS{},
}

var err error
f.Docker, err = docker.New()
if err != nil {
return nil, err
}

return f, nil
}

type Client struct{}

func (c *Client) ReadImage(repoName string, useDaemon bool) (v1.Image, error) {
repoStore, err := c.RepoStore(repoName, useDaemon)
if err != nil {
return nil, err
}

origImage, err := repoStore.Image()
if err != nil {
// Assume error is due to non-existent image
return nil, nil
}
if _, err := origImage.RawManifest(); err != nil {
// Assume error is due to non-existent image
// This is necessary for registries
return nil, nil
}

return origImage, nil
}

func (c *Client) RepoStore(repoName string, useDaemon bool) (img.Store, error) {
newRepoStore := img.NewRegistry
if useDaemon {
newRepoStore = img.NewDaemon
}
repoStore, err := newRepoStore(repoName)
if err != nil {
return nil, packs.FailErr(err, "access", repoName)
}
return repoStore, nil
}
42 changes: 0 additions & 42 deletions image/image.go

This file was deleted.

Loading

0 comments on commit 5f97064

Please sign in to comment.