diff options
author | Alexander Morozov <lk4d4math@gmail.com> | 2016-06-13 14:16:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-13 14:16:42 -0700 |
commit | f0193e278c31fb568c4cbbdc046e84a0d1a3390b (patch) | |
tree | 5e7e0e6bb5336904b9502de94053ca2ba62aad3c | |
parent | a502158d8a9b3a3949eb0bc0b087138ef65efabb (diff) | |
parent | ad4e20cd92079ec59b175b8a687ddadfa00037eb (diff) | |
download | docker-f0193e278c31fb568c4cbbdc046e84a0d1a3390b.tar.gz |
Merge pull request #23256 from vdemeester/migrate-pull-push-to-cobra
Use spf13/cobra for docker push and docker pull
-rw-r--r-- | api/client/commands.go | 2 | ||||
-rw-r--r-- | api/client/image/pull.go | 85 | ||||
-rw-r--r-- | api/client/image/push.go | 62 | ||||
-rw-r--r-- | api/client/pull.go | 90 | ||||
-rw-r--r-- | api/client/push.go | 68 | ||||
-rw-r--r-- | api/client/trust.go | 49 | ||||
-rw-r--r-- | cli/cobraadaptor/adaptor.go | 2 | ||||
-rw-r--r-- | cli/usage.go | 2 |
8 files changed, 193 insertions, 167 deletions
diff --git a/api/client/commands.go b/api/client/commands.go index e98813c334..b6ddd5c22e 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -8,8 +8,6 @@ func (cli *DockerCli) Command(name string) func(...string) error { "info": cli.CmdInfo, "inspect": cli.CmdInspect, "ps": cli.CmdPs, - "pull": cli.CmdPull, - "push": cli.CmdPush, "update": cli.CmdUpdate, }[name] } diff --git a/api/client/image/pull.go b/api/client/image/pull.go new file mode 100644 index 0000000000..e5968db269 --- /dev/null +++ b/api/client/image/pull.go @@ -0,0 +1,85 @@ +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/api/client/image/push.go b/api/client/image/push.go new file mode 100644 index 0000000000..35d1645952 --- /dev/null +++ b/api/client/image/push.go @@ -0,0 +1,62 @@ +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/api/client/pull.go b/api/client/pull.go deleted file mode 100644 index 364e513de1..0000000000 --- a/api/client/pull.go +++ /dev/null @@ -1,90 +0,0 @@ -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 { - - 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/api/client/push.go b/api/client/push.go deleted file mode 100644 index 7b2f42bc4f..0000000000 --- a/api/client/push.go +++ /dev/null @@ -1,68 +0,0 @@ -package client - -import ( - "io" - - "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) { - 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/api/client/trust.go b/api/client/trust.go index d2c3479f56..273b5e4c4a 100644 --- a/api/client/trust.go +++ b/api/client/trust.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "net" "net/http" "net/url" @@ -51,7 +52,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 +315,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 +378,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 } @@ -398,8 +400,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 } @@ -564,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/cli/cobraadaptor/adaptor.go b/cli/cobraadaptor/adaptor.go index 057acb5505..b1980491a8 100644 --- a/cli/cobraadaptor/adaptor.go +++ b/cli/cobraadaptor/adaptor.go @@ -61,6 +61,8 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { image.NewLoadCommand(dockerCli), image.NewRemoveCommand(dockerCli), image.NewSaveCommand(dockerCli), + image.NewPullCommand(dockerCli), + image.NewPushCommand(dockerCli), image.NewSearchCommand(dockerCli), image.NewImportCommand(dockerCli), image.NewTagCommand(dockerCli), diff --git a/cli/usage.go b/cli/usage.go index 4f46b4acf7..9cd7acd244 100644 --- a/cli/usage.go +++ b/cli/usage.go @@ -13,8 +13,6 @@ var DockerCommandUsage = []Command{ {"info", "Display system-wide information"}, {"inspect", "Return low-level information on a container or image"}, {"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"}, } |