github.com/canthefason/helm@v2.2.1-0.20170221172616-16b043b8d505+incompatible/cmd/helm/fetch.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     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  	"fmt"
    21  	"io"
    22  	"io/ioutil"
    23  	"os"
    24  	"path/filepath"
    25  
    26  	"github.com/spf13/cobra"
    27  	"k8s.io/helm/cmd/helm/helmpath"
    28  	"k8s.io/helm/pkg/chartutil"
    29  	"k8s.io/helm/pkg/downloader"
    30  )
    31  
    32  const fetchDesc = `
    33  Retrieve a package from a package repository, and download it locally.
    34  
    35  This is useful for fetching packages to inspect, modify, or repackage. It can
    36  also be used to perform cryptographic verification of a chart without installing
    37  the chart.
    38  
    39  There are options for unpacking the chart after download. This will create a
    40  directory for the chart and uncomparess into that directory.
    41  
    42  If the --verify flag is specified, the requested chart MUST have a provenance
    43  file, and MUST pass the verification process. Failure in any part of this will
    44  result in an error, and the chart will not be saved locally.
    45  `
    46  
    47  type fetchCmd struct {
    48  	untar    bool
    49  	untardir string
    50  	chartRef string
    51  	destdir  string
    52  	version  string
    53  
    54  	verify      bool
    55  	verifyLater bool
    56  	keyring     string
    57  
    58  	out io.Writer
    59  }
    60  
    61  func newFetchCmd(out io.Writer) *cobra.Command {
    62  	fch := &fetchCmd{out: out}
    63  
    64  	cmd := &cobra.Command{
    65  		Use:   "fetch [flags] [chart URL | repo/chartname] [...]",
    66  		Short: "download a chart from a repository and (optionally) unpack it in local directory",
    67  		Long:  fetchDesc,
    68  		RunE: func(cmd *cobra.Command, args []string) error {
    69  			if len(args) == 0 {
    70  				return fmt.Errorf("This command needs at least one argument, url or repo/name of the chart.")
    71  			}
    72  			for i := 0; i < len(args); i++ {
    73  				fch.chartRef = args[i]
    74  				if err := fch.run(); err != nil {
    75  					return err
    76  				}
    77  			}
    78  			return nil
    79  		},
    80  	}
    81  
    82  	f := cmd.Flags()
    83  	f.BoolVar(&fch.untar, "untar", false, "if set to true, will untar the chart after downloading it")
    84  	f.StringVar(&fch.untardir, "untardir", ".", "if untar is specified, this flag specifies the name of the directory into which the chart is expanded")
    85  	f.BoolVar(&fch.verify, "verify", false, "verify the package against its signature")
    86  	f.BoolVar(&fch.verifyLater, "prov", false, "fetch the provenance file, but don't perform verification")
    87  	f.StringVar(&fch.version, "version", "", "specific version of a chart. Without this, the latest version is fetched")
    88  	f.StringVar(&fch.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
    89  	f.StringVarP(&fch.destdir, "destination", "d", ".", "location to write the chart. If this and tardir are specified, tardir is appended to this")
    90  
    91  	return cmd
    92  }
    93  
    94  func (f *fetchCmd) run() error {
    95  	c := downloader.ChartDownloader{
    96  		HelmHome: helmpath.Home(homePath()),
    97  		Out:      f.out,
    98  		Keyring:  f.keyring,
    99  		Verify:   downloader.VerifyNever,
   100  	}
   101  
   102  	if f.verify {
   103  		c.Verify = downloader.VerifyAlways
   104  	} else if f.verifyLater {
   105  		c.Verify = downloader.VerifyLater
   106  	}
   107  
   108  	// If untar is set, we fetch to a tempdir, then untar and copy after
   109  	// verification.
   110  	dest := f.destdir
   111  	if f.untar {
   112  		var err error
   113  		dest, err = ioutil.TempDir("", "helm-")
   114  		if err != nil {
   115  			return fmt.Errorf("Failed to untar: %s", err)
   116  		}
   117  		defer os.RemoveAll(dest)
   118  	}
   119  
   120  	saved, v, err := c.DownloadTo(f.chartRef, f.version, dest)
   121  	if err != nil {
   122  		return err
   123  	}
   124  
   125  	if f.verify {
   126  		fmt.Fprintf(f.out, "Verification: %v\n", v)
   127  	}
   128  
   129  	// After verification, untar the chart into the requested directory.
   130  	if f.untar {
   131  		ud := f.untardir
   132  		if !filepath.IsAbs(ud) {
   133  			ud = filepath.Join(f.destdir, ud)
   134  		}
   135  		if fi, err := os.Stat(ud); err != nil {
   136  			if err := os.MkdirAll(ud, 0755); err != nil {
   137  				return fmt.Errorf("Failed to untar (mkdir): %s", err)
   138  			}
   139  
   140  		} else if !fi.IsDir() {
   141  			return fmt.Errorf("Failed to untar: %s is not a directory", ud)
   142  		}
   143  
   144  		return chartutil.ExpandFile(ud, saved)
   145  	}
   146  	return nil
   147  }
   148  
   149  // defaultKeyring returns the expanded path to the default keyring.
   150  func defaultKeyring() string {
   151  	return os.ExpandEnv("$HOME/.gnupg/pubring.gpg")
   152  }