Skip to content
This repository has been archived by the owner on Jun 13, 2021. It is now read-only.

Commit

Permalink
use docker/reference.Store to manage tags/digest by app image ID
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Jan 7, 2020
1 parent df1c57e commit 3064a5d
Show file tree
Hide file tree
Showing 19 changed files with 579 additions and 578 deletions.
6 changes: 5 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 12 additions & 35 deletions e2e/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ func TestBuild(t *testing.T) {
cmd.Command = dockerCli.Command("app", "build", "--tag", "single:1.0.0", "--iidfile", iidfile, "-f", path.Join(testDir, "single.dockerapp"), testDir)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

_, err := os.Stat(iidfile)
assert.NilError(t, err)
bytes, err := ioutil.ReadFile(iidfile)
assert.NilError(t, err)
iid := string(bytes)

cfg := getDockerConfigDir(t, cmd)

f := path.Join(cfg, "app", "bundles", "docker.io", "library", "single", "_tags", "1.0.0", image.BundleFilename)
s := strings.Split(iid, ":")
f := path.Join(cfg, "app", "bundles", "contents", s[0], s[1], image.BundleFilename)
bndl, err := image.FromFile(f)
assert.NilError(t, err)

Expand All @@ -47,11 +54,6 @@ func TestBuild(t *testing.T) {
assert.Assert(t, img.Image == "" || strings.Contains(img.Image, "@sha256:"))
}

_, err = os.Stat(iidfile)
assert.NilError(t, err)
bytes, err := ioutil.ReadFile(iidfile)
assert.NilError(t, err)
iid := string(bytes)
actualID, err := store.FromAppImage(bndl)
assert.NilError(t, err)
assert.Equal(t, iid, fmt.Sprintf("sha256:%s", actualID.String()))
Expand All @@ -67,31 +69,6 @@ func TestBuildMultiTag(t *testing.T) {
tags := []string{"1.0.0", "latest"}
cmd.Command = dockerCli.Command("app", "build", "--tag", "single:"+tags[0], "--tag", "single:"+tags[1], "--iidfile", iidfile, "-f", path.Join(testDir, "single.dockerapp"), testDir)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

cfg := getDockerConfigDir(t, cmd)

for _, tag := range tags {
f := path.Join(cfg, "app", "bundles", "docker.io", "library", "single", "_tags", tag, image.BundleFilename)
img, err := image.FromFile(f)
assert.NilError(t, err)
built := []string{img.InvocationImages[0].Digest, img.Images["web"].Digest, img.Images["worker"].Digest}
for _, ref := range built {
cmd.Command = dockerCli.Command("inspect", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
}
for _, img := range img.Images {
// Check all image not being built locally get a fixed reference
assert.Assert(t, img.Image == "" || strings.Contains(img.Image, "@sha256:"))
}
_, err = os.Stat(iidfile)
assert.NilError(t, err)
bytes, err := ioutil.ReadFile(iidfile)
assert.NilError(t, err)
iid := string(bytes)
actualID, err := store.FromAppImage(img)
assert.NilError(t, err)
assert.Equal(t, iid, fmt.Sprintf("sha256:%s", actualID.String()))
}
})
}

Expand Down Expand Up @@ -126,13 +103,13 @@ func TestBuildWithoutTag(t *testing.T) {

cfg := getDockerConfigDir(t, cmd)

f := path.Join(cfg, "app", "bundles", "_ids")
f := path.Join(cfg, "app", "bundles", "contents", "sha256")
infos, err := ioutil.ReadDir(f)
assert.NilError(t, err)
assert.Equal(t, len(infos), 1)
id := infos[0].Name()

f = path.Join(cfg, "app", "bundles", "_ids", id, image.BundleFilename)
f = path.Join(cfg, "app", "bundles", "contents", "sha256", id, image.BundleFilename)
data, err := ioutil.ReadFile(f)
assert.NilError(t, err)
var bndl bundle.Bundle
Expand All @@ -157,13 +134,13 @@ func TestBuildWithArgs(t *testing.T) {

cfg := getDockerConfigDir(t, cmd)

f := path.Join(cfg, "app", "bundles", "_ids")
f := path.Join(cfg, "app", "bundles", "contents", "sha256")
infos, err := ioutil.ReadDir(f)
assert.NilError(t, err)
assert.Equal(t, len(infos), 1)
id := infos[0].Name()

f = path.Join(cfg, "app", "bundles", "_ids", id, image.BundleFilename)
f = path.Join(cfg, "app", "bundles", "contents", "sha256", id, image.BundleFilename)
data, err := ioutil.ReadFile(f)
assert.NilError(t, err)
var bndl bundle.Bundle
Expand Down
8 changes: 7 additions & 1 deletion e2e/compatibility_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"testing"
"time"

"github.com/opencontainers/go-digest"

"gotest.tools/assert"
"k8s.io/apimachinery/pkg/util/wait"

Expand Down Expand Up @@ -72,9 +74,13 @@ func TestBackwardsCompatibilityV1(t *testing.T) {
data, err := ioutil.ReadFile(filepath.Join("testdata", "compatibility", "bundle-v0.9.0.json"))
assert.NilError(t, err)
// update bundle
bundleDir := filepath.Join(info.configDir, "app", "bundles", "docker.io", "library", "app-e2e", "_tags", "v0.9.0")
dg := digest.SHA256.FromBytes(data)
bundleDir := filepath.Join(info.configDir, "app", "bundles", "contents", dg.Algorithm().String(), dg.Encoded())
assert.NilError(t, os.MkdirAll(bundleDir, os.FileMode(0777)))
assert.NilError(t, ioutil.WriteFile(filepath.Join(bundleDir, "bundle.json"), data, os.FileMode(0644)))
metadata := filepath.Join(info.configDir, "app", "bundles", "repositories.json")
json := fmt.Sprintf("{\"Repositories\":{\"app-e2e\":{\"app-e2e:v0.9.0\":\"%s\"}}}", dg.String())
assert.NilError(t, ioutil.WriteFile(metadata, []byte(json), 0777))

// load images build with an old Docker App version
assert.NilError(t, loadAndTagImage(info, info.tmpDir, "app-e2e:0.1.0-invoc", "https://github.com/docker/app-e2e/raw/master/images/v0.9.0/app-e2e-invoc.tar"))
Expand Down
9 changes: 7 additions & 2 deletions e2e/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,14 @@ func runWithDindSwarmAndRegistry(t *testing.T, todo func(dindSwarmAndRegistryInf
todo(runner)
}

func build(t *testing.T, cmd icmd.Cmd, dockerCli dockerCliCommand, ref, path string) {
cmd.Command = dockerCli.Command("app", "build", "-t", ref, path)
func build(t *testing.T, cmd icmd.Cmd, dockerCli dockerCliCommand, ref, path string) string {
iidfile := fs.NewFile(t, "iid")
defer iidfile.Remove()
cmd.Command = dockerCli.Command("app", "build", "--iidfile", iidfile.Path(), "-t", ref, path)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
bytes, err := ioutil.ReadFile(iidfile.Path())
assert.NilError(t, err)
return string(bytes)
}

// Container represents a docker container
Expand Down
2 changes: 1 addition & 1 deletion e2e/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ Deleted: b-simple-app:latest`,
cmd.Command = dockerCli.Command("app", "image", "rm", "b-simple-app")
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
ExitCode: 1,
Err: `b-simple-app:latest: reference not found`,
Err: `b-simple-app: reference not found`,
})

expectedOutput := "REPOSITORY TAG APP IMAGE ID APP NAME \n"
Expand Down
4 changes: 2 additions & 2 deletions e2e/pushpull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ func TestPushUnknown(t *testing.T) {
cmd.Command = dockerCli.Command("app", "push", "unknown")
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
ExitCode: 1,
Err: `could not push "unknown:latest": no such App image: failed to read bundle "docker.io/library/unknown:latest": unknown:latest: reference not found`,
Err: `could not push "unknown": unknown: reference not found`,
})
})

t.Run("push invalid reference", func(t *testing.T) {
cmd.Command = dockerCli.Command("app", "push", "@")
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
ExitCode: 1,
Err: `could not push "@": invalid reference format`,
Err: `could not push "@": could not parse "@" as a valid reference: invalid reference format`,
})
})
}
Expand Down
50 changes: 7 additions & 43 deletions e2e/relocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,6 @@ import (
"gotest.tools/icmd"
)

func TestRelocationMapCreatedOnPull(t *testing.T) {
runWithDindSwarmAndRegistry(t, func(info dindSwarmAndRegistryInfo) {
cmd := info.configuredCmd
cfg := getDockerConfigDir(t, cmd)

path := filepath.Join("testdata", "local")
ref := info.registryAddress + "/test/local:a-tag"
bundlePath := filepath.Join(cfg, "app", "bundles", strings.Replace(info.registryAddress, ":", "_", 1), "test", "local", "_tags", "a-tag")

// Given a pushed application
build(t, cmd, dockerCli, ref, path)
cmd.Command = dockerCli.Command("app", "push", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
// And given application files are remove
assert.NilError(t, os.RemoveAll(bundlePath))
_, err := os.Stat(filepath.Join(bundlePath, image.BundleFilename))
assert.Assert(t, os.IsNotExist(err))

// When application is pulled
cmd.Command = dockerCli.Command("app", "pull", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

// Then the relocation map should exist
_, err = os.Stat(filepath.Join(bundlePath, image.RelocationMapFilename))
assert.NilError(t, err)
})
}

func TestRelocationMapRun(t *testing.T) {
runWithDindSwarmAndRegistry(t, func(info dindSwarmAndRegistryInfo) {
cmd := info.configuredCmd
Expand Down Expand Up @@ -82,7 +54,12 @@ func TestRelocationMapRun(t *testing.T) {
t.Run("without-relocation-map", func(t *testing.T) {
name := "test-relocation-map-run-without-relocation-map"
// And given the relocation map is removed after the pull
assert.NilError(t, os.RemoveAll(filepath.Join(bundlePath, image.RelocationMapFilename)))
assert.NilError(t, filepath.Walk(filepath.Join(cfg, "app", "bundles", "contents"), func(path string, info os.FileInfo, err error) error {
if info.Name() == image.RelocationMapFilename {
os.Remove(path)
}
return nil
}))

// Then the application cannot be run
cmd.Command = dockerCli.Command("app", "run", "--name", name, ref)
Expand All @@ -98,19 +75,13 @@ func TestPushPulledApplication(t *testing.T) {

path := filepath.Join("testdata", "local")
ref := info.registryAddress + "/test/local:a-tag"
bundlePath := filepath.Join(cfg, "app", "bundles", strings.Replace(info.registryAddress, ":", "_", 1), "test", "local", "_tags", "a-tag")

// Given an application pushed on a registry
build(t, cmd, dockerCli, ref, path)
cmd.Command = dockerCli.Command("app", "push", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
// And given local images are removed
cmd.Command = dockerCli.Command("rmi", "web", "local:1.1.0-beta1-invoc", "worker")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
// And given application files are remove
assert.NilError(t, os.RemoveAll(bundlePath))
_, err := os.Stat(filepath.Join(bundlePath, image.BundleFilename))
assert.Assert(t, os.IsNotExist(err))
assert.NilError(t, os.RemoveAll(filepath.Join(cfg, "app", "bundles")))

// And given application is pulled from the registry
cmd.Command = dockerCli.Command("app", "pull", ref)
Expand All @@ -119,13 +90,6 @@ func TestPushPulledApplication(t *testing.T) {
// Then the application can still be pushed
cmd.Command = dockerCli.Command("app", "push", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

// If relocation map is removed
assert.NilError(t, os.RemoveAll(filepath.Join(bundlePath, image.RelocationMapFilename)))

// Then the application cannot be pushed
cmd.Command = dockerCli.Command("app", "push", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Expected{ExitCode: 1})
})
}

Expand Down
2 changes: 1 addition & 1 deletion internal/cnab/cnab.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func PullBundle(dockerCli command.Cli, imageStore appstore.ImageStore, tagRef re
return nil, err
}
relocatedBundle := &image.AppImage{Bundle: bndl, RelocationMap: relocationMap}
if _, err := imageStore.Store(tagRef, relocatedBundle); err != nil {
if _, err := imageStore.Store(relocatedBundle, tagRef); err != nil {
return nil, err
}
return relocatedBundle, nil
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/image/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type imageStoreStubForListCmd struct {
refList []reference.Reference
}

func (b *imageStoreStubForListCmd) Store(ref reference.Reference, bndl *image.AppImage) (reference.Digested, error) {
func (b *imageStoreStubForListCmd) Store(bndl *image.AppImage, ref reference.Reference) (reference.Digested, error) {
b.refMap[ref] = bndl
b.refList = append(b.refList, ref)
return store.FromAppImage(bndl)
Expand Down Expand Up @@ -142,7 +142,7 @@ func testRunList(t *testing.T, refs []reference.Reference, bundles []image.AppIm
refList: []reference.Reference{},
}
for i, ref := range refs {
_, err = imageStore.Store(ref, &bundles[i])
_, err = imageStore.Store(&bundles[i], ref)
assert.NilError(t, err)
}
err = runList(dockerCli, options, imageStore)
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/image/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ func storeBundle(bundle *image.AppImage, name string, imageStore store.ImageStor
if err != nil {
return err
}
_, err = imageStore.Store(cnabRef, bundle)
_, err = imageStore.Store(bundle, cnabRef)
return err
}
2 changes: 1 addition & 1 deletion internal/commands/image/tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type imageStoreStub struct {
LookUpError error
}

func (b *imageStoreStub) Store(ref reference.Reference, bndle *image.AppImage) (reference.Digested, error) {
func (b *imageStoreStub) Store(img *image.AppImage, ref reference.Reference) (reference.Digested, error) {
defer func() {
b.StoredError = nil
}()
Expand Down
10 changes: 7 additions & 3 deletions internal/commands/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,21 @@ func runPush(dockerCli command.Cli, name string) error {
}

// Get the bundle
ref, err := reference.ParseDockerRef(name)
ref, err := imageStore.LookUp(name)
if err != nil {
return errors.Wrapf(err, "could not push %q", name)
}
named, ok := ref.(reference.Named)
if !ok {
return fmt.Errorf("could not push by ID. first tag your app image")
}

bndl, err := resolveReferenceAndBundle(imageStore, ref)
bndl, err := resolveReferenceAndBundle(imageStore, named)
if err != nil {
return err
}

cnabRef := reference.TagNameOnly(ref)
cnabRef := reference.TagNameOnly(named)

// Push the bundle
return pushBundle(dockerCli, bndl, cnabRef)
Expand Down
2 changes: 1 addition & 1 deletion internal/packager/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func PersistInImageStore(ref reference.Reference, bndl *bundle.Bundle) (referenc
if err != nil {
return nil, err
}
return imageStore.Store(ref, image.FromBundle(bndl))
return imageStore.Store(image.FromBundle(bndl), ref)
}

func GetNamedTagged(tag string) (reference.NamedTagged, error) {
Expand Down
Loading

0 comments on commit 3064a5d

Please sign in to comment.