diff --git a/pkg/config/relocation.go b/pkg/manifest/relocation.go similarity index 88% rename from pkg/config/relocation.go rename to pkg/manifest/relocation.go index 89a521a130..0fa6b18f32 100644 --- a/pkg/config/relocation.go +++ b/pkg/manifest/relocation.go @@ -1,4 +1,4 @@ -package config +package manifest // RelocationMapping represents a runtime provided mapping of a bundle image to a new tag type RelocationMapping map[string]string diff --git a/pkg/manifest/runtime-manifest.go b/pkg/manifest/runtime-manifest.go index 7ae3daa515..9cb90fa16d 100644 --- a/pkg/manifest/runtime-manifest.go +++ b/pkg/manifest/runtime-manifest.go @@ -318,6 +318,7 @@ func (m *RuntimeManifest) ResolveImages(bun *bundle.Bundle, reloMap RelocationMa if err != nil { return errors.Wrap(err, "unable to update image map from bundle.json") } + m.ImageMap[alias] = manifestImage } for alias, reloRef := range reloMap { @@ -326,6 +327,7 @@ func (m *RuntimeManifest) ResolveImages(bun *bundle.Bundle, reloMap RelocationMa if err != nil { return errors.Wrap(err, "unable to update image map from relocation mapping") } + m.ImageMap[alias] = manifestImage } return nil } @@ -338,8 +340,12 @@ func resolveImage(image *MappedImage, refString string) error { } switch v := ref.(type) { case reference.Canonical: + if tagged, ok := ref.(reference.NamedTagged); ok { + image.Tag = tagged.Tag() + } image.Repository = v.Name() image.Digest = v.Digest().String() + case reference.NamedTagged: image.Tag = v.Tag() image.Repository = v.Name() diff --git a/pkg/manifest/runtime-manifest_test.go b/pkg/manifest/runtime-manifest_test.go index dbf6a81be0..242e7c6071 100644 --- a/pkg/manifest/runtime-manifest_test.go +++ b/pkg/manifest/runtime-manifest_test.go @@ -894,12 +894,141 @@ func TestResolveImage(t *testing.T) { Tag: "latest", }, }, + { + name: "the one with a hostname", + reference: "deislabs.io/deislabs/porter-hello", + want: MappedImage{ + Repository: "deislabs.io/deislabs/porter-hello", + Tag: "latest", + }, + }, + { + name: "the one with a hostname and port", + reference: "deislabs.io:9090/deislabs/porter-hello:foo", + want: MappedImage{ + Repository: "deislabs.io:9090/deislabs/porter-hello", + Tag: "foo", + }, + }, + { + + name: "tagged and digested", + reference: "deislabs/porter-hello:latest@sha256:8b06c3da72dc9fa7002b9bc1f73a7421b4287c9cf0d3b08633287473707f9a63", + want: MappedImage{ + Repository: "deislabs/porter-hello", + Tag: "latest", + Digest: "sha256:8b06c3da72dc9fa7002b9bc1f73a7421b4287c9cf0d3b08633287473707f9a63", + }, + }, } for _, test := range tests { got := &MappedImage{} - resolveImage(got, test.reference) + err := resolveImage(got, test.reference) + assert.NoError(t, err) assert.Equal(t, test.want.Repository, got.Repository) assert.Equal(t, test.want.Tag, got.Tag) assert.Equal(t, test.want.Digest, got.Digest) } } + +func TestResolveImageErrors(t *testing.T) { + tests := []struct { + name string + reference string + want string + }{ + { + name: "no algo digest", + reference: "deislabs/porter-hello@8b06c3da72dc9fa7002b9bc1f73a7421b4287c9cf0d3b08633287473707f9a63", + want: "unable to parse docker image %s: invalid reference format", + }, + { + name: "bad digest", + reference: "deislabs/porter-hello@sha256:8b06c3da72dc9fa7002b9bc1f73a7421b4287c9cf0d3b08633287473707f", + want: "unable to parse docker image %s: invalid checksum digest length", + }, + { + name: "bad digest algo", + reference: "deislabs/porter-hello@sha356:8b06c3da72dc9fa7002b9bc1f73a7421b4287c9cf0d3b08633287473707f9a63", + want: "unable to parse docker image %s: unsupported digest algorithm", + }, + { + name: "malformed tagged ref", + reference: "deislabs/porter-hello@latest", + want: "unable to parse docker image %s: invalid reference format", + }, + { + name: "too many ports tagged ref", + reference: "deislabs:8080:8080/porter-hello:latest", + want: "unable to parse docker image %s: invalid reference format", + }, + } + for _, test := range tests { + got := &MappedImage{} + err := resolveImage(got, test.reference) + assert.EqualError(t, err, fmt.Sprintf(test.want, test.reference)) + } +} + +func TestResolveImageWithUpdatedBundle(t *testing.T) { + cxt := context.NewTestContext(t) + m := &Manifest{ + ImageMap: map[string]MappedImage{ + "machine": MappedImage{ + Repository: "deislabs/ghost", + Tag: "latest", + Digest: "sha256:75c495e5ce9c428d482973d72e3ce9925e1db304a97946c9aa0b540d7537e041", + }, + }, + } + + img := bundle.Image{} + img.Image = "blah/ghost:latest" + img.Digest = "sha256:75c495e5ce9c428d482973d72e3ce9925e1db304a97946c9aa0b540d7537e041" + bun := &bundle.Bundle{ + Images: map[string]bundle.Image{ + "machine": img, + }, + } + + reloMap := RelocationMapping{} + + rm := NewRuntimeManifest(cxt.Context, ActionInstall, m) + err := rm.ResolveImages(bun, reloMap) + assert.NoError(t, err) + mi := rm.ImageMap["machine"] + assert.Equal(t, "blah/ghost", mi.Repository) + +} +func TestResolveImageWithRelo(t *testing.T) { + cxt := context.NewTestContext(t) + m := &Manifest{ + ImageMap: map[string]MappedImage{ + "machine": MappedImage{ + Repository: "deislabs/ghost", + Tag: "latest", + Digest: "sha256:75c495e5ce9c428d482973d72e3ce9925e1db304a97946c9aa0b540d7537e041", + }, + }, + } + + img := bundle.Image{} + img.Image = "deislabs/ghost:latest" + img.Digest = "sha256:75c495e5ce9c428d482973d72e3ce9925e1db304a97946c9aa0b540d7537e041" + bun := &bundle.Bundle{ + Images: map[string]bundle.Image{ + "machine": img, + }, + } + + reloMap := RelocationMapping{ + "machine": "cnabio/ghost:latest", + } + + rm := NewRuntimeManifest(cxt.Context, ActionInstall, m) + err := rm.ResolveImages(bun, reloMap) + assert.NoError(t, err) + mi := rm.ImageMap["machine"] + assert.Equal(t, "cnabio/ghost", mi.Repository) + +} diff --git a/pkg/porter/run.go b/pkg/porter/run.go index ac4d013bbd..6d32b19a0c 100644 --- a/pkg/porter/run.go +++ b/pkg/porter/run.go @@ -114,7 +114,7 @@ func (p *Porter) Run(opts RunOptions) error { if err != nil { return errors.Wrap(err, "couldn't load runtime bundle.json") } - var reloMap config.RelocationMapping + var reloMap manifest.RelocationMapping if _, err := p.FileSystem.Stat("/cnab/app/relocation-mapping.json"); err == nil { reloBytes, err := p.FileSystem.ReadFile("/cnab/app/relocation-mapping.json") if err != nil {