Merge pull request #13629 from gjenkins8/rename_atomic_rollbackonfailure

Rename 'atomic' -> 'rollback-on-failure'
pull/31178/head
George Jenkins 2 weeks ago committed by GitHub
commit a0d6b0d383
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -81,21 +81,22 @@ type Install struct {
DryRunOption string
// HideSecret can be set to true when DryRun is enabled in order to hide
// Kubernetes Secrets in the output. It cannot be used outside of DryRun.
HideSecret bool
DisableHooks bool
Replace bool
WaitStrategy kube.WaitStrategy
WaitForJobs bool
Devel bool
DependencyUpdate bool
Timeout time.Duration
Namespace string
ReleaseName string
GenerateName bool
NameTemplate string
Description string
OutputDir string
Atomic bool
HideSecret bool
DisableHooks bool
Replace bool
WaitStrategy kube.WaitStrategy
WaitForJobs bool
Devel bool
DependencyUpdate bool
Timeout time.Duration
Namespace string
ReleaseName string
GenerateName bool
NameTemplate string
Description string
OutputDir string
// RollbackOnFailure enables rolling back (uninstalling) the release on failure if set
RollbackOnFailure bool
SkipCRDs bool
SubNotes bool
HideNotes bool
@ -298,9 +299,9 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
slog.Debug("API Version list given outside of client only mode, this list will be ignored")
}
// Make sure if Atomic is set, that wait is set as well. This makes it so
// Make sure if RollbackOnFailure is set, that wait is set as well. This makes it so
// the user doesn't have to specify both
if i.WaitStrategy == kube.HookOnlyStrategy && i.Atomic {
if i.WaitStrategy == kube.HookOnlyStrategy && i.RollbackOnFailure {
i.WaitStrategy = kube.StatusWatcherStrategy
}
@ -530,8 +531,8 @@ func (i *Install) performInstall(rel *release.Release, toBeAdopted kube.Resource
func (i *Install) failRelease(rel *release.Release, err error) (*release.Release, error) {
rel.SetStatus(release.StatusFailed, fmt.Sprintf("Release %q failed: %s", i.ReleaseName, err.Error()))
if i.Atomic {
slog.Debug("install failed, uninstalling release", "release", i.ReleaseName)
if i.RollbackOnFailure {
slog.Debug("install failed and rollback-on-failure is set, uninstalling release", "release", i.ReleaseName)
uninstall := NewUninstall(i.cfg)
uninstall.DisableHooks = i.DisableHooks
uninstall.KeepHistory = false
@ -539,7 +540,7 @@ func (i *Install) failRelease(rel *release.Release, err error) (*release.Release
if _, uninstallErr := uninstall.Run(i.ReleaseName); uninstallErr != nil {
return rel, fmt.Errorf("an error occurred while uninstalling the release. original install error: %w: %w", err, uninstallErr)
}
return rel, fmt.Errorf("release %s failed, and has been uninstalled due to atomic being set: %w", i.ReleaseName, err)
return rel, fmt.Errorf("release %s failed, and has been uninstalled due to rollback-on-failure being set: %w", i.ReleaseName, err)
}
i.recordRelease(rel) // Ignore the error, since we have another error to deal with.
return rel, err

@ -590,16 +590,16 @@ func TestInstallRelease_WaitForJobs(t *testing.T) {
is.Equal(res.Info.Status, release.StatusFailed)
}
func TestInstallRelease_Atomic(t *testing.T) {
func TestInstallRelease_RollbackOnFailure(t *testing.T) {
is := assert.New(t)
t.Run("atomic uninstall succeeds", func(t *testing.T) {
t.Run("rollback-on-failure uninstall succeeds", func(t *testing.T) {
instAction := installAction(t)
instAction.ReleaseName = "come-fail-away"
failer := instAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitError = fmt.Errorf("I timed out")
instAction.cfg.KubeClient = failer
instAction.Atomic = true
instAction.RollbackOnFailure = true
// disabling hooks to avoid an early fail when
// WaitForDelete is called on the pre-delete hook execution
instAction.DisableHooks = true
@ -608,7 +608,7 @@ func TestInstallRelease_Atomic(t *testing.T) {
res, err := instAction.Run(buildChart(), vals)
is.Error(err)
is.Contains(err.Error(), "I timed out")
is.Contains(err.Error(), "atomic")
is.Contains(err.Error(), "rollback-on-failure")
// Now make sure it isn't in storage anymore
_, err = instAction.cfg.Releases.Get(res.Name, res.Version)
@ -616,14 +616,14 @@ func TestInstallRelease_Atomic(t *testing.T) {
is.Equal(err, driver.ErrReleaseNotFound)
})
t.Run("atomic uninstall fails", func(t *testing.T) {
t.Run("rollback-on-failure uninstall fails", func(t *testing.T) {
instAction := installAction(t)
instAction.ReleaseName = "come-fail-away-with-me"
failer := instAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitError = fmt.Errorf("I timed out")
failer.DeleteError = fmt.Errorf("uninstall fail")
instAction.cfg.KubeClient = failer
instAction.Atomic = true
instAction.RollbackOnFailure = true
vals := map[string]interface{}{}
_, err := instAction.Run(buildChart(), vals)
@ -633,7 +633,7 @@ func TestInstallRelease_Atomic(t *testing.T) {
is.Contains(err.Error(), "an error occurred while uninstalling the release")
})
}
func TestInstallRelease_Atomic_Interrupted(t *testing.T) {
func TestInstallRelease_RollbackOnFailure_Interrupted(t *testing.T) {
is := assert.New(t)
instAction := installAction(t)
@ -641,7 +641,7 @@ func TestInstallRelease_Atomic_Interrupted(t *testing.T) {
failer := instAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitDuration = 10 * time.Second
instAction.cfg.KubeClient = failer
instAction.Atomic = true
instAction.RollbackOnFailure = true
vals := map[string]interface{}{}
ctx, cancel := context.WithCancel(t.Context())
@ -652,7 +652,7 @@ func TestInstallRelease_Atomic_Interrupted(t *testing.T) {
res, err := instAction.RunWithContext(ctx, buildChart(), vals)
is.Error(err)
is.Contains(err.Error(), "context canceled")
is.Contains(err.Error(), "atomic")
is.Contains(err.Error(), "rollback-on-failure")
is.Contains(err.Error(), "uninstalled")
// Now make sure it isn't in storage anymore

@ -89,8 +89,8 @@ type Upgrade struct {
ResetThenReuseValues bool
// MaxHistory limits the maximum number of revisions saved per release
MaxHistory int
// Atomic, if true, will roll back on failure.
Atomic bool
// RollbackOnFailure enables rolling back the upgraded release on failure
RollbackOnFailure bool
// CleanupOnFail will, if true, cause the upgrade to delete newly-created resources on a failed update.
CleanupOnFail bool
// SubNotes determines whether sub-notes are rendered in the chart.
@ -151,9 +151,9 @@ func (u *Upgrade) RunWithContext(ctx context.Context, name string, chart *chart.
return nil, err
}
// Make sure if Atomic is set, that wait is set as well. This makes it so
// Make sure wait is set if RollbackOnFailure. This makes it so
// the user doesn't have to specify both
if u.WaitStrategy == kube.HookOnlyStrategy && u.Atomic {
if u.WaitStrategy == kube.HookOnlyStrategy && u.RollbackOnFailure {
u.WaitStrategy = kube.StatusWatcherStrategy
}
@ -390,7 +390,7 @@ func (u *Upgrade) performUpgrade(ctx context.Context, originalRelease, upgradedR
}
}
// Function used to lock the Mutex, this is important for the case when the atomic flag is set.
// Function used to lock the Mutex, this is important for the case when RollbackOnFailure is set.
// In that case the upgrade will finish before the rollback is finished so it is necessary to wait for the rollback to finish.
// The rollback will be trigger by the function failRelease
func (u *Upgrade) reportToPerformUpgrade(c chan<- resultMessage, rel *release.Release, created kube.ResourceList, err error) {
@ -408,7 +408,7 @@ func (u *Upgrade) handleContext(ctx context.Context, done chan interface{}, c ch
case <-ctx.Done():
err := ctx.Err()
// when the atomic flag is set the ongoing release finish first and doesn't give time for the rollback happens.
// when RollbackOnFailure is set, the ongoing release finish first and doesn't give time for the rollback happens.
u.reportToPerformUpgrade(c, upgradedRelease, kube.ResourceList{}, err)
case <-done:
return
@ -499,8 +499,9 @@ func (u *Upgrade) failRelease(rel *release.Release, created kube.ResourceList, e
}
slog.Debug("resource cleanup complete")
}
if u.Atomic {
slog.Debug("upgrade failed and atomic is set, rolling back to last successful release")
if u.RollbackOnFailure {
slog.Debug("Upgrade failed and rollback-on-failure is set, rolling back to previous successful release")
// As a protection, get the last successful release before rollback.
// If there are no successful releases, bail out
@ -534,7 +535,7 @@ func (u *Upgrade) failRelease(rel *release.Release, created kube.ResourceList, e
if rollErr := rollin.Run(rel.Name); rollErr != nil {
return rel, fmt.Errorf("an error occurred while rolling back the release. original upgrade error: %w: %w", err, rollErr)
}
return rel, fmt.Errorf("release %s failed, and has been rolled back due to atomic being set: %w", rel.Name, err)
return rel, fmt.Errorf("release %s failed, and has been rolled back due to rollback-on-failure being set: %w", rel.Name, err)
}
return rel, err

@ -141,11 +141,11 @@ func TestUpgradeRelease_CleanupOnFail(t *testing.T) {
is.Equal(res.Info.Status, release.StatusFailed)
}
func TestUpgradeRelease_Atomic(t *testing.T) {
func TestUpgradeRelease_RollbackOnFailure(t *testing.T) {
is := assert.New(t)
req := require.New(t)
t.Run("atomic rollback succeeds", func(t *testing.T) {
t.Run("rollback-on-failure rollback succeeds", func(t *testing.T) {
upAction := upgradeAction(t)
rel := releaseStub()
@ -157,13 +157,13 @@ func TestUpgradeRelease_Atomic(t *testing.T) {
// We can't make Update error because then the rollback won't work
failer.WatchUntilReadyError = fmt.Errorf("arming key removed")
upAction.cfg.KubeClient = failer
upAction.Atomic = true
upAction.RollbackOnFailure = true
vals := map[string]interface{}{}
res, err := upAction.Run(rel.Name, buildChart(), vals)
req.Error(err)
is.Contains(err.Error(), "arming key removed")
is.Contains(err.Error(), "atomic")
is.Contains(err.Error(), "rollback-on-failure")
// Now make sure it is actually upgraded
updatedRes, err := upAction.cfg.Releases.Get(res.Name, 3)
@ -172,7 +172,7 @@ func TestUpgradeRelease_Atomic(t *testing.T) {
is.Equal(updatedRes.Info.Status, release.StatusDeployed)
})
t.Run("atomic uninstall fails", func(t *testing.T) {
t.Run("rollback-on-failure uninstall fails", func(t *testing.T) {
upAction := upgradeAction(t)
rel := releaseStub()
rel.Name = "fallout"
@ -182,7 +182,7 @@ func TestUpgradeRelease_Atomic(t *testing.T) {
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.UpdateError = fmt.Errorf("update fail")
upAction.cfg.KubeClient = failer
upAction.Atomic = true
upAction.RollbackOnFailure = true
vals := map[string]interface{}{}
_, err := upAction.Run(rel.Name, buildChart(), vals)
@ -409,7 +409,8 @@ func TestUpgradeRelease_Interrupted_Wait(t *testing.T) {
is.Equal(res.Info.Status, release.StatusFailed)
}
func TestUpgradeRelease_Interrupted_Atomic(t *testing.T) {
func TestUpgradeRelease_Interrupted_RollbackOnFailure(t *testing.T) {
is := assert.New(t)
req := require.New(t)
@ -422,7 +423,7 @@ func TestUpgradeRelease_Interrupted_Atomic(t *testing.T) {
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitDuration = 5 * time.Second
upAction.cfg.KubeClient = failer
upAction.Atomic = true
upAction.RollbackOnFailure = true
vals := map[string]interface{}{}
ctx, cancel := context.WithCancel(t.Context())
@ -431,7 +432,7 @@ func TestUpgradeRelease_Interrupted_Atomic(t *testing.T) {
res, err := upAction.RunWithContext(ctx, rel.Name, buildChart(), vals)
req.Error(err)
is.Contains(err.Error(), "release interrupted-release failed, and has been rolled back due to atomic being set: context canceled")
is.Contains(err.Error(), "release interrupted-release failed, and has been rolled back due to rollback-on-failure being set: context canceled")
// Now make sure it is actually upgraded
updatedRes, err := upAction.cfg.Releases.Get(res.Name, 3)

@ -206,7 +206,8 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart")
f.BoolVar(&client.DisableOpenAPIValidation, "disable-openapi-validation", false, "if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema")
f.BoolVar(&client.Atomic, "atomic", false, "if set, the installation process deletes the installation on failure. The --wait flag will be set automatically to \"watcher\" if --atomic is used")
f.BoolVar(&client.RollbackOnFailure, "rollback-on-failure", false, "if set, Helm will rollback (uninstall) the installation upon failure. The --wait flag will be default to \"watcher\" if --rollback-on-failure is set")
f.MarkDeprecated("atomic", "use --rollback-on-failure instead")
f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present")
f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent")
f.BoolVar(&client.SkipSchemaValidation, "skip-schema-validation", false, "if set, disables JSON schema validation")

@ -140,7 +140,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
instClient.WaitForJobs = client.WaitForJobs
instClient.Devel = client.Devel
instClient.Namespace = client.Namespace
instClient.Atomic = client.Atomic
instClient.RollbackOnFailure = client.RollbackOnFailure
instClient.PostRenderer = client.PostRenderer
instClient.DisableOpenAPIValidation = client.DisableOpenAPIValidation
instClient.SubNotes = client.SubNotes
@ -281,7 +281,9 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
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.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 to \"watcher\" if --atomic is used")
f.BoolVar(&client.RollbackOnFailure, "rollback-on-failure", false, "if set, Helm will rollback the upgrade to previous success release upon failure. The --wait flag will be defaulted to \"watcher\" if --rollback-on-failure is set")
f.BoolVar(&client.RollbackOnFailure, "atomic", false, "deprecated")
f.MarkDeprecated("atomic", "use --rollback-on-failure instead")
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")

Loading…
Cancel
Save