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 }