From 28e4f2b97c7478254145b222b2124669e36c4b6d Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 10 Jun 2016 12:07:23 +0200 Subject: [PATCH 1/3] Migrate pull command to cobra Signed-off-by: Vincent Demeester Upstream-commit: fa67b984f8ec1aa7b8292777210f4643d4bc1bf0 Component: engine --- components/engine/api/client/commands.go | 1 - components/engine/api/client/image/pull.go | 86 +++++++++++++++++++ components/engine/api/client/pull.go | 64 +------------- components/engine/api/client/trust.go | 7 +- components/engine/cli/cobraadaptor/adaptor.go | 1 + components/engine/cli/usage.go | 1 - 6 files changed, 93 insertions(+), 67 deletions(-) create mode 100644 components/engine/api/client/image/pull.go diff --git a/components/engine/api/client/commands.go b/components/engine/api/client/commands.go index b843106a72..d6f5aebdac 100644 --- a/components/engine/api/client/commands.go +++ b/components/engine/api/client/commands.go @@ -11,7 +11,6 @@ func (cli *DockerCli) Command(name string) func(...string) error { "login": cli.CmdLogin, "logout": cli.CmdLogout, "ps": cli.CmdPs, - "pull": cli.CmdPull, "push": cli.CmdPush, "update": cli.CmdUpdate, }[name] diff --git a/components/engine/api/client/image/pull.go b/components/engine/api/client/image/pull.go new file mode 100644 index 0000000000..24d91e4a63 --- /dev/null +++ b/components/engine/api/client/image/pull.go @@ -0,0 +1,86 @@ +package image + +import ( + "errors" + "fmt" + + "golang.org/x/net/context" + + "github.com/docker/docker/api/client" + "github.com/docker/docker/cli" + "github.com/docker/docker/reference" + "github.com/docker/docker/registry" + "github.com/spf13/cobra" +) + +type pullOptions struct { + remote string + all bool +} + +// NewPullCommand creates a new `docker pull` command +func NewPullCommand(dockerCli *client.DockerCli) *cobra.Command { + var opts pullOptions + + cmd := &cobra.Command{ + Use: "pull [OPTIONS] NAME[:TAG|@DIGEST]", + Short: "Pull an image or a repository from a registry", + Args: cli.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + opts.remote = args[0] + return runPull(dockerCli, opts) + }, + } + + flags := cmd.Flags() + + flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository") + client.AddTrustedFlags(flags, true) + + return cmd +} + +func runPull(dockerCli *client.DockerCli, opts pullOptions) error { + + distributionRef, err := reference.ParseNamed(opts.remote) + if err != nil { + return err + } + if opts.all && !reference.IsNameOnly(distributionRef) { + return errors.New("tag can't be used with --all-tags/-a") + } + + if !opts.all && reference.IsNameOnly(distributionRef) { + distributionRef = reference.WithDefaultTag(distributionRef) + fmt.Fprintf(dockerCli.Out(), "Using default tag: %s\n", reference.DefaultTag) + } + + var tag string + switch x := distributionRef.(type) { + case reference.Canonical: + tag = x.Digest().String() + case reference.NamedTagged: + tag = x.Tag() + } + + registryRef := registry.ParseReference(tag) + + // Resolve the Repository name from fqn to RepositoryInfo + repoInfo, err := registry.ParseRepositoryInfo(distributionRef) + if err != nil { + return err + } + + ctx := context.Background() + + authConfig := dockerCli.ResolveAuthConfig(ctx, repoInfo.Index) + requestPrivilege := dockerCli.RegistryAuthenticationPrivilegedFunc(repoInfo.Index, "pull") + + if client.IsTrusted() && !registryRef.HasDigest() { + // Check if tag is digest + return dockerCli.TrustedPull(ctx, repoInfo, registryRef, authConfig, requestPrivilege) + } + + return dockerCli.ImagePullPrivileged(ctx, authConfig, distributionRef.String(), requestPrivilege, opts.all) + +} diff --git a/components/engine/api/client/pull.go b/components/engine/api/client/pull.go index 364e513de1..c0cef6f009 100644 --- a/components/engine/api/client/pull.go +++ b/components/engine/api/client/pull.go @@ -1,74 +1,14 @@ package client import ( - "errors" - "fmt" - "golang.org/x/net/context" - Cli "github.com/docker/docker/cli" "github.com/docker/docker/pkg/jsonmessage" - flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/reference" - "github.com/docker/docker/registry" "github.com/docker/engine-api/types" ) -// CmdPull pulls an image or a repository from the registry. -// -// Usage: docker pull [OPTIONS] IMAGENAME[:TAG|@DIGEST] -func (cli *DockerCli) CmdPull(args ...string) error { - cmd := Cli.Subcmd("pull", []string{"NAME[:TAG|@DIGEST]"}, Cli.DockerCommands["pull"].Description, true) - allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository") - addTrustedFlags(cmd, true) - cmd.Require(flag.Exact, 1) - - cmd.ParseFlags(args, true) - remote := cmd.Arg(0) - - distributionRef, err := reference.ParseNamed(remote) - if err != nil { - return err - } - if *allTags && !reference.IsNameOnly(distributionRef) { - return errors.New("tag can't be used with --all-tags/-a") - } - - if !*allTags && reference.IsNameOnly(distributionRef) { - distributionRef = reference.WithDefaultTag(distributionRef) - fmt.Fprintf(cli.out, "Using default tag: %s\n", reference.DefaultTag) - } - - var tag string - switch x := distributionRef.(type) { - case reference.Canonical: - tag = x.Digest().String() - case reference.NamedTagged: - tag = x.Tag() - } - - registryRef := registry.ParseReference(tag) - - // Resolve the Repository name from fqn to RepositoryInfo - repoInfo, err := registry.ParseRepositoryInfo(distributionRef) - if err != nil { - return err - } - - ctx := context.Background() - - authConfig := cli.ResolveAuthConfig(ctx, repoInfo.Index) - requestPrivilege := cli.RegistryAuthenticationPrivilegedFunc(repoInfo.Index, "pull") - - if IsTrusted() && !registryRef.HasDigest() { - // Check if tag is digest - return cli.trustedPull(ctx, repoInfo, registryRef, authConfig, requestPrivilege) - } - - return cli.imagePullPrivileged(ctx, authConfig, distributionRef.String(), requestPrivilege, *allTags) -} - -func (cli *DockerCli) imagePullPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc, all bool) error { +// ImagePullPrivileged pulls the image and displays it to the output +func (cli *DockerCli) ImagePullPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc, all bool) error { encodedAuth, err := EncodeAuthToBase64(authConfig) if err != nil { diff --git a/components/engine/api/client/trust.go b/components/engine/api/client/trust.go index d2c3479f56..6c72099a9e 100644 --- a/components/engine/api/client/trust.go +++ b/components/engine/api/client/trust.go @@ -51,7 +51,7 @@ func addTrustedFlags(fs *flag.FlagSet, verify bool) { fs.BoolVar(&untrusted, []string{"-disable-content-trust"}, !trusted, message) } -// AddTrustedFlags adds the trust flags to a FlagSet +// AddTrustedFlags adds content trust flags to the current command flagset func AddTrustedFlags(fs *pflag.FlagSet, verify bool) { trusted, message := setupTrustedFlag(verify) fs.BoolVar(&untrusted, "disable-content-trust", !trusted, message) @@ -314,7 +314,8 @@ func notaryError(repoName string, err error) error { return err } -func (cli *DockerCli) trustedPull(ctx context.Context, repoInfo *registry.RepositoryInfo, ref registry.Reference, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error { +// TrustedPull handles content trust pulling of an image +func (cli *DockerCli) TrustedPull(ctx context.Context, repoInfo *registry.RepositoryInfo, ref registry.Reference, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error { var refs []target notaryRepo, err := cli.getNotaryRepository(repoInfo, authConfig, "pull") @@ -376,7 +377,7 @@ func (cli *DockerCli) trustedPull(ctx context.Context, repoInfo *registry.Reposi if err != nil { return err } - if err := cli.imagePullPrivileged(ctx, authConfig, ref.String(), requestPrivilege, false); err != nil { + if err := cli.ImagePullPrivileged(ctx, authConfig, ref.String(), requestPrivilege, false); err != nil { return err } diff --git a/components/engine/cli/cobraadaptor/adaptor.go b/components/engine/cli/cobraadaptor/adaptor.go index a9bdd1a170..2f3d14821e 100644 --- a/components/engine/cli/cobraadaptor/adaptor.go +++ b/components/engine/cli/cobraadaptor/adaptor.go @@ -59,6 +59,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { image.NewLoadCommand(dockerCli), image.NewRemoveCommand(dockerCli), image.NewSaveCommand(dockerCli), + image.NewPullCommand(dockerCli), image.NewSearchCommand(dockerCli), image.NewImportCommand(dockerCli), image.NewTagCommand(dockerCli), diff --git a/components/engine/cli/usage.go b/components/engine/cli/usage.go index 20eae80f74..c063dd0da6 100644 --- a/components/engine/cli/usage.go +++ b/components/engine/cli/usage.go @@ -16,7 +16,6 @@ var DockerCommandUsage = []Command{ {"login", "Log in to a Docker registry"}, {"logout", "Log out from a Docker registry"}, {"ps", "List containers"}, - {"pull", "Pull an image or a repository from a registry"}, {"push", "Push an image or a repository to a registry"}, {"update", "Update configuration of one or more containers"}, } From 5c061ea6ccc18bb5d34ace706582bc35d319dc5d Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 10 Jun 2016 12:07:28 +0200 Subject: [PATCH 2/3] Migrate push command to cobra Signed-off-by: Vincent Demeester Upstream-commit: 9640e3a4514f96a890310757a09fd77a3c70e931 Component: engine --- components/engine/api/client/image/push.go | 63 +++++++++++++++++++ components/engine/api/client/push.go | 49 +-------------- components/engine/api/client/trust.go | 5 +- components/engine/cli/cobraadaptor/adaptor.go | 1 + 4 files changed, 69 insertions(+), 49 deletions(-) create mode 100644 components/engine/api/client/image/push.go diff --git a/components/engine/api/client/image/push.go b/components/engine/api/client/image/push.go new file mode 100644 index 0000000000..54527a0fb9 --- /dev/null +++ b/components/engine/api/client/image/push.go @@ -0,0 +1,63 @@ +package image + +import ( + "golang.org/x/net/context" + + "github.com/docker/docker/api/client" + "github.com/docker/docker/cli" + "github.com/docker/docker/pkg/jsonmessage" + "github.com/docker/docker/reference" + "github.com/docker/docker/registry" + "github.com/spf13/cobra" +) + +// NewPushCommand creates a new `docker push` command +func NewPushCommand(dockerCli *client.DockerCli) *cobra.Command { + cmd := &cobra.Command{ + Use: "push NAME[:TAG]", + Short: "Push an image or a repository to a registry", + Args: cli.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + return runPush(dockerCli, args[0]) + }, + } + + flags := cmd.Flags() + + client.AddTrustedFlags(flags, true) + + return cmd +} + +func runPush(dockerCli *client.DockerCli, remote string) error { + + ref, err := reference.ParseNamed(remote) + if err != nil { + return err + } + + // Resolve the Repository name from fqn to RepositoryInfo + repoInfo, err := registry.ParseRepositoryInfo(ref) + if err != nil { + return err + } + + ctx := context.Background() + + // Resolve the Auth config relevant for this server + authConfig := dockerCli.ResolveAuthConfig(ctx, repoInfo.Index) + requestPrivilege := dockerCli.RegistryAuthenticationPrivilegedFunc(repoInfo.Index, "push") + + if client.IsTrusted() { + return dockerCli.TrustedPush(ctx, repoInfo, ref, authConfig, requestPrivilege) + } + + responseBody, err := dockerCli.ImagePushPrivileged(ctx, authConfig, ref.String(), requestPrivilege) + if err != nil { + return err + } + + defer responseBody.Close() + + return jsonmessage.DisplayJSONMessagesStream(responseBody, dockerCli.Out(), dockerCli.OutFd(), dockerCli.IsTerminalOut(), nil) +} diff --git a/components/engine/api/client/push.go b/components/engine/api/client/push.go index 7b2f42bc4f..5c1e40124f 100644 --- a/components/engine/api/client/push.go +++ b/components/engine/api/client/push.go @@ -5,56 +5,11 @@ import ( "golang.org/x/net/context" - Cli "github.com/docker/docker/cli" - "github.com/docker/docker/pkg/jsonmessage" - flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/reference" - "github.com/docker/docker/registry" "github.com/docker/engine-api/types" ) -// CmdPush pushes an image or repository to the registry. -// -// Usage: docker push NAME[:TAG] -func (cli *DockerCli) CmdPush(args ...string) error { - cmd := Cli.Subcmd("push", []string{"NAME[:TAG]"}, Cli.DockerCommands["push"].Description, true) - addTrustedFlags(cmd, false) - cmd.Require(flag.Exact, 1) - - cmd.ParseFlags(args, true) - - ref, err := reference.ParseNamed(cmd.Arg(0)) - if err != nil { - return err - } - - // Resolve the Repository name from fqn to RepositoryInfo - repoInfo, err := registry.ParseRepositoryInfo(ref) - if err != nil { - return err - } - - ctx := context.Background() - - // Resolve the Auth config relevant for this server - authConfig := cli.ResolveAuthConfig(ctx, repoInfo.Index) - requestPrivilege := cli.RegistryAuthenticationPrivilegedFunc(repoInfo.Index, "push") - - if IsTrusted() { - return cli.trustedPush(ctx, repoInfo, ref, authConfig, requestPrivilege) - } - - responseBody, err := cli.imagePushPrivileged(ctx, authConfig, ref.String(), requestPrivilege) - if err != nil { - return err - } - - defer responseBody.Close() - - return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) -} - -func (cli *DockerCli) imagePushPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) (io.ReadCloser, error) { +// ImagePushPrivileged push the image +func (cli *DockerCli) ImagePushPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) (io.ReadCloser, error) { encodedAuth, err := EncodeAuthToBase64(authConfig) if err != nil { return nil, err diff --git a/components/engine/api/client/trust.go b/components/engine/api/client/trust.go index 6c72099a9e..3311b4a078 100644 --- a/components/engine/api/client/trust.go +++ b/components/engine/api/client/trust.go @@ -399,8 +399,9 @@ func (cli *DockerCli) TrustedPull(ctx context.Context, repoInfo *registry.Reposi return nil } -func (cli *DockerCli) trustedPush(ctx context.Context, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error { - responseBody, err := cli.imagePushPrivileged(ctx, authConfig, ref.String(), requestPrivilege) +// TrustedPush handles content trust pushing of an image +func (cli *DockerCli) TrustedPush(ctx context.Context, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error { + responseBody, err := cli.ImagePushPrivileged(ctx, authConfig, ref.String(), requestPrivilege) if err != nil { return err } diff --git a/components/engine/cli/cobraadaptor/adaptor.go b/components/engine/cli/cobraadaptor/adaptor.go index 2f3d14821e..ec0c6d39c0 100644 --- a/components/engine/cli/cobraadaptor/adaptor.go +++ b/components/engine/cli/cobraadaptor/adaptor.go @@ -60,6 +60,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { image.NewRemoveCommand(dockerCli), image.NewSaveCommand(dockerCli), image.NewPullCommand(dockerCli), + image.NewPushCommand(dockerCli), image.NewSearchCommand(dockerCli), image.NewImportCommand(dockerCli), image.NewTagCommand(dockerCli), From 1397f0c340e2a63fb29b0733b619b21519f064dd Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 10 Jun 2016 12:07:32 +0200 Subject: [PATCH 3/3] Moving Image{Push,Pull}Privileged to trust.go Signed-off-by: Vincent Demeester Upstream-commit: ad4e20cd92079ec59b175b8a687ddadfa00037eb Component: engine --- components/engine/api/client/commands.go | 1 - components/engine/api/client/image/pull.go | 1 - components/engine/api/client/image/push.go | 1 - components/engine/api/client/pull.go | 30 ------------------ components/engine/api/client/push.go | 23 -------------- components/engine/api/client/trust.go | 37 ++++++++++++++++++++++ components/engine/cli/usage.go | 1 - 7 files changed, 37 insertions(+), 57 deletions(-) delete mode 100644 components/engine/api/client/pull.go delete mode 100644 components/engine/api/client/push.go diff --git a/components/engine/api/client/commands.go b/components/engine/api/client/commands.go index d6f5aebdac..6d6d9c8763 100644 --- a/components/engine/api/client/commands.go +++ b/components/engine/api/client/commands.go @@ -11,7 +11,6 @@ func (cli *DockerCli) Command(name string) func(...string) error { "login": cli.CmdLogin, "logout": cli.CmdLogout, "ps": cli.CmdPs, - "push": cli.CmdPush, "update": cli.CmdUpdate, }[name] } diff --git a/components/engine/api/client/image/pull.go b/components/engine/api/client/image/pull.go index 24d91e4a63..e5968db269 100644 --- a/components/engine/api/client/image/pull.go +++ b/components/engine/api/client/image/pull.go @@ -41,7 +41,6 @@ func NewPullCommand(dockerCli *client.DockerCli) *cobra.Command { } func runPull(dockerCli *client.DockerCli, opts pullOptions) error { - distributionRef, err := reference.ParseNamed(opts.remote) if err != nil { return err diff --git a/components/engine/api/client/image/push.go b/components/engine/api/client/image/push.go index 54527a0fb9..35d1645952 100644 --- a/components/engine/api/client/image/push.go +++ b/components/engine/api/client/image/push.go @@ -30,7 +30,6 @@ func NewPushCommand(dockerCli *client.DockerCli) *cobra.Command { } func runPush(dockerCli *client.DockerCli, remote string) error { - ref, err := reference.ParseNamed(remote) if err != nil { return err diff --git a/components/engine/api/client/pull.go b/components/engine/api/client/pull.go deleted file mode 100644 index c0cef6f009..0000000000 --- a/components/engine/api/client/pull.go +++ /dev/null @@ -1,30 +0,0 @@ -package client - -import ( - "golang.org/x/net/context" - - "github.com/docker/docker/pkg/jsonmessage" - "github.com/docker/engine-api/types" -) - -// ImagePullPrivileged pulls the image and displays it to the output -func (cli *DockerCli) ImagePullPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc, all bool) error { - - encodedAuth, err := EncodeAuthToBase64(authConfig) - if err != nil { - return err - } - options := types.ImagePullOptions{ - RegistryAuth: encodedAuth, - PrivilegeFunc: requestPrivilege, - All: all, - } - - responseBody, err := cli.client.ImagePull(ctx, ref, options) - if err != nil { - return err - } - defer responseBody.Close() - - return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) -} diff --git a/components/engine/api/client/push.go b/components/engine/api/client/push.go deleted file mode 100644 index 5c1e40124f..0000000000 --- a/components/engine/api/client/push.go +++ /dev/null @@ -1,23 +0,0 @@ -package client - -import ( - "io" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" -) - -// ImagePushPrivileged push the image -func (cli *DockerCli) ImagePushPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) (io.ReadCloser, error) { - encodedAuth, err := EncodeAuthToBase64(authConfig) - if err != nil { - return nil, err - } - options := types.ImagePushOptions{ - RegistryAuth: encodedAuth, - PrivilegeFunc: requestPrivilege, - } - - return cli.client.ImagePush(ctx, ref, options) -} diff --git a/components/engine/api/client/trust.go b/components/engine/api/client/trust.go index 3311b4a078..273b5e4c4a 100644 --- a/components/engine/api/client/trust.go +++ b/components/engine/api/client/trust.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "net" "net/http" "net/url" @@ -566,3 +567,39 @@ func (cli *DockerCli) addTargetToAllSignableRoles(repo *client.NotaryRepository, return repo.AddTarget(target, signableRoles...) } + +// ImagePullPrivileged pulls the image and displays it to the output +func (cli *DockerCli) ImagePullPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc, all bool) error { + + encodedAuth, err := EncodeAuthToBase64(authConfig) + if err != nil { + return err + } + options := types.ImagePullOptions{ + RegistryAuth: encodedAuth, + PrivilegeFunc: requestPrivilege, + All: all, + } + + responseBody, err := cli.client.ImagePull(ctx, ref, options) + if err != nil { + return err + } + defer responseBody.Close() + + return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) +} + +// ImagePushPrivileged push the image +func (cli *DockerCli) ImagePushPrivileged(ctx context.Context, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) (io.ReadCloser, error) { + encodedAuth, err := EncodeAuthToBase64(authConfig) + if err != nil { + return nil, err + } + options := types.ImagePushOptions{ + RegistryAuth: encodedAuth, + PrivilegeFunc: requestPrivilege, + } + + return cli.client.ImagePush(ctx, ref, options) +} diff --git a/components/engine/cli/usage.go b/components/engine/cli/usage.go index c063dd0da6..7ebbf2d12f 100644 --- a/components/engine/cli/usage.go +++ b/components/engine/cli/usage.go @@ -16,7 +16,6 @@ var DockerCommandUsage = []Command{ {"login", "Log in to a Docker registry"}, {"logout", "Log out from a Docker registry"}, {"ps", "List containers"}, - {"push", "Push an image or a repository to a registry"}, {"update", "Update configuration of one or more containers"}, }