github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/image_push.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "github.com/containerd/nerdctl/pkg/api/types" 21 "github.com/containerd/nerdctl/pkg/clientutil" 22 "github.com/containerd/nerdctl/pkg/cmd/image" 23 "github.com/spf13/cobra" 24 ) 25 26 const ( 27 allowNonDistFlag = "allow-nondistributable-artifacts" 28 ) 29 30 func newPushCommand() *cobra.Command { 31 var pushCommand = &cobra.Command{ 32 Use: "push [flags] NAME[:TAG]", 33 Short: "Push an image or a repository to a registry. Optionally specify \"ipfs://\" or \"ipns://\" scheme to push image to IPFS.", 34 Args: IsExactArgs(1), 35 RunE: pushAction, 36 ValidArgsFunction: pushShellComplete, 37 SilenceUsage: true, 38 SilenceErrors: true, 39 } 40 // #region platform flags 41 // platform is defined as StringSlice, not StringArray, to allow specifying "--platform=amd64,arm64" 42 pushCommand.Flags().StringSlice("platform", []string{}, "Push content for a specific platform") 43 pushCommand.RegisterFlagCompletionFunc("platform", shellCompletePlatforms) 44 pushCommand.Flags().Bool("all-platforms", false, "Push content for all platforms") 45 // #endregion 46 47 pushCommand.Flags().Bool("estargz", false, "Convert the image into eStargz") 48 pushCommand.Flags().Bool("ipfs-ensure-image", true, "Ensure the entire contents of the image is locally available before push") 49 pushCommand.Flags().String("ipfs-address", "", "multiaddr of IPFS API (default uses $IPFS_PATH env variable if defined or local directory ~/.ipfs)") 50 51 // #region sign flags 52 pushCommand.Flags().String("sign", "none", "Sign the image (none|cosign|notation") 53 pushCommand.RegisterFlagCompletionFunc("sign", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 54 return []string{"none", "cosign", "notation"}, cobra.ShellCompDirectiveNoFileComp 55 }) 56 pushCommand.Flags().String("cosign-key", "", "Path to the private key file, KMS URI or Kubernetes Secret for --sign=cosign") 57 pushCommand.Flags().String("notation-key-name", "", "Signing key name for a key previously added to notation's key list for --sign=notation") 58 // #endregion 59 60 // #region soci flags 61 pushCommand.Flags().Int64("soci-span-size", -1, "Span size that soci index uses to segment layer data. Default is 4 MiB.") 62 pushCommand.Flags().Int64("soci-min-layer-size", -1, "Minimum layer size to build zTOC for. Smaller layers won't have zTOC and not lazy pulled. Default is 10 MiB.") 63 // #endregion 64 65 pushCommand.Flags().BoolP("quiet", "q", false, "Suppress verbose output") 66 67 pushCommand.Flags().Bool(allowNonDistFlag, false, "Allow pushing images with non-distributable blobs") 68 69 return pushCommand 70 } 71 72 func processImagePushOptions(cmd *cobra.Command) (types.ImagePushOptions, error) { 73 globalOptions, err := processRootCmdFlags(cmd) 74 if err != nil { 75 return types.ImagePushOptions{}, err 76 } 77 platform, err := cmd.Flags().GetStringSlice("platform") 78 if err != nil { 79 return types.ImagePushOptions{}, err 80 } 81 allPlatforms, err := cmd.Flags().GetBool("all-platforms") 82 if err != nil { 83 return types.ImagePushOptions{}, err 84 } 85 estargz, err := cmd.Flags().GetBool("estargz") 86 if err != nil { 87 return types.ImagePushOptions{}, err 88 } 89 ipfsEnsureImage, err := cmd.Flags().GetBool("ipfs-ensure-image") 90 if err != nil { 91 return types.ImagePushOptions{}, err 92 } 93 ipfsAddress, err := cmd.Flags().GetString("ipfs-address") 94 if err != nil { 95 return types.ImagePushOptions{}, err 96 } 97 quiet, err := cmd.Flags().GetBool("quiet") 98 if err != nil { 99 return types.ImagePushOptions{}, err 100 } 101 allowNonDist, err := cmd.Flags().GetBool(allowNonDistFlag) 102 if err != nil { 103 return types.ImagePushOptions{}, err 104 } 105 signOptions, err := processImageSignOptions(cmd) 106 if err != nil { 107 return types.ImagePushOptions{}, err 108 } 109 sociOptions, err := processSociOptions(cmd) 110 if err != nil { 111 return types.ImagePushOptions{}, err 112 } 113 return types.ImagePushOptions{ 114 GOptions: globalOptions, 115 SignOptions: signOptions, 116 SociOptions: sociOptions, 117 Platforms: platform, 118 AllPlatforms: allPlatforms, 119 Estargz: estargz, 120 IpfsEnsureImage: ipfsEnsureImage, 121 IpfsAddress: ipfsAddress, 122 Quiet: quiet, 123 AllowNondistributableArtifacts: allowNonDist, 124 Stdout: cmd.OutOrStdout(), 125 }, nil 126 } 127 128 func pushAction(cmd *cobra.Command, args []string) error { 129 options, err := processImagePushOptions(cmd) 130 if err != nil { 131 return err 132 } 133 rawRef := args[0] 134 135 client, ctx, cancel, err := clientutil.NewClient(cmd.Context(), options.GOptions.Namespace, options.GOptions.Address) 136 if err != nil { 137 return err 138 } 139 defer cancel() 140 141 return image.Push(ctx, client, rawRef, options) 142 } 143 144 func pushShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 145 // show image names 146 return shellCompleteImageNames(cmd) 147 }