Skip to content

Commit

Permalink
Split --output flag for fixup and pull commands into 2 flags: --bundl…
Browse files Browse the repository at this point in the history
…e and --relocation-map

Fix and harden e2e test, checking fixed bundle and generated relocation map

Signed-off-by: Silvin Lubecki <[email protected]>
  • Loading branch information
silvin-lubecki committed Sep 10, 2019
1 parent 3117eda commit e145e39
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 41 deletions.
16 changes: 6 additions & 10 deletions cmd/cnab-to-oci/fixup.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import (

type fixupOptions struct {
input string
output string
bundle string
relocationMap string
targetRef string
insecureRegistries []string
autoUpdateBundle bool
Expand All @@ -35,7 +36,8 @@ func fixupCmd() *cobra.Command {
return runFixup(opts)
},
}
cmd.Flags().StringVarP(&opts.output, "output", "o", "fixed-bundle.json", "specify the output file")
cmd.Flags().StringVar(&opts.bundle, "bundle", "fixed-bundle.json", "fixed bundle output file (- to print on standard output)")
cmd.Flags().StringVar(&opts.relocationMap, "relocation-map", "relocation-map.json", "relocation map output file (- to print on standard output)")
cmd.Flags().StringVarP(&opts.targetRef, "target", "t", "", "reference where the bundle will be pushed")
cmd.Flags().StringSliceVar(&opts.insecureRegistries, "insecure-registries", nil, "Use plain HTTP for those registries")
cmd.Flags().BoolVar(&opts.autoUpdateBundle, "auto-update-bundle", false, "Updates the bundle image properties with the one resolved on the registry")
Expand Down Expand Up @@ -63,19 +65,13 @@ func runFixup(opts fixupOptions) error {
fixupOptions = append(fixupOptions, remotes.WithAutoBundleUpdate())
}
relocationMap, err := remotes.FixupBundle(context.Background(), &b, ref, createResolver(opts.insecureRegistries), fixupOptions...)
fmt.Println("Relocation map:", relocationMap)
if err != nil {
return err
}
bundleJSON, err = json.MarshalCanonical(b)
if err != nil {
if err := writeOutput(opts.bundle, b); err != nil {
return err
}
if opts.output == "-" {
fmt.Fprintln(os.Stdout, string(bundleJSON))
return nil
}
return ioutil.WriteFile(opts.output, bundleJSON, 0644)
return writeOutput(opts.relocationMap, relocationMap)
}

func displayEvent(ev remotes.FixupEvent) {
Expand Down
20 changes: 14 additions & 6 deletions cmd/cnab-to-oci/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (
)

type pullOptions struct {
output string
bundle string
relocationMap string
targetRef string
insecureRegistries []string
}
Expand All @@ -30,7 +31,8 @@ func pullCmd() *cobra.Command {
},
}

cmd.Flags().StringVarP(&opts.output, "output", "o", "pulled.json", "output file")
cmd.Flags().StringVar(&opts.bundle, "bundle", "pulled.json", "bundle output file (- to print on standard output)")
cmd.Flags().StringVar(&opts.relocationMap, "relocation-map", "relocation-map.json", "relocation map output file (- to print on standard output)")
cmd.Flags().StringSliceVar(&opts.insecureRegistries, "insecure-registries", nil, "Use plain HTTP for those registries")
return cmd
}
Expand All @@ -42,17 +44,23 @@ func runPull(opts pullOptions) error {
}

b, relocationMap, err := remotes.Pull(context.Background(), ref, createResolver(opts.insecureRegistries))
fmt.Println("Relocation map", relocationMap)
if err != nil {
return err
}
bytes, err := json.MarshalCanonical(b)
if err := writeOutput(opts.bundle, b); err != nil {
return err
}
return writeOutput(opts.relocationMap, relocationMap)
}

func writeOutput(file string, data interface{}) error {
bytes, err := json.MarshalCanonical(data)
if err != nil {
return err
}
if opts.output == "-" {
if file == "-" {
fmt.Fprintln(os.Stdout, string(bytes))
return nil
}
return ioutil.WriteFile(opts.output, bytes, 0644)
return ioutil.WriteFile(file, bytes, 0644)
}
1 change: 0 additions & 1 deletion cmd/cnab-to-oci/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ func runPush(opts pushOptions) error {
if err != nil {
return err
}
fmt.Println(relocationMap)
d, err := remotes.Push(context.Background(), &b, relocationMap, ref, resolver, opts.allowFallbacks)
if err != nil {
return err
Expand Down
81 changes: 58 additions & 23 deletions e2e/e2e_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package e2e

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
Expand All @@ -25,9 +26,13 @@ func TestPushAndPullCNAB(t *testing.T) {

invocationImageName := registry + "/e2e/hello-world:0.1.0-invoc"
serviceImageName := registry + "/e2e/http-echo"
appImageName := registry + "/myuser"

// Build invocation image
runCmd(t, icmd.Command("docker", "build", "-f", filepath.Join("testdata", "hello-world", "invocation-image", "Dockerfile"),
"-t", invocationImageName, filepath.Join("testdata", "hello-world", "invocation-image")))
cmd := icmd.Command("docker", "build", "-f", filepath.Join("testdata", "hello-world", "invocation-image", "Dockerfile"),
"-t", invocationImageName, filepath.Join("testdata", "hello-world", "invocation-image"))
cmd.Env = append(os.Environ(), "DOCKER_BUILDKIT=1")
runCmd(t, cmd)

// Fetch service image
runCmd(t, icmd.Command("docker", "pull", "hashicorp/http-echo"))
Expand All @@ -43,52 +48,53 @@ func TestPushAndPullCNAB(t *testing.T) {
runCmd(t, icmd.Command("docker", "push", serviceImageName))

// Templatize the bundle
tmpl, err := template.ParseFiles(filepath.Join("testdata", "hello-world", "bundle.json.template"))
assert.NilError(t, err)
data := struct {
InvocationImage string
ServiceImage string
}{
invocationImageName,
serviceImageName,
}
f, err := os.Create(dir.Join("bundle.json"))
assert.NilError(t, err)
defer f.Close()
err = tmpl.Execute(f, data)
assert.NilError(t, err)
applyTemplate(t, serviceImageName, invocationImageName, filepath.Join("testdata", "hello-world", "bundle.json.template"), dir.Join("bundle.json"))

// Save the fixed bundle
runCmd(t, icmd.Command("cnab-to-oci", "fixup", dir.Join("bundle.json"),
"--target", registry+"/myuser",
"--target", appImageName,
"--insecure-registries", registry,
"--output", dir.Join("fixed-bundle.json"),
"--bundle", dir.Join("fixed-bundle.json"),
"--relocation-map", dir.Join("relocation.json"),
"--auto-update-bundle"))

// Check the fixed bundle
applyTemplate(t, serviceImageName, invocationImageName, filepath.Join("testdata", "bundle.json.golden.template"), filepath.Join("testdata", "bundle.json.golden"))
buf, err := ioutil.ReadFile(dir.Join("fixed-bundle.json"))
assert.NilError(t, err)
golden.Assert(t, string(buf), "bundle.json.golden")

// Check the relocation map
checkRelocationMap(t, serviceImageName, invocationImageName, appImageName, dir.Join("relocation.json"))

// Re fix-up, checking it works twice
runCmd(t, icmd.Command("cnab-to-oci", "fixup", dir.Join("bundle.json"),
"--target", registry+"/myuser",
"--target", appImageName,
"--insecure-registries", registry,
"--output", dir.Join("fixed-bundle.json"),
"--bundle", dir.Join("fixed-bundle.json"),
"--auto-update-bundle"))

// Push the CNAB to the registry and get the digest
out := runCmd(t, icmd.Command("cnab-to-oci", "push", dir.Join("bundle.json"),
"--target", registry+"/myuser",
"--target", appImageName,
"--insecure-registries", registry,
"--auto-update-bundle"))
re := regexp.MustCompile(`"(.*)"`)
digest := re.FindAllStringSubmatch(out, -1)[0][1]

// Pull the CNAB from the registry
runCmd(t, icmd.Command("cnab-to-oci", "pull", registry+"/myuser@"+digest,
"--output", dir.Join("pulled-bundle.json"),
runCmd(t, icmd.Command("cnab-to-oci", "pull", fmt.Sprintf("%s@%s", appImageName, digest),
"--bundle", dir.Join("pulled-bundle.json"),
"--relocation-map", dir.Join("pulled-relocation.json"),
"--insecure-registries", registry))
pulledBundle, err := ioutil.ReadFile(dir.Join("pulled-bundle.json"))
assert.NilError(t, err)
pulledRelocation, err := ioutil.ReadFile(dir.Join("pulled-relocation.json"))
assert.NilError(t, err)

// Check the fixed bundle.json is equal to the pulled bundle.json
golden.Assert(t, string(pulledBundle), dir.Join("fixed-bundle.json"))
golden.Assert(t, string(pulledRelocation), dir.Join("relocation.json"))
}

func runCmd(t *testing.T, cmd icmd.Cmd) string {
Expand All @@ -98,3 +104,32 @@ func runCmd(t *testing.T, cmd icmd.Cmd) string {
result.Assert(t, icmd.Success)
return result.Stdout()
}

func applyTemplate(t *testing.T, serviceImageName, invocationImageName, templateFile, resultFile string) {
tmpl, err := template.ParseFiles(templateFile)
assert.NilError(t, err)
data := struct {
InvocationImage string
ServiceImage string
}{
invocationImageName,
serviceImageName,
}
f, err := os.Create(resultFile)
assert.NilError(t, err)
defer f.Close()
err = tmpl.Execute(f, data)
assert.NilError(t, err)
}

func checkRelocationMap(t *testing.T, serviceImageName, invocationImageName, appImageName, relocationMapFile string) {
data, err := ioutil.ReadFile(relocationMapFile)
assert.NilError(t, err)
relocationMap := map[string]string{}
err = json.Unmarshal(data, &relocationMap)
assert.NilError(t, err)

// Check the relocated images are in the app repository
assert.Assert(t, strings.HasPrefix(relocationMap[serviceImageName], appImageName))
assert.Assert(t, strings.HasPrefix(relocationMap[invocationImageName], appImageName))
}
1 change: 1 addition & 0 deletions e2e/testdata/bundle.json.golden.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"actions":{"io.cnab.status":{}},"definitions":{"port":{"default":"8080","type":"string"},"text":{"default":"Hello, World!","type":"string"}},"description":"Hello, World!","images":{"hello":{"contentDigest":"sha256:61d5cb94d7e546518a7bbd5bee06bfad0ecea8f56a75b084522a43dccbbcd845","description":"hello","image":"{{ .ServiceImage }}","imageType":"docker","mediaType":"application/vnd.docker.distribution.manifest.v2+json","size":528}},"invocationImages":[{"contentDigest":"sha256:5be99f09470367463607bd9eb4139d80fdd0c4020266c503c84f89e795f4e875","image":"{{ .InvocationImage }}","imageType":"docker","mediaType":"application/vnd.docker.distribution.manifest.v2+json","size":941}],"maintainers":[{"email":"[email protected]","name":"user"}],"name":"hello-world","parameters":{"fields":{"definition":"","destination":null}},"schemaVersion":"v1.0.0-WD","version":"0.1.0"}
2 changes: 1 addition & 1 deletion e2e/testdata/hello-world/bundle.json.template
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"actions":{"io.cnab.status":{}},"definitions":{"port":{"default":"8080","type":"string"},"text":{"default":"Hello, World!","type":"string"}},"description":"Hello, World!","images":{"hello":{"image":"{{ .ServiceImage }}","imageType":"docker"}},"invocationImages":[{"image":"{{ .InvocationImage }}","imageType":"docker"}],"maintainers":[{"email":"[email protected]","name":"user"}],"name":"hello-world","parameters":{"fields":{"port":{"definition":"port","destination":{"env":"PORT"}},"text":{"definition":"text","destination":{"env":"HELLO_TEXT"}}}},"schemaVersion":"v1.0.0-WD","version":"0.1.0"}
{"actions":{"io.cnab.status":{}},"definitions":{"port":{"default":"8080","type":"string"},"text":{"default":"Hello, World!","type":"string"}},"description":"Hello, World!","images":{"hello":{"description":"hello","image":"{{ .ServiceImage }}","imageType":"docker"}},"invocationImages":[{"image":"{{ .InvocationImage }}","imageType":"docker"}],"maintainers":[{"email":"[email protected]","name":"user"}],"name":"hello-world","parameters":{"fields":{"port":{"definition":"port","destination":{"env":"PORT"}},"text":{"definition":"text","destination":{"env":"HELLO_TEXT"}}}},"schemaVersion":"v1.0.0-WD","version":"0.1.0"}

0 comments on commit e145e39

Please sign in to comment.