diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 12d797545..d5f4c3f02 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -30,6 +30,7 @@ import ( "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/cli/values" + "helm.sh/helm/v3/pkg/downloader" "helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/storage/driver" ) @@ -110,6 +111,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { instClient.DisableOpenAPIValidation = client.DisableOpenAPIValidation instClient.SubNotes = client.SubNotes instClient.Description = client.Description + instClient.DependencyUpdate = client.DependencyUpdate rel, err := runInstall(args, instClient, valueOpts, out) if err != nil { @@ -131,7 +133,8 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { return err } - vals, err := valueOpts.MergeValues(getter.All(settings)) + p := getter.All(settings) + vals, err := valueOpts.MergeValues(p) if err != nil { return err } @@ -141,9 +144,30 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { if err != nil { return err } + if req := ch.Metadata.Dependencies; req != nil { if err := action.CheckDependencies(ch, req); err != nil { - return err + if client.DependencyUpdate { + man := &downloader.Manager{ + Out: out, + ChartPath: chartPath, + Keyring: client.ChartPathOptions.Keyring, + SkipUpdate: false, + Getters: p, + RepositoryConfig: settings.RepositoryConfig, + RepositoryCache: settings.RepositoryCache, + Debug: settings.Debug, + } + if err := man.Update(); err != nil { + return err + } + // Reload the chart with the updated Chart.lock file. + if ch, err = loader.Load(chartPath); err != nil { + return errors.Wrap(err, "failed reloading chart after repo update") + } + } else { + return err + } } } @@ -184,6 +208,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&client.CleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this upgrade when upgrade fails") f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") f.StringVar(&client.Description, "description", "", "add a custom description") + f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "run helm dependency update before upgrading the chart") addChartPathOptionsFlags(f, &client.ChartPathOptions) addValueOptionsFlags(f, valueOpts) bindOutputFlag(cmd, &outfmt) diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go index 6fe79ebce..43d790df8 100644 --- a/cmd/helm/upgrade_test.go +++ b/cmd/helm/upgrade_test.go @@ -125,6 +125,17 @@ func TestUpgradeCmd(t *testing.T) { golden: "output/upgrade-with-install-timeout.txt", rels: []*release.Release{relMock("crazy-bunny", 1, ch)}, }, + { + name: "install a release with missing dependencies", + cmd: fmt.Sprintf("upgrade bonkers-bunny -i '%s'", missingDepsPath), + golden: "output/upgrade-with-install-missing-dependencies.txt", + wantError: true, + }, + { + name: "install a release with missing dependencies", + cmd: fmt.Sprintf("upgrade bonkers-bunny -i --dependency-update '%s'", missingDepsPath), + golden: "output/upgrade-with-install-dependency-update.txt", + }, { name: "upgrade a release with wait", cmd: fmt.Sprintf("upgrade crazy-bunny --wait '%s'", chartPath), @@ -137,6 +148,11 @@ func TestUpgradeCmd(t *testing.T) { golden: "output/upgrade-with-missing-dependencies.txt", wantError: true, }, + { + name: "upgrade a release with missing dependencies", + cmd: fmt.Sprintf("upgrade --dependency-update bonkers-bunny %s", missingDepsPath), + golden: "output/upgrade-with-dependency-update.txt", + }, { name: "upgrade a release with bad dependencies", cmd: fmt.Sprintf("upgrade bonkers-bunny '%s'", badDepsPath), diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index c439af79d..3b22f8ab5 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -96,6 +96,8 @@ type Upgrade struct { PostRenderer postrender.PostRenderer // DisableOpenAPIValidation controls whether OpenAPI validation is enforced. DisableOpenAPIValidation bool + // Run dependency update + DependencyUpdate bool } // NewUpgrade creates a new Upgrade object with the given configuration.