github.com/pjbgf/helm@v3.0.0-beta.3+incompatible/cmd/helm/install.go (about)

     1  /*
     2  Copyright The Helm Authors.
     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  	"io"
    21  	"time"
    22  
    23  	"github.com/pkg/errors"
    24  	"github.com/spf13/cobra"
    25  	"github.com/spf13/pflag"
    26  
    27  	"helm.sh/helm/cmd/helm/require"
    28  	"helm.sh/helm/pkg/action"
    29  	"helm.sh/helm/pkg/chart"
    30  	"helm.sh/helm/pkg/chart/loader"
    31  	"helm.sh/helm/pkg/cli/values"
    32  	"helm.sh/helm/pkg/downloader"
    33  	"helm.sh/helm/pkg/getter"
    34  	"helm.sh/helm/pkg/release"
    35  )
    36  
    37  const installDesc = `
    38  This command installs a chart archive.
    39  
    40  The install argument must be a chart reference, a path to a packaged chart,
    41  a path to an unpacked chart directory or a URL.
    42  
    43  To override values in a chart, use either the '--values' flag and pass in a file
    44  or use the '--set' flag and pass configuration from the command line, to force
    45  a string value use '--set-string'.
    46  
    47  	$ helm install -f myvalues.yaml myredis ./redis
    48  
    49  or
    50  
    51  	$ helm install --set name=prod myredis ./redis
    52  
    53  or
    54  
    55  	$ helm install --set-string long_int=1234567890 myredis ./redis
    56  
    57  You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
    58  last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
    59  contained a key called 'Test', the value set in override.yaml would take precedence:
    60  
    61  	$ helm install -f myvalues.yaml -f override.yaml  myredis ./redis
    62  
    63  You can specify the '--set' flag multiple times. The priority will be given to the
    64  last (right-most) set specified. For example, if both 'bar' and 'newbar' values are
    65  set for a key called 'foo', the 'newbar' value would take precedence:
    66  
    67  	$ helm install --set foo=bar --set foo=newbar  myredis ./redis
    68  
    69  
    70  To check the generated manifests of a release without installing the chart,
    71  the '--debug' and '--dry-run' flags can be combined. This will still require a
    72  round-trip to the Tiller server.
    73  
    74  If --verify is set, the chart MUST have a provenance file, and the provenance
    75  file MUST pass all verification steps.
    76  
    77  There are five different ways you can express the chart you want to install:
    78  
    79  1. By chart reference: helm install example/mariadb
    80  2. By path to a packaged chart: helm install ./nginx-1.2.3.tgz
    81  3. By path to an unpacked chart directory: helm install ./nginx
    82  4. By absolute URL: helm install https://example.com/charts/nginx-1.2.3.tgz
    83  5. By chart reference and repo url: helm install --repo https://example.com/charts/ nginx
    84  
    85  CHART REFERENCES
    86  
    87  A chart reference is a convenient way of reference a chart in a chart repository.
    88  
    89  When you use a chart reference with a repo prefix ('example/mariadb'), Helm will look in the local
    90  configuration for a chart repository named 'example', and will then look for a
    91  chart in that repository whose name is 'mariadb'. It will install the latest
    92  version of that chart unless you also supply a version number with the
    93  '--version' flag.
    94  
    95  To see the list of chart repositories, use 'helm repo list'. To search for
    96  charts in a repository, use 'helm search'.
    97  `
    98  
    99  func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
   100  	client := action.NewInstall(cfg)
   101  	valueOpts := &values.Options{}
   102  
   103  	cmd := &cobra.Command{
   104  		Use:   "install [NAME] [CHART]",
   105  		Short: "install a chart",
   106  		Long:  installDesc,
   107  		Args:  require.MinimumNArgs(1),
   108  		RunE: func(_ *cobra.Command, args []string) error {
   109  			rel, err := runInstall(args, client, valueOpts, out)
   110  			if err != nil {
   111  				return err
   112  			}
   113  			action.PrintRelease(out, rel)
   114  			return nil
   115  		},
   116  	}
   117  
   118  	addInstallFlags(cmd.Flags(), client, valueOpts)
   119  
   120  	return cmd
   121  }
   122  
   123  func addInstallFlags(f *pflag.FlagSet, client *action.Install, valueOpts *values.Options) {
   124  	f.BoolVar(&client.DryRun, "dry-run", false, "simulate an install")
   125  	f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during install")
   126  	f.BoolVar(&client.Replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production")
   127  	f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)")
   128  	f.BoolVar(&client.Wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout")
   129  	f.BoolVarP(&client.GenerateName, "generate-name", "g", false, "generate the name (and omit the NAME parameter)")
   130  	f.StringVar(&client.NameTemplate, "name-template", "", "specify template used to name the release")
   131  	f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
   132  	f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "run helm dependency update before installing the chart")
   133  	f.BoolVar(&client.Atomic, "atomic", false, "if set, installation process purges chart on fail. The --wait flag will be set automatically if --atomic is used")
   134  	f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present.")
   135  	addValueOptionsFlags(f, valueOpts)
   136  	addChartPathOptionsFlags(f, &client.ChartPathOptions)
   137  }
   138  
   139  func addValueOptionsFlags(f *pflag.FlagSet, v *values.Options) {
   140  	f.StringSliceVarP(&v.ValueFiles, "values", "f", []string{}, "specify values in a YAML file or a URL(can specify multiple)")
   141  	f.StringArrayVar(&v.Values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
   142  	f.StringArrayVar(&v.StringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
   143  }
   144  
   145  func addChartPathOptionsFlags(f *pflag.FlagSet, c *action.ChartPathOptions) {
   146  	f.StringVar(&c.Version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed")
   147  	f.BoolVar(&c.Verify, "verify", false, "verify the package before installing it")
   148  	f.StringVar(&c.Keyring, "keyring", defaultKeyring(), "location of public keys used for verification")
   149  	f.StringVar(&c.RepoURL, "repo", "", "chart repository url where to locate the requested chart")
   150  	f.StringVar(&c.Username, "username", "", "chart repository username where to locate the requested chart")
   151  	f.StringVar(&c.Password, "password", "", "chart repository password where to locate the requested chart")
   152  	f.StringVar(&c.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
   153  	f.StringVar(&c.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file")
   154  	f.StringVar(&c.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
   155  }
   156  
   157  func runInstall(args []string, client *action.Install, valueOpts *values.Options, out io.Writer) (*release.Release, error) {
   158  	debug("Original chart version: %q", client.Version)
   159  	if client.Version == "" && client.Devel {
   160  		debug("setting version to >0.0.0-0")
   161  		client.Version = ">0.0.0-0"
   162  	}
   163  
   164  	name, chart, err := client.NameAndChart(args)
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	client.ReleaseName = name
   169  
   170  	cp, err := client.ChartPathOptions.LocateChart(chart, settings)
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  
   175  	debug("CHART PATH: %s\n", cp)
   176  
   177  	p := getter.All(settings)
   178  	vals, err := valueOpts.MergeValues(p)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  
   183  	// Check chart dependencies to make sure all are present in /charts
   184  	chartRequested, err := loader.Load(cp)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  
   189  	validInstallableChart, err := isChartInstallable(chartRequested)
   190  	if !validInstallableChart {
   191  		return nil, err
   192  	}
   193  
   194  	if req := chartRequested.Metadata.Dependencies; req != nil {
   195  		// If CheckDependencies returns an error, we have unfulfilled dependencies.
   196  		// As of Helm 2.4.0, this is treated as a stopping condition:
   197  		// https://github.com/helm/helm/issues/2209
   198  		if err := action.CheckDependencies(chartRequested, req); err != nil {
   199  			if client.DependencyUpdate {
   200  				man := &downloader.Manager{
   201  					Out:              out,
   202  					ChartPath:        cp,
   203  					Keyring:          client.ChartPathOptions.Keyring,
   204  					SkipUpdate:       false,
   205  					Getters:          p,
   206  					RepositoryConfig: settings.RepositoryConfig,
   207  					RepositoryCache:  settings.RepositoryCache,
   208  				}
   209  				if err := man.Update(); err != nil {
   210  					return nil, err
   211  				}
   212  			} else {
   213  				return nil, err
   214  			}
   215  		}
   216  	}
   217  
   218  	client.Namespace = getNamespace()
   219  	return client.Run(chartRequested, vals)
   220  }
   221  
   222  // isChartInstallable validates if a chart can be installed
   223  //
   224  // Application chart type is only installable
   225  func isChartInstallable(ch *chart.Chart) (bool, error) {
   226  	switch ch.Metadata.Type {
   227  	case "", "application":
   228  		return true, nil
   229  	}
   230  	return false, errors.Errorf("%s charts are not installable", ch.Metadata.Type)
   231  }