Commit c180c4a2 authored by Nic Roland's avatar Nic Roland

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
parent bf9dea13
...@@ -503,6 +503,16 @@ func validateYAML(data string) error { ...@@ -503,6 +503,16 @@ func validateYAML(data string) error {
return yaml.Unmarshal([]byte(data), b) 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. // performRelease runs a release.
func (s *releaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) { func (s *releaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
res := &services.InstallReleaseResponse{Release: r} res := &services.InstallReleaseResponse{Release: r}
...@@ -525,9 +535,7 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install ...@@ -525,9 +535,7 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install
if err := kubeCli.Create(r.Namespace, b); err != nil { if err := kubeCli.Create(r.Namespace, b); err != nil {
r.Info.Status.Code = release.Status_FAILED r.Info.Status.Code = release.Status_FAILED
log.Printf("warning: Release %q failed: %s", r.Name, err) log.Printf("warning: Release %q failed: %s", r.Name, err)
if err := s.env.Releases.Create(r); err != nil { s.recordRelease(r, req.ReuseName)
log.Printf("warning: Failed to record release %q: %s", r.Name, err)
}
return res, fmt.Errorf("release %s failed: %s", r.Name, err) 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 ...@@ -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 // One possible strategy would be to do a timed retry to see if we can get
// this stored in the future. // this stored in the future.
r.Info.Status.Code = release.Status_DEPLOYED r.Info.Status.Code = release.Status_DEPLOYED
if err := s.env.Releases.Create(r); err != nil { s.recordRelease(r, req.ReuseName)
log.Printf("warning: Failed to record release %q: %s", r.Name, err)
}
return res, nil return res, nil
} }
......
...@@ -451,6 +451,15 @@ func TestInstallReleaseReuseName(t *testing.T) { ...@@ -451,6 +451,15 @@ func TestInstallReleaseReuseName(t *testing.T) {
if res.Release.Name != rel.Name { if res.Release.Name != rel.Name {
t.Errorf("expected %q, got %q", rel.Name, res.Release.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) { func TestUpdateRelease(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment