github.com/codefresh-io/kcfi@v0.0.0-20230301195427-c1578715cc46/cmd/kcfi/upgrade.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 "fmt" 21 "io" 22 "time" 23 24 "github.com/pkg/errors" 25 "github.com/spf13/cobra" 26 27 "github.com/codefresh-io/kcfi/pkg/helm-internal/completion" 28 "helm.sh/helm/v3/cmd/helm/require" 29 "helm.sh/helm/v3/pkg/action" 30 "helm.sh/helm/v3/pkg/chart/loader" 31 "helm.sh/helm/v3/pkg/cli/output" 32 "helm.sh/helm/v3/pkg/cli/values" 33 "helm.sh/helm/v3/pkg/getter" 34 "helm.sh/helm/v3/pkg/storage/driver" 35 ) 36 37 const upgradeDesc = ` 38 This command upgrades a release to a new version of a chart. 39 40 The upgrade arguments must be a release and chart. The chart 41 argument can be either: a chart reference('example/mariadb'), a path to a chart directory, 42 a packaged chart, or a fully qualified URL. For chart references, the latest 43 version will be specified unless the '--version' flag is set. 44 45 To override values in a chart, use either the '--values' flag and pass in a file 46 or use the '--set' flag and pass configuration from the command line, to force string 47 values, use '--set-string'. In case a value is large and therefore 48 you want not to use neither '--values' nor '--set', use '--set-file' to read the 49 single large value from file. 50 51 You can specify the '--values'/'-f' flag multiple times. The priority will be given to the 52 last (right-most) file specified. For example, if both myvalues.yaml and override.yaml 53 contained a key called 'Test', the value set in override.yaml would take precedence: 54 55 $ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis 56 57 You can specify the '--set' flag multiple times. The priority will be given to the 58 last (right-most) set specified. For example, if both 'bar' and 'newbar' values are 59 set for a key called 'foo', the 'newbar' value would take precedence: 60 61 $ helm upgrade --set foo=bar --set foo=newbar redis ./redis 62 ` 63 64 func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { 65 client := action.NewUpgrade(cfg) 66 valueOpts := &values.Options{} 67 var outfmt output.Format 68 var createNamespace bool 69 70 cmd := &cobra.Command{ 71 Use: "upgrade [RELEASE] [CHART]", 72 Short: "upgrade a release", 73 Long: upgradeDesc, 74 Args: require.ExactArgs(2), 75 RunE: func(cmd *cobra.Command, args []string) error { 76 client.Namespace = settings.Namespace() 77 78 // Fixes #7002 - Support reading values from STDIN for `upgrade` command 79 // Must load values AFTER determining if we have to call install so that values loaded from stdin are are not read twice 80 if client.Install { 81 // If a release does not exist, install it. 82 histClient := action.NewHistory(cfg) 83 histClient.Max = 1 84 if _, err := histClient.Run(args[0]); err == driver.ErrReleaseNotFound { 85 // Only print this to stdout for table output 86 if outfmt == output.Table { 87 fmt.Fprintf(out, "Release %q does not exist. Installing it now.\n", args[0]) 88 } 89 instClient := action.NewInstall(cfg) 90 instClient.CreateNamespace = createNamespace 91 instClient.ChartPathOptions = client.ChartPathOptions 92 instClient.DryRun = client.DryRun 93 instClient.DisableHooks = client.DisableHooks 94 instClient.SkipCRDs = client.SkipCRDs 95 instClient.Timeout = client.Timeout 96 instClient.Wait = client.Wait 97 instClient.Devel = client.Devel 98 instClient.Namespace = client.Namespace 99 instClient.Atomic = client.Atomic 100 instClient.PostRenderer = client.PostRenderer 101 instClient.DisableOpenAPIValidation = client.DisableOpenAPIValidation 102 instClient.SubNotes = client.SubNotes 103 104 rel, err := runInstall(args, instClient, valueOpts, out) 105 if err != nil { 106 return err 107 } 108 return outfmt.Write(out, &statusPrinter{rel, settings.Debug}) 109 } else if err != nil { 110 return err 111 } 112 } 113 114 if client.Version == "" && client.Devel { 115 debug("setting version to >0.0.0-0") 116 client.Version = ">0.0.0-0" 117 } 118 119 chartPath, err := client.ChartPathOptions.LocateChart(args[1], settings) 120 if err != nil { 121 return err 122 } 123 124 vals, err := valueOpts.MergeValues(getter.All(settings)) 125 if err != nil { 126 return err 127 } 128 129 // Check chart dependencies to make sure all are present in /charts 130 ch, err := loader.Load(chartPath) 131 if err != nil { 132 return err 133 } 134 if req := ch.Metadata.Dependencies; req != nil { 135 if err := action.CheckDependencies(ch, req); err != nil { 136 return err 137 } 138 } 139 140 if ch.Metadata.Deprecated { 141 fmt.Fprintln(out, "WARNING: This chart is deprecated") 142 } 143 144 rel, err := client.Run(args[0], ch, vals) 145 if err != nil { 146 return errors.Wrap(err, "UPGRADE FAILED") 147 } 148 149 if outfmt == output.Table { 150 fmt.Fprintf(out, "Release %q has been upgraded. Happy Helming!\n", args[0]) 151 } 152 153 return outfmt.Write(out, &statusPrinter{rel, settings.Debug}) 154 }, 155 } 156 157 // Function providing dynamic auto-completion 158 completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { 159 if len(args) == 0 { 160 return compListReleases(toComplete, cfg) 161 } 162 if len(args) == 1 { 163 return compListCharts(toComplete, true) 164 } 165 return nil, completion.BashCompDirectiveNoFileComp 166 }) 167 168 f := cmd.Flags() 169 f.BoolVar(&createNamespace, "create-namespace", false, "if --install is set, create the release namespace if not present") 170 f.BoolVarP(&client.Install, "install", "i", false, "if a release by this name doesn't already exist, run an install") 171 f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") 172 f.BoolVar(&client.DryRun, "dry-run", false, "simulate an upgrade") 173 f.BoolVar(&client.Recreate, "recreate-pods", false, "performs pods restart for the resource if applicable") 174 f.MarkDeprecated("recreate-pods", "functionality will no longer be updated. Consult the documentation for other methods to recreate pods") 175 f.BoolVar(&client.Force, "force", false, "force resource updates through a replacement strategy") 176 f.BoolVar(&client.DisableHooks, "no-hooks", false, "disable pre/post upgrade hooks") 177 f.BoolVar(&client.DisableOpenAPIValidation, "disable-openapi-validation", false, "if set, the upgrade process will not validate rendered templates against the Kubernetes OpenAPI Schema") 178 f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed when an upgrade is performed with install flag enabled. By default, CRDs are installed if not already present, when an upgrade is performed with install flag enabled") 179 f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") 180 f.BoolVar(&client.ResetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart") 181 f.BoolVar(&client.ReuseValues, "reuse-values", false, "when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored") 182 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") 183 f.BoolVar(&client.Atomic, "atomic", false, "if set, upgrade process rolls back changes made in case of failed upgrade. The --wait flag will be set automatically if --atomic is used") 184 f.IntVar(&client.MaxHistory, "history-max", 10, "limit the maximum number of revisions saved per release. Use 0 for no limit") 185 f.BoolVar(&client.CleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this upgrade when upgrade fails") 186 f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") 187 f.StringVar(&client.Description, "description", "", "add a custom description") 188 addChartPathOptionsFlags(f, &client.ChartPathOptions) 189 addValueOptionsFlags(f, valueOpts) 190 bindOutputFlag(cmd, &outfmt) 191 bindPostRenderFlag(cmd, &client.PostRenderer) 192 193 return cmd 194 }