From c180c4a250808b7c92428832ed9a1030e0ceb665 Mon Sep 17 00:00:00 2001 From: Nic Roland Date: Thu, 1 Sep 2016 17:51:53 +0100 Subject: [PATCH] fix(tiller): Install --replace will result in an upgrade If a release has been deleted, `install --replace` will work but the release status will still be "deleted". This means that subsequest attempts to change the release will fail. Upgrading the release instead will prevent such zombie releases. Closes #1131 --- cmd/tiller/release_server.go | 18 ++++++++++++------ cmd/tiller/release_server_test.go | 9 +++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go index eb1cb158a..7f11bf981 100644 --- a/cmd/tiller/release_server.go +++ b/cmd/tiller/release_server.go @@ -503,6 +503,16 @@ func validateYAML(data string) error { return yaml.Unmarshal([]byte(data), b) } +func (s *releaseServer) recordRelease(r *release.Release, reuse bool) { + if reuse { + if err := s.env.Releases.Update(r); err != nil { + log.Printf("warning: Failed to update release %q: %s", r.Name, err) + } + } else if err := s.env.Releases.Create(r); err != nil { + log.Printf("warning: Failed to record release %q: %s", r.Name, err) + } +} + // performRelease runs a release. func (s *releaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) { res := &services.InstallReleaseResponse{Release: r} @@ -525,9 +535,7 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install if err := kubeCli.Create(r.Namespace, b); err != nil { r.Info.Status.Code = release.Status_FAILED log.Printf("warning: Release %q failed: %s", r.Name, err) - if err := s.env.Releases.Create(r); err != nil { - log.Printf("warning: Failed to record release %q: %s", r.Name, err) - } + s.recordRelease(r, req.ReuseName) return res, fmt.Errorf("release %s failed: %s", r.Name, err) } @@ -546,9 +554,7 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install // One possible strategy would be to do a timed retry to see if we can get // this stored in the future. r.Info.Status.Code = release.Status_DEPLOYED - if err := s.env.Releases.Create(r); err != nil { - log.Printf("warning: Failed to record release %q: %s", r.Name, err) - } + s.recordRelease(r, req.ReuseName) return res, nil } diff --git a/cmd/tiller/release_server_test.go b/cmd/tiller/release_server_test.go index 3e2644c56..c5bd01837 100644 --- a/cmd/tiller/release_server_test.go +++ b/cmd/tiller/release_server_test.go @@ -451,6 +451,15 @@ func TestInstallReleaseReuseName(t *testing.T) { if res.Release.Name != rel.Name { t.Errorf("expected %q, got %q", rel.Name, res.Release.Name) } + + getreq := &services.GetReleaseStatusRequest{Name: rel.Name} + getres, err := rs.GetReleaseStatus(c, getreq) + if err != nil { + t.Errorf("Failed to retrieve release: %s", err) + } + if getres.Info.Status.Code != release.Status_DEPLOYED { + t.Errorf("Release status is %q", getres.Info.Status.Code) + } } func TestUpdateRelease(t *testing.T) {