github.com/corburn/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 }