github.com/xeptore/docker-cli@v20.10.14+incompatible/cli/command/image/push.go (about) 1 package image 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 8 "github.com/docker/cli/cli" 9 "github.com/docker/cli/cli/command" 10 "github.com/docker/cli/cli/streams" 11 "github.com/docker/distribution/reference" 12 "github.com/docker/docker/api/types" 13 "github.com/docker/docker/pkg/jsonmessage" 14 "github.com/docker/docker/registry" 15 "github.com/pkg/errors" 16 "github.com/spf13/cobra" 17 ) 18 19 type pushOptions struct { 20 all bool 21 remote string 22 untrusted bool 23 quiet bool 24 } 25 26 // NewPushCommand creates a new `docker push` command 27 func NewPushCommand(dockerCli command.Cli) *cobra.Command { 28 var opts pushOptions 29 30 cmd := &cobra.Command{ 31 Use: "push [OPTIONS] NAME[:TAG]", 32 Short: "Push an image or a repository to a registry", 33 Args: cli.ExactArgs(1), 34 RunE: func(cmd *cobra.Command, args []string) error { 35 opts.remote = args[0] 36 return RunPush(dockerCli, opts) 37 }, 38 } 39 40 flags := cmd.Flags() 41 flags.BoolVarP(&opts.all, "all-tags", "a", false, "Push all tagged images in the repository") 42 flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress verbose output") 43 command.AddTrustSigningFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled()) 44 45 return cmd 46 } 47 48 // RunPush performs a push against the engine based on the specified options 49 func RunPush(dockerCli command.Cli, opts pushOptions) error { 50 ref, err := reference.ParseNormalizedNamed(opts.remote) 51 switch { 52 case err != nil: 53 return err 54 case opts.all && !reference.IsNameOnly(ref): 55 return errors.New("tag can't be used with --all-tags/-a") 56 case !opts.all && reference.IsNameOnly(ref): 57 ref = reference.TagNameOnly(ref) 58 if tagged, ok := ref.(reference.Tagged); ok && !opts.quiet { 59 _, _ = fmt.Fprintf(dockerCli.Out(), "Using default tag: %s\n", tagged.Tag()) 60 } 61 } 62 63 // Resolve the Repository name from fqn to RepositoryInfo 64 repoInfo, err := registry.ParseRepositoryInfo(ref) 65 if err != nil { 66 return err 67 } 68 69 ctx := context.Background() 70 71 // Resolve the Auth config relevant for this server 72 authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index) 73 encodedAuth, err := command.EncodeAuthToBase64(authConfig) 74 if err != nil { 75 return err 76 } 77 requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "push") 78 options := types.ImagePushOptions{ 79 All: opts.all, 80 RegistryAuth: encodedAuth, 81 PrivilegeFunc: requestPrivilege, 82 } 83 84 responseBody, err := dockerCli.Client().ImagePush(ctx, reference.FamiliarString(ref), options) 85 if err != nil { 86 return err 87 } 88 89 defer responseBody.Close() 90 if !opts.untrusted { 91 // TODO PushTrustedReference currently doesn't respect `--quiet` 92 return PushTrustedReference(dockerCli, repoInfo, ref, authConfig, responseBody) 93 } 94 95 if opts.quiet { 96 err = jsonmessage.DisplayJSONMessagesToStream(responseBody, streams.NewOut(ioutil.Discard), nil) 97 if err == nil { 98 fmt.Fprintln(dockerCli.Out(), ref.String()) 99 } 100 return err 101 } 102 return jsonmessage.DisplayJSONMessagesToStream(responseBody, dockerCli.Out(), nil) 103 }