Merge pull request #9653 from Okhoshi/feat/reset-then-reuse-flag

feat(helm): Add --reset-then-reuse-values flag to 'helm upgrade'
pull/12547/head
Scott Rigby 1 year ago committed by GitHub
commit 2745909d3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -252,6 +252,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&client.ResetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart") f.BoolVar(&client.ResetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart")
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") 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")
f.BoolVar(&client.ResetThenReuseValues, "reset-then-reuse-values", false, "when upgrading, reset the values to the ones built into the chart, apply the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' or '--reuse-values' is specified, this is ignored")
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.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.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.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")

@ -82,6 +82,8 @@ type Upgrade struct {
ResetValues bool ResetValues bool
// ReuseValues will re-use the user's last supplied values. // ReuseValues will re-use the user's last supplied values.
ReuseValues bool ReuseValues bool
// ResetThenReuseValues will reset the values to the chart's built-ins then merge with user's last supplied values.
ResetThenReuseValues bool
// Recreate will (if true) recreate pods after a rollback. // Recreate will (if true) recreate pods after a rollback.
Recreate bool Recreate bool
// MaxHistory limits the maximum number of revisions saved per release // MaxHistory limits the maximum number of revisions saved per release
@ -552,6 +554,15 @@ func (u *Upgrade) reuseValues(chart *chart.Chart, current *release.Release, newV
return newVals, nil return newVals, nil
} }
// If the ResetThenReuseValues flag is set, we use the new chart's values, but we copy the old config's values over the new config's values.
if u.ResetThenReuseValues {
u.cfg.Log("merging values from old release to new values")
newVals = chartutil.CoalesceTables(newVals, current.Config)
return newVals, nil
}
if len(newVals) == 0 && len(current.Config) > 0 { if len(newVals) == 0 && len(current.Config) > 0 {
u.cfg.Log("copying values from %s (v%d) to new release.", current.Name, current.Version) u.cfg.Log("copying values from %s (v%d) to new release.", current.Name, current.Version)
newVals = current.Config newVals = current.Config

@ -308,6 +308,59 @@ func TestUpgradeRelease_ReuseValues(t *testing.T) {
}) })
} }
func TestUpgradeRelease_ResetThenReuseValues(t *testing.T) {
is := assert.New(t)
t.Run("reset then reuse values should work with values", func(t *testing.T) {
upAction := upgradeAction(t)
existingValues := map[string]interface{}{
"name": "value",
"maxHeapSize": "128m",
"replicas": 2,
}
newValues := map[string]interface{}{
"name": "newValue",
"maxHeapSize": "512m",
"cpu": "12m",
}
newChartValues := map[string]interface{}{
"memory": "256m",
}
expectedValues := map[string]interface{}{
"name": "newValue",
"maxHeapSize": "512m",
"cpu": "12m",
"replicas": 2,
}
rel := releaseStub()
rel.Name = "nuketown"
rel.Info.Status = release.StatusDeployed
rel.Config = existingValues
err := upAction.cfg.Releases.Create(rel)
is.NoError(err)
upAction.ResetThenReuseValues = true
// setting newValues and upgrading
res, err := upAction.Run(rel.Name, buildChart(withValues(newChartValues)), newValues)
is.NoError(err)
// Now make sure it is actually upgraded
updatedRes, err := upAction.cfg.Releases.Get(res.Name, 2)
is.NoError(err)
if updatedRes == nil {
is.Fail("Updated Release is nil")
return
}
is.Equal(release.StatusDeployed, updatedRes.Info.Status)
is.Equal(expectedValues, updatedRes.Config)
is.Equal(newChartValues, updatedRes.Chart.Values)
})
}
func TestUpgradeRelease_Pending(t *testing.T) { func TestUpgradeRelease_Pending(t *testing.T) {
req := require.New(t) req := require.New(t)

Loading…
Cancel
Save