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  }