github.com/vtuson/helm@v2.8.2+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/pkg/chartutil"
    28  	"k8s.io/helm/pkg/downloader"
    29  	"k8s.io/helm/pkg/getter"
    30  	"k8s.io/helm/pkg/repo"
    31  )
    32  
    33  const fetchDesc = `
    34  Retrieve a package from a package repository, and download it locally.
    35  
    36  This is useful for fetching packages to inspect, modify, or repackage. It can
    37  also be used to perform cryptographic verification of a chart without installing
    38  the chart.
    39  
    40  There are options for unpacking the chart after download. This will create a
    41  directory for the chart and uncompress into that directory.
    42  
    43  If the --verify flag is specified, the requested chart MUST have a provenance
    44  file, and MUST pass the verification process. Failure in any part of this will
    45  result in an error, and the chart will not be saved locally.
    46  `
    47  
    48  type fetchCmd struct {
    49  	untar    bool
    50  	untardir string
    51  	chartRef string
    52  	destdir  string
    53  	version  string
    54  	repoURL  string
    55  
    56  	verify      bool
    57  	verifyLater bool
    58  	keyring     string
    59  
    60  	certFile string
    61  	keyFile  string
    62  	caFile   string
    63  
    64  	devel bool
    65  
    66  	out io.Writer
    67  }
    68  
    69  func newFetchCmd(out io.Writer) *cobra.Command {
    70  	fch := &fetchCmd{out: out}
    71  
    72  	cmd := &cobra.Command{
    73  		Use:   "fetch [flags] [chart URL | repo/chartname] [...]",
    74  		Short: "download a chart from a repository and (optionally) unpack it in local directory",
    75  		Long:  fetchDesc,
    76  		RunE: func(cmd *cobra.Command, args []string) error {
    77  			if len(args) == 0 {
    78  				return fmt.Errorf("need at least one argument, url or repo/name of the chart")
    79  			}
    80  
    81  			if fch.version == "" && fch.devel {
    82  				debug("setting version to >0.0.0-0")
    83  				fch.version = ">0.0.0-0"
    84  			}
    85  
    86  			for i := 0; i < len(args); i++ {
    87  				fch.chartRef = args[i]
    88  				if err := fch.run(); err != nil {
    89  					return err
    90  				}
    91  			}
    92  			return nil
    93  		},
    94  	}
    95  
    96  	f := cmd.Flags()
    97  	f.BoolVar(&fch.untar, "untar", false, "if set to true, will untar the chart after downloading it")
    98  	f.StringVar(&fch.untardir, "untardir", ".", "if untar is specified, this flag specifies the name of the directory into which the chart is expanded")
    99  	f.BoolVar(&fch.verify, "verify", false, "verify the package against its signature")
   100  	f.BoolVar(&fch.verifyLater, "prov", false, "fetch the provenance file, but don't perform verification")
   101  	f.StringVar(&fch.version, "version", "", "specific version of a chart. Without this, the latest version is fetched")
   102  	f.StringVar(&fch.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
   103  	f.StringVarP(&fch.destdir, "destination", "d", ".", "location to write the chart. If this and tardir are specified, tardir is appended to this")
   104  	f.StringVar(&fch.repoURL, "repo", "", "chart repository url where to locate the requested chart")
   105  	f.StringVar(&fch.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
   106  	f.StringVar(&fch.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
   107  	f.StringVar(&fch.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
   108  	f.BoolVar(&fch.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
   109  
   110  	return cmd
   111  }
   112  
   113  func (f *fetchCmd) run() error {
   114  	c := downloader.ChartDownloader{
   115  		HelmHome: settings.Home,
   116  		Out:      f.out,
   117  		Keyring:  f.keyring,
   118  		Verify:   downloader.VerifyNever,
   119  		Getters:  getter.All(settings),
   120  	}
   121  
   122  	if f.verify {
   123  		c.Verify = downloader.VerifyAlways
   124  	} else if f.verifyLater {
   125  		c.Verify = downloader.VerifyLater
   126  	}
   127  
   128  	// If untar is set, we fetch to a tempdir, then untar and copy after
   129  	// verification.
   130  	dest := f.destdir
   131  	if f.untar {
   132  		var err error
   133  		dest, err = ioutil.TempDir("", "helm-")
   134  		if err != nil {
   135  			return fmt.Errorf("Failed to untar: %s", err)
   136  		}
   137  		defer os.RemoveAll(dest)
   138  	}
   139  
   140  	if f.repoURL != "" {
   141  		chartURL, err := repo.FindChartInRepoURL(f.repoURL, f.chartRef, f.version, f.certFile, f.keyFile, f.caFile, getter.All(settings))
   142  		if err != nil {
   143  			return err
   144  		}
   145  		f.chartRef = chartURL
   146  	}
   147  
   148  	saved, v, err := c.DownloadTo(f.chartRef, f.version, dest)
   149  	if err != nil {
   150  		return err
   151  	}
   152  
   153  	if f.verify {
   154  		fmt.Fprintf(f.out, "Verification: %v\n", v)
   155  	}
   156  
   157  	// After verification, untar the chart into the requested directory.
   158  	if f.untar {
   159  		ud := f.untardir
   160  		if !filepath.IsAbs(ud) {
   161  			ud = filepath.Join(f.destdir, ud)
   162  		}
   163  		if fi, err := os.Stat(ud); err != nil {
   164  			if err := os.MkdirAll(ud, 0755); err != nil {
   165  				return fmt.Errorf("Failed to untar (mkdir): %s", err)
   166  			}
   167  
   168  		} else if !fi.IsDir() {
   169  			return fmt.Errorf("Failed to untar: %s is not a directory", ud)
   170  		}
   171  
   172  		return chartutil.ExpandFile(ud, saved)
   173  	}
   174  	return nil
   175  }
   176  
   177  // defaultKeyring returns the expanded path to the default keyring.
   178  func defaultKeyring() string {
   179  	return os.ExpandEnv("$HOME/.gnupg/pubring.gpg")
   180  }