1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
package main
import (
"fmt"
"os"
"runtime"
"github.com/containers/buildah"
"github.com/containers/buildah/define"
buildahcli "github.com/containers/buildah/pkg/cli"
"github.com/containers/buildah/pkg/parse"
"github.com/containers/common/pkg/auth"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
type pullOptions struct {
allTags bool
authfile string
blobCache string
certDir string
creds string
signaturePolicy string
quiet bool
removeSignatures bool
tlsVerify bool
decryptionKeys []string
pullPolicy string
}
func init() {
var (
opts pullOptions
pullDescription = ` Pulls an image from a registry and stores it locally.
An image can be pulled using its tag or digest. If a tag is not
specified, the image with the 'latest' tag (if it exists) is pulled.`
)
pullCommand := &cobra.Command{
Use: "pull",
Short: "Pull an image from the specified location",
Long: pullDescription,
RunE: func(cmd *cobra.Command, args []string) error {
return pullCmd(cmd, args, opts)
},
Example: `buildah pull imagename
buildah pull docker-daemon:imagename:imagetag
buildah pull myregistry/myrepository/imagename:imagetag`,
}
pullCommand.SetUsageTemplate(UsageTemplate())
flags := pullCommand.Flags()
flags.SetInterspersed(false)
flags.BoolVarP(&opts.allTags, "all-tags", "a", false, "download all tagged images in the repository")
flags.StringVar(&opts.authfile, "authfile", auth.GetDefaultAuthFile(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
flags.StringVar(&opts.blobCache, "blob-cache", "", "store copies of pulled image blobs in the specified directory")
flags.StringVar(&opts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry")
flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
flags.StringVar(&opts.pullPolicy, "policy", "missing", "missing, always, or never.")
flags.BoolVarP(&opts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pulling image")
flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
flags.StringSliceVar(&opts.decryptionKeys, "decryption-key", nil, "key needed to decrypt the image")
if err := flags.MarkHidden("signature-policy"); err != nil {
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
}
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when pulling images")
flags.String("os", runtime.GOOS, "prefer `OS` instead of the running OS for choosing images")
flags.String("arch", runtime.GOARCH, "prefer `ARCH` instead of the architecture of the machine for choosing images")
flags.String("variant", "", "override the `variant` of the specified image")
flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.")
if err := flags.MarkHidden("blob-cache"); err != nil {
panic(fmt.Sprintf("error marking blob-cache as hidden: %v", err))
}
rootCmd.AddCommand(pullCommand)
}
func pullCmd(c *cobra.Command, args []string, iopts pullOptions) error {
if len(args) == 0 {
return errors.Errorf("an image name must be specified")
}
if err := buildahcli.VerifyFlagsArgsOrder(args); err != nil {
return err
}
if len(args) > 1 {
return errors.Errorf("too many arguments specified")
}
if err := auth.CheckAuthFile(iopts.authfile); err != nil {
return err
}
systemContext, err := parse.SystemContextFromOptions(c)
if err != nil {
return errors.Wrapf(err, "error building system context")
}
store, err := getStore(c)
if err != nil {
return err
}
decConfig, err := getDecryptConfig(iopts.decryptionKeys)
if err != nil {
return errors.Wrapf(err, "unable to obtain decrypt config")
}
policy, ok := define.PolicyMap[iopts.pullPolicy]
if !ok {
return fmt.Errorf("unrecognized pull policy %s", iopts.pullPolicy)
}
options := buildah.PullOptions{
SignaturePolicyPath: iopts.signaturePolicy,
Store: store,
SystemContext: systemContext,
BlobDirectory: iopts.blobCache,
AllTags: iopts.allTags,
ReportWriter: os.Stderr,
RemoveSignatures: iopts.removeSignatures,
MaxRetries: maxPullPushRetries,
RetryDelay: pullPushRetryDelay,
OciDecryptConfig: decConfig,
PullPolicy: policy,
}
if iopts.quiet {
options.ReportWriter = nil // Turns off logging output
}
id, err := buildah.Pull(getContext(), args[0], options)
if err != nil {
return err
}
fmt.Printf("%s\n", id)
return nil
}
|