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