fix(uninstall): supersede deployed releases

This ensures that when `helm uninstall` is run with `--keep-history`
any release in a `deployed` state other than the last release (e.g.
due to a failed upgrade) is being marked as `superseded`.

As a by-effect, running `helm upgrade` on a release which has been
uninstalled after an upgrade failure now no longer works. But instead
fails with a `"<name>" has no deployed releases` error. Which is the
(likely) intended behavior, and prevents other side-effects like
rolling back to a release version which happened before the uninstall
if `--atomic` (or `--rollback-on-failure`) was provided.

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Signed-off-by: MrJack <36191829+biagiopietro@users.noreply.github.com>
pull/31615/head
Hidde Beydals 2 years ago committed by MrJack
parent 84708937bf
commit bd1d2fff75

@ -188,6 +188,25 @@ func (u *Uninstall) Run(name string) (*releasei.UninstallReleaseResponse, error)
u.cfg.Logger().Debug("uninstall: Failed to store updated release", slog.Any("error", err))
}
// Supersede all previous deployments, see issue #12556 (which is a
// variation on #2941).
deployed, err := u.cfg.Releases.DeployedAll(name)
if err != nil && !errors.Is(err, driver.ErrNoDeployedReleases) {
return nil, err
}
for _, reli := range deployed {
rel, err := releaserToV1Release(reli)
if err != nil {
return nil, err
}
u.cfg.Logger().Debug("superseding previous deployment", "version", rel.Version)
rel.Info.Status = common.StatusSuperseded
if err := u.cfg.Releases.Update(rel); err != nil {
u.cfg.Logger().Debug("uninstall: Failed to store updated release", slog.Any("error", err))
}
}
if len(errs) > 0 {
return res, fmt.Errorf("uninstallation completed with %d error(s): %w", len(errs), joinErrors(errs, "; "))
}

@ -19,6 +19,7 @@ package cmd
import (
"testing"
"helm.sh/helm/v4/pkg/release/common"
release "helm.sh/helm/v4/pkg/release/v1"
)
@ -57,6 +58,15 @@ func TestUninstall(t *testing.T) {
golden: "output/uninstall-keep-history.txt",
rels: []*release.Release{release.Mock(&release.MockReleaseOptions{Name: "aeneas"})},
},
{
name: "keep history with earlier deployed release",
cmd: "uninstall aeneas --keep-history",
golden: "output/uninstall-keep-history-earlier-deployed.txt",
rels: []*release.Release{
release.Mock(&release.MockReleaseOptions{Name: "aeneas", Version: 1, Status: common.StatusDeployed}),
release.Mock(&release.MockReleaseOptions{Name: "aeneas", Version: 2, Status: common.StatusFailed}),
},
},
{
name: "wait",
cmd: "uninstall aeneas --wait",

Loading…
Cancel
Save