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

Digest #678

Merged
merged 1 commit into from
Oct 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 46 additions & 10 deletions e2e/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,43 @@ func TestBuild(t *testing.T) {
cmd := info.configuredCmd

testDir := path.Join("testdata", "build")
cmd.Command = dockerCli.Command("app", "build", path.Join(testDir, "single"), "single:1.0.0")
cmd.Command = dockerCli.Command("app", "build", path.Join(testDir, "single"), "--tag", "single:1.0.0")
icmd.RunCmd(cmd).Assert(t, icmd.Success)

var cfg string
for _, s := range cmd.Env {
if strings.HasPrefix(s, "DOCKER_CONFIG=") {
cfg = s[14:]
}
}
if cfg == "" {
t.Fatalf("Failed to retrieve docker config folder")
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)
assert.NilError(t, err)

built := []string{bndl.InvocationImages[0].Digest, bndl.Images["web"].Digest, bndl.Images["worker"].Digest}
for _, ref := range built {
cmd.Command = dockerCli.Command("inspect", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
}
})
}

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

testDir := path.Join("testdata", "build")
cmd.Command = dockerCli.Command("app", "build", path.Join(testDir, "single"))
icmd.RunCmd(cmd).Assert(t, icmd.Success)

f := path.Join(cfg, "app", "bundles", "docker.io", "library", "single", "_tags", "1.0.0.json")
cfg := getDockerConfigDir(t, cmd)

f := path.Join(cfg, "app", "bundles", "_ids")
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, "bundle.json")
data, err := ioutil.ReadFile(f)
assert.NilError(t, err)
var bndl bundle.Bundle
Expand All @@ -44,3 +67,16 @@ func TestBuild(t *testing.T) {
}
})
}

func getDockerConfigDir(t *testing.T, cmd icmd.Cmd) string {
var cfg string
for _, s := range cmd.Env {
if strings.HasPrefix(s, "DOCKER_CONFIG=") {
cfg = s[14:]
}
}
if cfg == "" {
t.Fatalf("Failed to retrieve docker config folder")
}
return cfg
}
6 changes: 3 additions & 3 deletions e2e/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func TestRenderFormatters(t *testing.T) {
cmd := info.configuredCmd

appPath := filepath.Join("testdata", "simple", "simple.dockerapp")
cmd.Command = dockerCli.Command("app", "build", appPath, "a-simple-tag")
cmd.Command = dockerCli.Command("app", "build", appPath, "--tag", "a-simple-tag")
icmd.RunCmd(cmd).Assert(t, icmd.Success)

cmd.Command = dockerCli.Command("app", "render", "--formatter", "json", appPath)
Expand Down Expand Up @@ -161,10 +161,10 @@ func TestInspectApp(t *testing.T) {
cmd.Dir = dir.Path()
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
ExitCode: 1,
Err: "invalid reference format",
Err: "could not parse '' as a valid reference",
})

cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "simple-app:1.0.0")
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "--tag", "simple-app:1.0.0")
cmd.Dir = ""
icmd.RunCmd(cmd).Assert(t, icmd.Success)

Expand Down
14 changes: 7 additions & 7 deletions e2e/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (

func insertBundles(t *testing.T, cmd icmd.Cmd, info dindSwarmAndRegistryInfo) {
// Push an application so that we can later pull it by digest
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), info.registryAddress+"/c-myapp")
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), "--tag", info.registryAddress+"/c-myapp")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "b-simple-app")
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "--tag", "b-simple-app")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "a-simple-app")
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "--tag", "a-simple-app")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
}

Expand Down Expand Up @@ -86,7 +86,7 @@ func TestImageTag(t *testing.T) {
}

// given a first available image
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "a-simple-app")
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "simple", "simple.dockerapp"), "--tag", "a-simple-app")
icmd.RunCmd(cmd).Assert(t, icmd.Success)

singleImageExpectation := `APP IMAGE APP NAME
Expand All @@ -112,14 +112,14 @@ a-simple-app:latest simple
dockerAppImageTag("a-simple-app$2", "b-simple-app")
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
ExitCode: 1,
Err: `could not parse 'a-simple-app$2' as a valid reference: invalid reference format`,
Err: `could not parse 'a-simple-app$2' as a valid reference`,
})

// with invalid target reference
dockerAppImageTag("a-simple-app", "b@simple-app")
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
ExitCode: 1,
Err: `could not parse 'b@simple-app' as a valid reference: invalid reference format`,
Err: `could not parse 'b@simple-app' as a valid reference`,
})

// with unexisting source image
Expand Down Expand Up @@ -175,7 +175,7 @@ c-simple-app:latest simple
`)

// given a new application
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), "push-pull")
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), "--tag", "push-pull")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
expectImageListOutput(t, cmd, `APP IMAGE APP NAME
a-simple-app:0.1 simple
Expand Down
4 changes: 2 additions & 2 deletions e2e/pushpull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func TestPushInstallBundle(t *testing.T) {
ref := info.registryAddress + "/test/push-bundle"

// render the app to a bundle, we use the app from the push pull test above.
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), "a-simple-app:1.0.0")
cmd.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), "--tag", "a-simple-app:1.0.0")
icmd.RunCmd(cmd).Assert(t, icmd.Success)

// push it and install to check it is available
Expand Down Expand Up @@ -243,7 +243,7 @@ func TestPushInstallBundle(t *testing.T) {
cmdIsolatedStore.Env = append(cmdIsolatedStore.Env, "DOCKER_CONTEXT=swarm-context")

// bundle the app again but this time with a tag to store it into the bundle store
cmdIsolatedStore.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), ref2)
cmdIsolatedStore.Command = dockerCli.Command("app", "build", filepath.Join("testdata", "push-pull", "push-pull.dockerapp"), "--tag", ref2)
icmd.RunCmd(cmdIsolatedStore).Assert(t, icmd.Success)
// Push the app without tagging it explicitly
cmdIsolatedStore.Command = dockerCli.Command("app", "push", ref2)
Expand Down
32 changes: 9 additions & 23 deletions internal/commands/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@ type buildOptions struct {
func Cmd(dockerCli command.Cli) *cobra.Command {
var opts buildOptions
cmd := &cobra.Command{
Use: "build [APP_NAME] [APP_IMAGE]",
Use: "build [APP_NAME] [OPTIONS]",
Short: "Build service images for the application",
Example: `$ docker app build myapp.dockerapp my/app:1.0.0`,
Args: cli.ExactArgs(2),
Example: `$ docker app build myapp.dockerapp --tag my/app:1.0.0`,
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.tag = args[1]
tag, err := runBuild(dockerCli, args[0], opts)
ref, err := runBuild(dockerCli, args[0], opts)
if err == nil {
fmt.Printf("Successfully build %s\n", tag.String())
fmt.Printf("Successfully build %s\n", ref.String())
}
return err
},
Expand All @@ -56,23 +55,19 @@ func Cmd(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()
flags.BoolVar(&opts.noCache, "no-cache", false, "Do not use cache when building the image")
flags.StringVar(&opts.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
flags.StringVarP(&opts.tag, "tag", "t", "", "Application image and optionally a tag in the 'image:tag' format")
flags.BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image")

return cmd
}

func runBuild(dockerCli command.Cli, application string, opt buildOptions) (reference.Named, error) {
func runBuild(dockerCli command.Cli, application string, opt buildOptions) (reference.Reference, error) {
err := checkMinimalEngineVersion(dockerCli)
if err != nil {
return nil, err
}

if opt.tag == "" {
// FIXME temporary, until we get support for Digest in bundleStore and other commands
return nil, fmt.Errorf("A tag is required to run docker app build")
}

var ref reference.Named
var ref reference.Reference
ref, err = packager.GetNamedTagged(opt.tag)
if err != nil {
return nil, err
Expand Down Expand Up @@ -128,16 +123,7 @@ func runBuild(dockerCli command.Cli, application string, opt buildOptions) (refe
return nil, err
}

if ref == nil {
if ref, err = computeDigest(bundle); err != nil {
return nil, err
}
}

if err = packager.PersistInBundleStore(ref, bundle); err != nil {
return nil, err
}
return ref, nil
return packager.PersistInBundleStore(ref, bundle)
}

func checkMinimalEngineVersion(dockerCli command.Cli) error {
Expand Down
43 changes: 0 additions & 43 deletions internal/commands/build/digest.go

This file was deleted.

26 changes: 13 additions & 13 deletions internal/commands/cnab.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/deislabs/cnab-go/driver"
dockerDriver "github.com/deislabs/cnab-go/driver/docker"
"github.com/docker/app/internal"
"github.com/docker/app/internal/commands/image"
"github.com/docker/app/internal/log"
"github.com/docker/app/internal/packager"
appstore "github.com/docker/app/internal/store"
Expand Down Expand Up @@ -283,25 +284,24 @@ func resolveBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name
return nil, "", fmt.Errorf("could not resolve bundle %q", name)
}

func getBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name string) (*bundle.Bundle, reference.Named, error) {
ref, err := reference.ParseNormalizedNamed(name)
func getBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name string) (*bundle.Bundle, reference.Reference, error) {
ref, err := image.StringToRef(name)
if err != nil {
return nil, nil, errors.Wrap(err, name)
return nil, nil, err
}
tagRef := reference.TagNameOnly(ref)

bndl, err := bundleStore.Read(tagRef)
bndl, err := bundleStore.Read(ref)
if err != nil {
fmt.Fprintf(dockerCli.Err(), "Unable to find application image %q locally\n", reference.FamiliarString(tagRef))
fmt.Fprintf(dockerCli.Err(), "Unable to find application image %q locally\n", reference.FamiliarString(ref))

bndl, err = pullBundle(dockerCli, bundleStore, tagRef)
if err != nil {
return nil, nil, err
if named, ok := ref.(reference.Named); ok {
bndl, err = pullBundle(dockerCli, bundleStore, named)
if err != nil {
return nil, nil, err
}
}
return bndl, tagRef, nil
}

return bndl, tagRef, nil
return bndl, ref, nil
}

func pullBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, tagRef reference.Named) (*bundle.Bundle, error) {
Expand All @@ -314,7 +314,7 @@ func pullBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, tagRef
if err != nil {
return nil, err
}
if err := bundleStore.Store(tagRef, bndl); err != nil {
if _, err := bundleStore.Store(tagRef, bndl); err != nil {
return nil, err
}
return bndl, nil
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/image/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func runList(dockerCli command.Cli, bundleStore store.BundleStore) error {
return printImages(dockerCli, pkgs)
}

func getPackages(bundleStore store.BundleStore, references []reference.Named) ([]pkg, error) {
func getPackages(bundleStore store.BundleStore, references []reference.Reference) ([]pkg, error) {
packages := make([]pkg, len(references))
for i, ref := range references {
b, err := bundleStore.Read(ref)
Expand Down Expand Up @@ -112,6 +112,6 @@ var (
)

type pkg struct {
ref reference.Named
ref reference.Reference
bundle *bundle.Bundle
}
7 changes: 3 additions & 4 deletions internal/commands/image/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,15 @@ $ docker app image rm docker.io/library/myapp@sha256:beef...`,
}

func runRm(bundleStore store.BundleStore, app string) error {
ref, err := reference.ParseNormalizedNamed(app)
ref, err := StringToRef(app)
if err != nil {
return err
}

tagged := reference.TagNameOnly(ref)
if err := bundleStore.Remove(tagged); err != nil {
if err := bundleStore.Remove(ref); err != nil {
return err
}

fmt.Println("Deleted: " + reference.FamiliarString(tagged))
fmt.Println("Deleted: " + reference.FamiliarString(ref))
return nil
}
18 changes: 8 additions & 10 deletions internal/commands/image/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func runTag(bundleStore store.BundleStore, srcAppImage, destAppImage string) err
}

func readBundle(name string, bundleStore store.BundleStore) (*bundle.Bundle, error) {
cnabRef, err := stringToRef(name)
cnabRef, err := StringToRef(name)
if err != nil {
return nil, err
}
Expand All @@ -57,19 +57,17 @@ func readBundle(name string, bundleStore store.BundleStore) (*bundle.Bundle, err
}

func storeBundle(bundle *bundle.Bundle, name string, bundleStore store.BundleStore) error {
cnabRef, err := stringToRef(name)
cnabRef, err := StringToRef(name)
if err != nil {
return err
}

return bundleStore.Store(cnabRef, bundle)
_, err = bundleStore.Store(cnabRef, bundle)
return err
}

func stringToRef(name string) (reference.Named, error) {
cnabRef, err := reference.ParseNormalizedNamed(name)
if err != nil {
return nil, fmt.Errorf("could not parse '%s' as a valid reference: %v", name, err)
func StringToRef(s string) (reference.Reference, error) {
ndeloof marked this conversation as resolved.
Show resolved Hide resolved
ndeloof marked this conversation as resolved.
Show resolved Hide resolved
if named, err := reference.ParseNormalizedNamed(s); err == nil {
return reference.TagNameOnly(named), nil
}

return reference.TagNameOnly(cnabRef), nil
return store.FromString(s)
}