github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podmanV2/images/pull.go (about)

     1  package images
     2  
     3  import (
     4  	"fmt"
     5  
     6  	buildahcli "github.com/containers/buildah/pkg/cli"
     7  	"github.com/containers/image/v5/types"
     8  	"github.com/containers/libpod/cmd/podmanV2/registry"
     9  	"github.com/containers/libpod/pkg/domain/entities"
    10  	"github.com/opentracing/opentracing-go"
    11  	"github.com/pkg/errors"
    12  	"github.com/spf13/cobra"
    13  	"github.com/spf13/pflag"
    14  )
    15  
    16  // pullOptionsWrapper wraps entities.ImagePullOptions and prevents leaking
    17  // CLI-only fields into the API types.
    18  type pullOptionsWrapper struct {
    19  	entities.ImagePullOptions
    20  	TLSVerifyCLI bool // CLI only
    21  }
    22  
    23  var (
    24  	pullOptions     = pullOptionsWrapper{}
    25  	pullDescription = `Pulls an image from a registry and stores it locally.
    26  
    27    An image can be pulled by tag or digest. If a tag is not specified, the image with the 'latest' tag is pulled.`
    28  
    29  	// Command: podman pull
    30  	pullCmd = &cobra.Command{
    31  		Use:     "pull [flags] IMAGE",
    32  		Short:   "Pull an image from a registry",
    33  		Long:    pullDescription,
    34  		PreRunE: preRunE,
    35  		RunE:    imagePull,
    36  		Example: `podman pull imageName
    37    podman pull fedora:latest`,
    38  	}
    39  
    40  	// Command: podman image pull
    41  	// It's basically a clone of `pullCmd` with the exception of being a
    42  	// child of the images command.
    43  	imagesPullCmd = &cobra.Command{
    44  		Use:     pullCmd.Use,
    45  		Short:   pullCmd.Short,
    46  		Long:    pullCmd.Long,
    47  		PreRunE: pullCmd.PreRunE,
    48  		RunE:    pullCmd.RunE,
    49  		Example: `podman image pull imageName
    50    podman image pull fedora:latest`,
    51  	}
    52  )
    53  
    54  func init() {
    55  	// pull
    56  	registry.Commands = append(registry.Commands, registry.CliCommand{
    57  		Mode:    []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
    58  		Command: pullCmd,
    59  	})
    60  
    61  	pullCmd.SetHelpTemplate(registry.HelpTemplate())
    62  	pullCmd.SetUsageTemplate(registry.UsageTemplate())
    63  
    64  	flags := pullCmd.Flags()
    65  	pullFlags(flags)
    66  
    67  	// images pull
    68  	registry.Commands = append(registry.Commands, registry.CliCommand{
    69  		Mode:    []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
    70  		Command: imagesPullCmd,
    71  		Parent:  imageCmd,
    72  	})
    73  
    74  	imagesPullCmd.SetHelpTemplate(registry.HelpTemplate())
    75  	imagesPullCmd.SetUsageTemplate(registry.UsageTemplate())
    76  	imagesPullFlags := imagesPullCmd.Flags()
    77  	pullFlags(imagesPullFlags)
    78  }
    79  
    80  // pullFlags set the flags for the pull command.
    81  func pullFlags(flags *pflag.FlagSet) {
    82  	flags.BoolVar(&pullOptions.AllTags, "all-tags", false, "All tagged images in the repository will be pulled")
    83  	flags.StringVar(&pullOptions.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
    84  	flags.StringVar(&pullOptions.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys")
    85  	flags.StringVar(&pullOptions.Credentials, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
    86  	flags.StringVar(&pullOptions.OverrideArch, "override-arch", "", "Use `ARCH` instead of the architecture of the machine for choosing images")
    87  	flags.StringVar(&pullOptions.OverrideOS, "override-os", "", "Use `OS` instead of the running OS for choosing images")
    88  	flags.BoolVarP(&pullOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images")
    89  	flags.StringVar(&pullOptions.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)")
    90  	flags.BoolVar(&pullOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries")
    91  
    92  	if registry.IsRemote() {
    93  		_ = flags.MarkHidden("authfile")
    94  		_ = flags.MarkHidden("cert-dir")
    95  		_ = flags.MarkHidden("signature-policy")
    96  		_ = flags.MarkHidden("tls-verify")
    97  	}
    98  }
    99  
   100  // imagePull is implement the command for pulling images.
   101  func imagePull(cmd *cobra.Command, args []string) error {
   102  	// Sanity check input.
   103  	if len(args) == 0 {
   104  		return errors.Errorf("an image name must be specified")
   105  	}
   106  	if len(args) > 1 {
   107  		return errors.Errorf("too many arguments. Requires exactly 1")
   108  	}
   109  
   110  	// Start tracing if requested.
   111  	if cmd.Flags().Changed("trace") {
   112  		span, _ := opentracing.StartSpanFromContext(registry.GetContext(), "pullCmd")
   113  		defer span.Finish()
   114  	}
   115  
   116  	pullOptsAPI := pullOptions.ImagePullOptions
   117  	// TLS verification in c/image is controlled via a `types.OptionalBool`
   118  	// which allows for distinguishing among set-true, set-false, unspecified
   119  	// which is important to implement a sane way of dealing with defaults of
   120  	// boolean CLI flags.
   121  	if cmd.Flags().Changed("tls-verify") {
   122  		pullOptsAPI.TLSVerify = types.NewOptionalBool(pullOptions.TLSVerifyCLI)
   123  	}
   124  
   125  	// Let's do all the remaining Yoga in the API to prevent us from
   126  	// scattering logic across (too) many parts of the code.
   127  	pullReport, err := registry.ImageEngine().Pull(registry.GetContext(), args[0], pullOptsAPI)
   128  	if err != nil {
   129  		return err
   130  	}
   131  
   132  	if len(pullReport.Images) > 1 {
   133  		fmt.Println("Pulled Images:")
   134  	}
   135  	for _, img := range pullReport.Images {
   136  		fmt.Println(img)
   137  	}
   138  
   139  	return nil
   140  }