Skip to content

Commit

Permalink
Merge pull request docker#529 from ijc/push-from-bundle
Browse files Browse the repository at this point in the history
Push directly from bundle
  • Loading branch information
silvin-lubecki committed May 13, 2019
2 parents 368989a + ced138b commit b953958
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 17 deletions.
17 changes: 9 additions & 8 deletions e2e/commands_test.go
Expand Up @@ -66,14 +66,15 @@ func testRenderApp(appPath string, env ...string) func(*testing.T) {
}
cmd.Command = args
cmd.Env = append(cmd.Env, env...)
// Check rendering to stdout
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
assert.Assert(t, is.Equal(readFile(t, filepath.Join(appPath, "expected.txt")), result.Stdout()), "rendering mismatch")
// Checks rendering to a file
cmd.Command = append(cmd.Command, "--output="+dir.Join("actual.yaml"))
icmd.RunCmd(cmd).Assert(t, icmd.Success)

assert.Assert(t, is.Equal(readFile(t, filepath.Join(appPath, "expected.txt")), readFile(t, dir.Join("actual.yaml"))), "rendering mismatch")
t.Run("stdout", func(t *testing.T) {
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
assert.Assert(t, is.Equal(readFile(t, filepath.Join(appPath, "expected.txt")), result.Stdout()), "rendering mismatch")
})
t.Run("file", func(t *testing.T) {
cmd.Command = append(cmd.Command, "--output="+dir.Join("actual.yaml"))
icmd.RunCmd(cmd).Assert(t, icmd.Success)
assert.Assert(t, is.Equal(readFile(t, filepath.Join(appPath, "expected.txt")), readFile(t, dir.Join("actual.yaml"))), "rendering mismatch")
})
}
}

Expand Down
48 changes: 48 additions & 0 deletions e2e/pushpull_test.go
Expand Up @@ -6,6 +6,7 @@ import (
"net"
"path/filepath"
"strconv"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -132,6 +133,53 @@ func TestPushPullInstall(t *testing.T) {
})
}

func TestPushInstallBundle(t *testing.T) {
runWithDindSwarmAndRegistry(t, func(info dindSwarmAndRegistryInfo) {
cmd := info.configuredCmd
ref := info.registryAddress + "/test/push-bundle"

tmpDir := fs.NewDir(t, t.Name())
defer tmpDir.Remove()
bundleFile := tmpDir.Join("bundle.json")

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

// push it and install to check it is available
t.Run("push-bundle", func(t *testing.T) {
name := strings.Replace(t.Name(), "/", "_", 1)
cmd.Command = dockerCli.Command("app", "push", "--insecure-registries="+info.registryAddress, "--tag", ref, bundleFile)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

cmd.Command = dockerCli.Command("app", "install", "--insecure-registries="+info.registryAddress, ref, "--name", name)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
cmd.Command = dockerCli.Command("service", "ls")
assert.Check(t, cmp.Contains(icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined(), ref))

// ensure it doesn't confuse the next test
cmd.Command = dockerCli.Command("app", "uninstall", name)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

cmd.Command = dockerCli.Command("service", "ls")
assert.Check(t, !strings.Contains(icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined(), ref))
})

// push it again using the first ref and install from the new ref to check it is also available
t.Run("push-ref", func(t *testing.T) {
name := strings.Replace(t.Name(), "/", "_", 1)
ref2 := info.registryAddress + "/test/push-ref"
cmd.Command = dockerCli.Command("app", "push", "--insecure-registries="+info.registryAddress, "--tag", ref2, ref+":latest")
icmd.RunCmd(cmd).Assert(t, icmd.Success)

cmd.Command = dockerCli.Command("app", "install", "--insecure-registries="+info.registryAddress, ref2, "--name", name)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
cmd.Command = dockerCli.Command("service", "ls")
assert.Check(t, cmp.Contains(icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined(), ref2))
})
})
}

func findAvailablePort() int {
rand.Seed(time.Now().UnixNano())
for {
Expand Down
22 changes: 13 additions & 9 deletions internal/commands/push.go
Expand Up @@ -11,7 +11,6 @@ import (

"github.com/containerd/containerd/platforms"
"github.com/deislabs/cnab-go/bundle"
"github.com/docker/app/internal/packager"
"github.com/docker/app/types/metadata"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
Expand Down Expand Up @@ -52,16 +51,21 @@ func pushCmd(dockerCli command.Cli) *cobra.Command {

func runPush(dockerCli command.Cli, name string, opts pushOptions) error {
defer muteDockerCli(dockerCli)()
app, err := packager.Extract(name)

bundleStore, err := prepareBundleStore()
if err != nil {
return err
}
defer app.Cleanup()
bndl, err := makeBundleFromApp(dockerCli, app, nil)

bndl, _, err := resolveBundle(dockerCli, bundleStore, name, false, nil)
if err != nil {
return err
}
retag, err := shouldRetagInvocationImage(app.Metadata(), bndl, opts.tag)
if err := bndl.Validate(); err != nil {
return err
}

retag, err := shouldRetagInvocationImage(metadata.FromBundle(bndl), bndl, opts.tag)
if err != nil {
return err
}
Expand All @@ -85,11 +89,11 @@ func runPush(dockerCli command.Cli, name string, opts pushOptions) error {
RegistryAuth: encodedAuth,
})
if err != nil {
return err
return errors.Wrapf(err, "starting push of %q", retag.invocationImageRef.String())
}
defer reader.Close()
if err = jsonmessage.DisplayJSONMessagesStream(reader, ioutil.Discard, 0, false, nil); err != nil {
return err
return errors.Wrapf(err, "pushing to %q", retag.invocationImageRef.String())
}

resolverConfig := remotes.NewResolverConfigFromDockerConfigFile(dockerCli.ConfigFile(), opts.registry.insecureRegistries...)
Expand All @@ -107,12 +111,12 @@ func runPush(dockerCli command.Cli, name string, opts pushOptions) error {
err = remotes.FixupBundle(context.Background(), bndl, retag.cnabRef, resolverConfig, fixupOptions...)

if err != nil {
return err
return errors.Wrapf(err, "fixing up %q for push", retag.cnabRef)
}
// push bundle manifest
descriptor, err := remotes.Push(context.Background(), bndl, retag.cnabRef, resolverConfig.Resolver, true)
if err != nil {
return err
return errors.Wrapf(err, "pushing to %q", retag.cnabRef)
}
fmt.Printf("Successfully pushed bundle to %s. Digest is %s.\n", retag.cnabRef.String(), descriptor.Digest)
return nil
Expand Down
12 changes: 12 additions & 0 deletions internal/commands/root.go
Expand Up @@ -78,6 +78,18 @@ func prepareStores(targetContext string) (store.BundleStore, store.InstallationS
return bundleStore, installationStore, credentialStore, nil
}

func prepareBundleStore() (store.BundleStore, error) {
appstore, err := store.NewApplicationStore(config.Dir())
if err != nil {
return nil, err
}
bundleStore, err := appstore.BundleStore()
if err != nil {
return nil, err
}
return bundleStore, nil
}

type parametersOptions struct {
parametersFiles []string
overrides []string
Expand Down
18 changes: 18 additions & 0 deletions types/metadata/metadata.go
Expand Up @@ -2,6 +2,8 @@ package metadata

import (
"strings"

"github.com/deislabs/cnab-go/bundle"
)

// Maintainer represents one of the apps's maintainers
Expand Down Expand Up @@ -38,3 +40,19 @@ type AppMetadata struct {
Description string `json:"description,omitempty"`
Maintainers Maintainers `json:"maintainers,omitempty"`
}

// Metadata extracts the docker-app metadata from the bundle
func FromBundle(bndl *bundle.Bundle) AppMetadata {
meta := AppMetadata{
Name: bndl.Name,
Version: bndl.Version,
Description: bndl.Description,
}
for _, m := range bndl.Maintainers {
meta.Maintainers = append(meta.Maintainers, Maintainer{
Name: m.Name,
Email: m.Email,
})
}
return meta
}

0 comments on commit b953958

Please sign in to comment.