Skip to content

Commit

Permalink
save relocation map from cnab-to-oci
Browse files Browse the repository at this point in the history
When a relocation map is generated from `cnab-to-oci` save it
within the same directory as the `bundle.json` file.

More information about reloaction map can be found in corresponding
`cnab-to-oci` issue: cnabio/cnab-to-oci#58

The `bundle.Bundle` struct is now wrapped in a `relocated.Bundle`
that will also contain the relocation map.

Methods to fetch `bundle.json` and `relocation-map.json` as well
as en entire bundle with the relocation map at once are moved to
a `fetch` package to avoid dependency cycle.

Signed-off-by: Yves Brissaud <[email protected]>
  • Loading branch information
eunomie committed Nov 7, 2019
1 parent 42218d2 commit d48d5cc
Show file tree
Hide file tree
Showing 21 changed files with 274 additions and 126 deletions.
2 changes: 2 additions & 0 deletions Gopkg.lock

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

15 changes: 7 additions & 8 deletions e2e/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"strings"
"testing"

"github.com/docker/app/internal/relocated"

"gotest.tools/fs"

"github.com/docker/app/internal/store"
Expand All @@ -30,11 +32,8 @@ func TestBuild(t *testing.T) {

cfg := getDockerConfigDir(t, cmd)

f := path.Join(cfg, "app", "bundles", "docker.io", "library", "single", "_tags", "1.0.0", "bundle.json")
data, err := ioutil.ReadFile(f)
assert.NilError(t, err)
var bndl bundle.Bundle
err = json.Unmarshal(data, &bndl)
f := path.Join(cfg, "app", "bundles", "docker.io", "library", "single", "_tags", "1.0.0", relocated.BundleFilename)
bndl, err := relocated.BundleFromFile(f)
assert.NilError(t, err)

built := []string{bndl.InvocationImages[0].Digest, bndl.Images["web"].Digest, bndl.Images["worker"].Digest}
Expand All @@ -53,7 +52,7 @@ func TestBuild(t *testing.T) {
bytes, err := ioutil.ReadFile(iidfile)
assert.NilError(t, err)
iid := string(bytes)
actualID, err := store.FromBundle(&bndl)
actualID, err := store.FromBundle(bndl)
assert.NilError(t, err)
assert.Equal(t, iid, fmt.Sprintf("sha256:%s", actualID.String()))
})
Expand Down Expand Up @@ -96,7 +95,7 @@ func TestBuildWithoutTag(t *testing.T) {
assert.Equal(t, len(infos), 1)
id := infos[0].Name()

f = path.Join(cfg, "app", "bundles", "_ids", id, "bundle.json")
f = path.Join(cfg, "app", "bundles", "_ids", id, relocated.BundleFilename)
data, err := ioutil.ReadFile(f)
assert.NilError(t, err)
var bndl bundle.Bundle
Expand Down Expand Up @@ -127,7 +126,7 @@ func TestBuildWithArgs(t *testing.T) {
assert.Equal(t, len(infos), 1)
id := infos[0].Name()

f = path.Join(cfg, "app", "bundles", "_ids", id, "bundle.json")
f = path.Join(cfg, "app", "bundles", "_ids", id, relocated.BundleFilename)
data, err := ioutil.ReadFile(f)
assert.NilError(t, err)
var bndl bundle.Bundle
Expand Down
5 changes: 3 additions & 2 deletions e2e/cnab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"path"
"testing"

"github.com/docker/app/internal/relocated"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
"gotest.tools/icmd"
Expand Down Expand Up @@ -50,7 +51,7 @@ func TestCallCustomStatusAction(t *testing.T) {
icmd.RunCmd(cmd).Assert(t, icmd.Success)

// docker app install
cmd.Command = dockerCli.Command("app", "run", "--cnab-bundle-json", path.Join(testDir, "bundle.json"), "--name", testCase.name)
cmd.Command = dockerCli.Command("app", "run", "--cnab-bundle-json", path.Join(testDir, relocated.BundleFilename), "--name", testCase.name)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

// docker app uninstall
Expand Down Expand Up @@ -78,7 +79,7 @@ func TestCnabParameters(t *testing.T) {
}()

// docker app install
cmd.Command = dockerCli.Command("app", "run", "--cnab-bundle-json", path.Join(testDir, "bundle.json"), "--name", "cnab-parameters",
cmd.Command = dockerCli.Command("app", "run", "--cnab-bundle-json", path.Join(testDir, relocated.BundleFilename), "--name", "cnab-parameters",
"--set", "boolParam=true",
"--set", "stringParam=value",
"--set", "intParam=42")
Expand Down
7 changes: 4 additions & 3 deletions e2e/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/deislabs/cnab-go/credentials"
"github.com/docker/app/internal"
"github.com/docker/app/internal/relocated"
"github.com/docker/app/internal/yaml"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
Expand Down Expand Up @@ -205,7 +206,7 @@ func TestRunOnlyOne(t *testing.T) {
Err: `"docker app run" requires exactly 1 argument.`,
})

cmd.Command = dockerCli.Command("app", "run", "--cnab-bundle-json", "bundle.json", "myapp")
cmd.Command = dockerCli.Command("app", "run", "--cnab-bundle-json", relocated.BundleFilename, "myapp")
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
ExitCode: 1,
Err: `"docker app run" cannot run a bundle and an App image`,
Expand Down Expand Up @@ -348,14 +349,14 @@ func TestCredentials(t *testing.T) {
assert.NilError(t, err)
bundleJSON := golden.Get(t, "credential-install-bundle.json")
tmpDir := fs.NewDir(t, t.Name(),
fs.WithFile("bundle.json", "", fs.WithBytes(bundleJSON)),
fs.WithFile(relocated.BundleFilename, "", fs.WithBytes(bundleJSON)),
fs.WithDir("local",
fs.WithFile("test-creds.yaml", "", fs.WithBytes(buf)),
),
)
defer tmpDir.Remove()

bundle := tmpDir.Join("bundle.json")
bundle := tmpDir.Join(relocated.BundleFilename)

t.Run("missing", func(t *testing.T) {
cmd.Command = dockerCli.Command(
Expand Down
41 changes: 41 additions & 0 deletions e2e/relocation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package e2e

import (
"os"
"path/filepath"
"strings"
"testing"

"github.com/docker/app/internal/relocated"

"gotest.tools/assert"
"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, relocated.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, relocated.RelocationMapFilename))
assert.NilError(t, err)
})
}
32 changes: 11 additions & 21 deletions internal/cnab/cnab.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ package cnab
import (
"context"
"fmt"
"io/ioutil"
"os"

"github.com/deislabs/cnab-go/bundle"
"github.com/docker/app/internal"
"github.com/docker/app/internal/log"
"github.com/docker/app/internal/packager"
"github.com/docker/app/internal/relocated"
"github.com/docker/app/internal/store"
appstore "github.com/docker/app/internal/store"
"github.com/docker/cli/cli/command"
Expand Down Expand Up @@ -48,30 +47,20 @@ func getAppNameKind(name string) (string, nameKind) {
return name, nameKindReference
}

func extractAndLoadAppBasedBundle(dockerCli command.Cli, name string) (*bundle.Bundle, string, error) {
func extractAndLoadAppBasedBundle(dockerCli command.Cli, name string) (*relocated.Bundle, string, error) {
app, err := packager.Extract(name)
if err != nil {
return nil, "", err
}
defer app.Cleanup()
bndl, err := packager.MakeBundleFromApp(dockerCli, app, nil)
return bndl, "", err
}

// LoadBundleFromFile loads a bundle from a file
func LoadBundleFromFile(filename string) (*bundle.Bundle, error) {
b := &bundle.Bundle{}
data, err := ioutil.ReadFile(filename)
if err != nil {
return b, err
}
return bundle.Unmarshal(data)
return relocated.FromBundle(bndl), "", err
}

// ResolveBundle looks for a CNAB bundle which can be in a Docker App Package format or
// a bundle stored locally or in the bundle store. It returns a built or found bundle,
// a reference to the bundle if it is found in the bundlestore, and an error.
func ResolveBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name string) (*bundle.Bundle, string, error) {
func ResolveBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name string) (*relocated.Bundle, string, error) {
// resolution logic:
// - if there is a docker-app package in working directory or if a directory is given use packager.Extract
// - pull the bundle from the registry and add it to the bundle store
Expand All @@ -90,7 +79,7 @@ func ResolveBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name
}

// GetBundle searches for the bundle locally and tries to pull it if not found
func GetBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name string) (*bundle.Bundle, reference.Reference, error) {
func GetBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name string) (*relocated.Bundle, reference.Reference, error) {
bndl, ref, err := getBundleFromStore(bundleStore, name)
if err != nil {
named, err := store.StringToNamedRef(name)
Expand All @@ -108,7 +97,7 @@ func GetBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name str
return bndl, ref, nil
}

func getBundleFromStore(bundleStore appstore.BundleStore, name string) (*bundle.Bundle, reference.Reference, error) {
func getBundleFromStore(bundleStore appstore.BundleStore, name string) (*relocated.Bundle, reference.Reference, error) {
ref, err := bundleStore.LookUp(name)
if err != nil {
logrus.Debugf("Unable to find reference %q in the bundle store", name)
Expand All @@ -123,18 +112,19 @@ func getBundleFromStore(bundleStore appstore.BundleStore, name string) (*bundle.
}

// PullBundle pulls the bundle and stores it into the bundle store
func PullBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, tagRef reference.Named) (*bundle.Bundle, error) {
func PullBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, tagRef reference.Named) (*relocated.Bundle, error) {
insecureRegistries, err := internal.InsecureRegistriesFromEngine(dockerCli)
if err != nil {
return nil, fmt.Errorf("could not retrieve insecure registries: %v", err)
}

bndl, _, err := remotes.Pull(log.WithLogContext(context.Background()), reference.TagNameOnly(tagRef), remotes.CreateResolver(dockerCli.ConfigFile(), insecureRegistries...))
bndl, relocationMap, err := remotes.Pull(log.WithLogContext(context.Background()), reference.TagNameOnly(tagRef), remotes.CreateResolver(dockerCli.ConfigFile(), insecureRegistries...))
if err != nil {
return nil, err
}
if _, err := bundleStore.Store(tagRef, bndl); err != nil {
relocatedBundle := &relocated.Bundle{Bundle: bndl, RelocationMap: relocationMap}
if _, err := bundleStore.Store(tagRef, relocatedBundle); err != nil {
return nil, err
}
return bndl, nil
return relocatedBundle, nil
}
2 changes: 1 addition & 1 deletion internal/commands/image/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func runInspect(dockerCli command.Cli, appname string, opts inspectOptions) erro
if err != nil {
return err
}
installation.Bundle = bndl
installation.Bundle = bndl.Bundle
driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, opts.InstallerContextOptions, os.Stdout)
if err != nil {
return err
Expand Down
5 changes: 3 additions & 2 deletions internal/commands/image/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"strings"
"text/tabwriter"

"github.com/deislabs/cnab-go/bundle"
"github.com/docker/app/internal/relocated"

"github.com/docker/app/internal/store"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
Expand Down Expand Up @@ -182,5 +183,5 @@ func getImageListColumns(options imageListOption) []imageListColumn {

type pkg struct {
ref reference.Reference
bundle *bundle.Bundle
bundle *relocated.Bundle
}
34 changes: 21 additions & 13 deletions internal/commands/image/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"testing"

"github.com/docker/app/internal/relocated"

"gotest.tools/assert"

"github.com/deislabs/cnab-go/bundle"
Expand All @@ -15,18 +17,18 @@ import (
)

type bundleStoreStubForListCmd struct {
refMap map[reference.Reference]*bundle.Bundle
refMap map[reference.Reference]*relocated.Bundle
// in order to keep the reference in the same order between tests
refList []reference.Reference
}

func (b *bundleStoreStubForListCmd) Store(ref reference.Reference, bndle *bundle.Bundle) (reference.Digested, error) {
b.refMap[ref] = bndle
func (b *bundleStoreStubForListCmd) Store(ref reference.Reference, bndl *relocated.Bundle) (reference.Digested, error) {
b.refMap[ref] = bndl
b.refList = append(b.refList, ref)
return store.FromBundle(bndle)
return store.FromBundle(bndl)
}

func (b *bundleStoreStubForListCmd) Read(ref reference.Reference) (*bundle.Bundle, error) {
func (b *bundleStoreStubForListCmd) Read(ref reference.Reference) (*relocated.Bundle, error) {
bndl, ok := b.refMap[ref]
if ok {
return bndl, nil
Expand Down Expand Up @@ -54,17 +56,23 @@ func TestListCmd(t *testing.T) {
parseReference(t, "foo/bar:1.0"),
ref,
}
bundles := []bundle.Bundle{
bundles := []relocated.Bundle{
{
Name: "Digested App",
Bundle: &bundle.Bundle{
Name: "Digested App",
},
},
{
Version: "1.0.0",
SchemaVersion: "1.0.0",
Name: "Foo App",
Bundle: &bundle.Bundle{
Version: "1.0.0",
SchemaVersion: "1.0.0",
Name: "Foo App",
},
},
{
Name: "Quiet App",
Bundle: &bundle.Bundle{
Name: "Quiet App",
},
},
}

Expand Down Expand Up @@ -114,13 +122,13 @@ func parseReference(t *testing.T, s string) reference.Reference {
return ref
}

func testRunList(t *testing.T, refs []reference.Reference, bundles []bundle.Bundle, options imageListOption, expectedOutput string) {
func testRunList(t *testing.T, refs []reference.Reference, bundles []relocated.Bundle, options imageListOption, expectedOutput string) {
var buf bytes.Buffer
w := bufio.NewWriter(&buf)
dockerCli, err := command.NewDockerCli(command.WithOutputStream(w))
assert.NilError(t, err)
bundleStore := &bundleStoreStubForListCmd{
refMap: make(map[reference.Reference]*bundle.Bundle),
refMap: make(map[reference.Reference]*relocated.Bundle),
refList: []reference.Reference{},
}
for i, ref := range refs {
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/image/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func prepareCustomAction(actionName string, dockerCli command.Cli, appname strin
if err != nil {
return nil, nil, nil, err
}
installation.Bundle = bundle
installation.Bundle = bundle.Bundle

if err := bdl.MergeBundleParameters(installation,
bdl.WithFileParameters(opts.ParametersFiles),
Expand Down
Loading

0 comments on commit d48d5cc

Please sign in to comment.