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

Commit

Permalink
Add "--service-images" to pull command
Browse files Browse the repository at this point in the history
This allows users in a single node configuration to optionally pull
down the service images defined in an app bundle with:

 docker app pull --service-images [your app]

Fixes: fixes #789

Signed-off-by: Andy Doan <andy@foundries.io>
  • Loading branch information
doanac committed Jan 10, 2020
1 parent 6d698be commit 445fe77
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
22 changes: 22 additions & 0 deletions e2e/pushpull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,28 @@ Unable to find App "unknown": failed to resolve bundle manifest "docker.io/libra
})
}

func TestPushPullServiceImages(t *testing.T) {
runWithDindSwarmAndRegistry(t, func(info dindSwarmAndRegistryInfo) {
cmd := info.configuredCmd
ref := info.registryAddress + "/test/push-pull"
tag := ":v.0.0.1"
build(t, cmd, dockerCli, ref+tag, filepath.Join("testdata", "push-pull"))

cmd.Command = dockerCli.Command("app", "push", ref+tag)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

// Make sure this image does not exist so that we can verify the pull works.
cmd.Command = dockerCli.Command("image", "rm", "busybox:1.30.1")
icmd.RunCmd(cmd).Assert(t, icmd.Success)

cmd.Command = dockerCli.Command("app", "pull", "--service-images", ref+tag)
icmd.RunCmd(cmd).Assert(t, icmd.Success)

cmd.Command = dockerCli.Command("image", "inspect", "busybox@sha256:4b6ad3a68d34da29bf7c8ccb5d355ba8b4babcad1f99798204e7abb43e54ee3d")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
})
}

func TestPushInstallBundle(t *testing.T) {
runWithDindSwarmAndRegistry(t, func(info dindSwarmAndRegistryInfo) {
cmd := info.configuredCmd
Expand Down
53 changes: 51 additions & 2 deletions internal/commands/pull.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,73 @@
package commands

import (
"context"
"fmt"
"os"

"github.com/docker/docker/api/types"
"github.com/docker/app/internal/cnab"
"github.com/docker/app/internal/packager"
"github.com/docker/app/internal/store"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
"github.com/docker/distribution/reference"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

type pullOptions struct {
serviceImages bool
}

func pullCmd(dockerCli command.Cli) *cobra.Command {
var opts pullOptions

cmd := &cobra.Command{
Use: "pull APP_IMAGE",
Short: "Pull an App image from a registry",
Example: `$ docker app pull myrepo/myapp:0.1.0`,
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runPull(dockerCli, args[0])
return runPull(dockerCli, opts, args[0])
},
}
cmd.Flags().BoolVar(&opts.serviceImages, "service-images", false, "Also pull down service images to this host's context")
return cmd
}

func runPull(dockerCli command.Cli, name string) error {
func pullImage(ctx context.Context, cli command.Cli, image string) error {
ref, err := reference.ParseNormalizedNamed(image)
if err != nil {
return err
}

// Resolve the Repository name from fqn to RepositoryInfo
repoInfo, err := registry.ParseRepositoryInfo(ref)
if err != nil {
return err
}
authConfig := command.ResolveAuthConfig(ctx, cli, repoInfo.Index)
encodedAuth, err := command.EncodeAuthToBase64(authConfig)
if err != nil {
return err
}
options := types.ImagePullOptions{
RegistryAuth: encodedAuth,
}
responseBody, err := cli.Client().ImagePull(ctx, image, options)
if err != nil {
return err
}
defer responseBody.Close()

return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.Out(), cli.Out().FD(), false, nil)
}

func runPull(dockerCli command.Cli, opts pullOptions, name string) error {
appstore, err := store.NewApplicationStore(config.Dir())
if err != nil {
return err
Expand All @@ -52,5 +91,15 @@ func runPull(dockerCli command.Cli, name string) error {
}
fmt.Fprintf(os.Stdout, "Successfully pulled %q (%s) from %s\n", bndl.Name, bndl.Version, ref.String())

if opts.serviceImages {
ctx := context.Background()
for name, image := range bndl.Images {
fmt.Fprintf(os.Stdout, "Pulling: %s -> %s\n", name, image.Image)
if err := pullImage(ctx, dockerCli, image.Image); err != nil {
return err
}
}
}

return nil
}

0 comments on commit 445fe77

Please sign in to comment.