github.com/coreos/rocket@v1.30.1-0.20200224141603-171c416fac02/rkt/fetch.go (about)

     1  // Copyright 2014 The rkt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"github.com/appc/spec/schema/types"
    19  	"github.com/rkt/rkt/common"
    20  	"github.com/rkt/rkt/common/apps"
    21  	"github.com/rkt/rkt/rkt/image"
    22  	"github.com/rkt/rkt/store/imagestore"
    23  	"github.com/rkt/rkt/store/treestore"
    24  
    25  	"github.com/spf13/cobra"
    26  )
    27  
    28  var (
    29  	defaultOS   = common.GetOS()
    30  	defaultArch = common.GetArch()
    31  	cmdFetch    = &cobra.Command{
    32  		Use:   "fetch IMAGE_URL...",
    33  		Short: "Fetch image(s) and store them in the local store",
    34  		Long: `Locates and downloads remote ACIs and their attached signatures.
    35  
    36  If the ACI is available in the local store, the image will not be fetched
    37  again.`,
    38  		Run: runWrapper(runFetch),
    39  	}
    40  	flagFullHash bool
    41  	// We can't have different defaults for a given flag variable shared across
    42  	// subcommands, so we can't use pullPolicyUpdate here
    43  	flagPullPolicyDefaultUpdate string
    44  )
    45  
    46  func init() {
    47  	// Disable interspersed flags to stop parsing after the first non flag
    48  	// argument. All the subsequent parsing will be done by parseApps.
    49  	// This is needed to correctly handle multiple IMAGE --signature=sigfile options
    50  	cmdFetch.Flags().SetInterspersed(false)
    51  
    52  	cmdFetch.Flags().Var((*appAsc)(&rktApps), "signature", "local signature file to use in validating the preceding image")
    53  	cmdFetch.Flags().BoolVar(&flagStoreOnly, "store-only", false, "use only available images in the store (do not discover or download from remote URLs)")
    54  	cmdFetch.Flags().MarkDeprecated("store-only", "please use --pull-policy=never")
    55  	cmdFetch.Flags().BoolVar(&flagNoStore, "no-store", false, "fetch images ignoring the local store")
    56  	cmdFetch.Flags().MarkDeprecated("no-store", "please use --pull-policy=update")
    57  	cmdFetch.Flags().BoolVar(&flagFullHash, "full", false, "print the full image hash after fetching")
    58  	cmdFetch.Flags().StringVar(&flagPullPolicyDefaultUpdate, "pull-policy", image.PullPolicyUpdate, "when to pull an image")
    59  
    60  	cmdRkt.AddCommand(cmdFetch)
    61  
    62  	// Hide image fetch option in command list
    63  	cmdImageFetch := *cmdFetch
    64  	cmdImageFetch.Hidden = true
    65  	cmdImage.AddCommand(&cmdImageFetch)
    66  }
    67  
    68  func runFetch(cmd *cobra.Command, args []string) (exit int) {
    69  	if err := parseApps(&rktApps, args, cmd.Flags(), false); err != nil {
    70  		stderr.PrintE("unable to parse arguments", err)
    71  		return 254
    72  	}
    73  
    74  	if rktApps.Count() < 1 {
    75  		stderr.Print("must provide at least one image")
    76  		return 254
    77  	}
    78  
    79  	// flagPullPolicy defaults to new regardless of subcommand, so we use a
    80  	// different variable for the flag on fetch and then set it here
    81  	flagPullPolicy = flagPullPolicyDefaultUpdate
    82  
    83  	if flagStoreOnly && flagNoStore {
    84  		stderr.Print("both --store-only and --no-store specified")
    85  		return 254
    86  	}
    87  	if flagStoreOnly {
    88  		flagPullPolicy = image.PullPolicyNever
    89  	}
    90  	if flagNoStore {
    91  		flagPullPolicy = image.PullPolicyUpdate
    92  	}
    93  
    94  	s, err := imagestore.NewStore(storeDir())
    95  	if err != nil {
    96  		stderr.PrintE("cannot open store", err)
    97  		return 254
    98  	}
    99  
   100  	ts, err := treestore.NewStore(treeStoreDir(), s)
   101  	if err != nil {
   102  		stderr.PrintE("cannot open treestore", err)
   103  		return 254
   104  	}
   105  
   106  	ks := getKeystore()
   107  	config, err := getConfig()
   108  	if err != nil {
   109  		stderr.PrintE("cannot get configuration", err)
   110  		return 254
   111  	}
   112  	ft := &image.Fetcher{
   113  		S:                  s,
   114  		Ts:                 ts,
   115  		Ks:                 ks,
   116  		Headers:            config.AuthPerHost,
   117  		DockerAuth:         config.DockerCredentialsPerRegistry,
   118  		InsecureFlags:      globalFlags.InsecureFlags,
   119  		Debug:              globalFlags.Debug,
   120  		TrustKeysFromHTTPS: globalFlags.TrustKeysFromHTTPS,
   121  
   122  		PullPolicy: flagPullPolicy,
   123  		WithDeps:   true,
   124  	}
   125  
   126  	err = ft.FetchImages(&rktApps)
   127  	if err != nil {
   128  		stderr.Error(err)
   129  		return 254
   130  	}
   131  	err = rktApps.Walk(func(app *apps.App) error {
   132  		hash := app.ImageID.String()
   133  		if !flagFullHash {
   134  			hash = types.ShortHash(hash)
   135  		}
   136  		stdout.Print(hash)
   137  		return nil
   138  	})
   139  	if err != nil {
   140  		stderr.Error(err)
   141  		return 254
   142  	}
   143  
   144  	return
   145  }