diff --git a/cmd/helm/install.go b/cmd/helm/install.go index fac2131c1..4e0bc557c 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -31,7 +31,6 @@ 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/release" ) @@ -215,23 +214,10 @@ func runInstall(args []string, client *action.Install, valueOpts *values.Options // https://github.com/helm/helm/issues/2209 if err := action.CheckDependencies(chartRequested, req); err != nil { if client.DependencyUpdate { - man := &downloader.Manager{ - Out: out, - ChartPath: cp, - Keyring: client.ChartPathOptions.Keyring, - SkipUpdate: false, - Getters: p, - RepositoryConfig: settings.RepositoryConfig, - RepositoryCache: settings.RepositoryCache, - Debug: settings.Debug, - } - if err := man.Update(); err != nil { + // Update all dependencies if DependencyUpdate flag is set (Implemented with PR#9399) + if chartRequested, err = action.UpdateDependencies(cp, client.ChartPathOptions.Keyring, settings, out, p); err != nil { return nil, err } - // Reload the chart with the updated Chart.lock file. - if chartRequested, err = loader.Load(cp); err != nil { - return nil, errors.Wrap(err, "failed reloading chart after repo update") - } } else { return nil, err } diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 1952b8421..385d84a0d 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -105,6 +105,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { instClient.Wait = client.Wait instClient.WaitForJobs = client.WaitForJobs instClient.Devel = client.Devel + instClient.DependencyUpdate = client.DependencyUpdate instClient.Namespace = client.Namespace instClient.Atomic = client.Atomic instClient.PostRenderer = client.PostRenderer @@ -132,6 +133,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { return err } + p := getter.All(settings) vals, err := valueOpts.MergeValues(getter.All(settings)) if err != nil { return err @@ -142,7 +144,20 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { if err != nil { return err } + + // Only check dependencies if there are any if req := ch.Metadata.Dependencies; req != nil { + if client.DependencyUpdate { + // Update all dependencies if DependencyUpdate flag is set (Implemented with PR#9399) + if ch, err = action.UpdateDependencies(chartPath, client.ChartPathOptions.Keyring, settings, out, p); err != nil { + return err + } + } + + // If CheckDependencies returns an error, we have unfulfilled dependencies. + // As of Helm 2.4.0, this is treated as a stopping condition: + // https://github.com/helm/helm/issues/2209 + // Update all dependencies if DependencyUpdate is true if err := action.CheckDependencies(ch, req); err != nil { return err } @@ -182,6 +197,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { 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") f.BoolVar(&client.WaitForJobs, "wait-for-jobs", false, "if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout") 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") + f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "run helm dependency update before upgrading the chart") f.IntVar(&client.MaxHistory, "history-max", settings.MaxHistory, "limit the maximum number of revisions saved per release. Use 0 for no limit") 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") diff --git a/pkg/action/dependency.go b/pkg/action/dependency.go index 6a284d762..cc11bb648 100644 --- a/pkg/action/dependency.go +++ b/pkg/action/dependency.go @@ -25,9 +25,13 @@ import ( "github.com/Masterminds/semver/v3" "github.com/gosuri/uitable" + "github.com/pkg/errors" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v3/pkg/downloader" + "helm.sh/helm/v3/pkg/getter" ) // Dependency is the action for building a given chart's dependency tree. @@ -228,3 +232,28 @@ func (d *Dependency) printMissing(chartpath string, out io.Writer, reqs []*chart } } } + +// UpdateDependencies update dependency charts. +func UpdateDependencies(chartPath string, keyRing string, settings *cli.EnvSettings, out io.Writer, p getter.Providers) (*chart.Chart, error) { + // Update all dependencies if DependencyUpdate is true + man := &downloader.Manager{ + Out: out, + ChartPath: chartPath, + Keyring: keyRing, + SkipUpdate: false, + Getters: p, + RepositoryConfig: settings.RepositoryConfig, + RepositoryCache: settings.RepositoryCache, + Debug: settings.Debug, + } + // Reload chart dependencies + if err := man.Update(); err != nil { + return nil, err + } + // Reload the chart with the updated Chart.lock file. + ch, err := loader.Load(chartPath) + if err != nil { + return nil, errors.Wrap(err, "failed reloading chart after repo update") + } + return ch, nil +} diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 3b3dd3f1c..80aaf4f28 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -98,6 +98,8 @@ type Upgrade struct { PostRenderer postrender.PostRenderer // DisableOpenAPIValidation controls whether OpenAPI validation is enforced. DisableOpenAPIValidation bool + // Upgrade Chart dependencies before upgrade if true + DependencyUpdate bool } // NewUpgrade creates a new Upgrade object with the given configuration.