From ff49127c70a1ceb22dcc85d1118a63d996348df5 Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Thu, 28 Sep 2017 13:15:38 +0100 Subject: [PATCH] Abort install/update early if Release ConfigMap can't be stored It is better not to update any resource and report error, than update some/all resource and have no record of a release --- pkg/tiller/release_install.go | 14 ++++++++++---- pkg/tiller/release_server.go | 7 ++++--- pkg/tiller/release_update.go | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pkg/tiller/release_install.go b/pkg/tiller/release_install.go index 8e7fd3acd..efad2307a 100644 --- a/pkg/tiller/release_install.go +++ b/pkg/tiller/release_install.go @@ -162,7 +162,9 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install // update old release status old.Info.Status.Code = release.Status_SUPERSEDED - s.recordRelease(old, true) + if err := s.recordRelease(old, true); err != nil { + return res, fmt.Errorf("Failed to update existing Release v%d status. Aborting install, no resources were updated", old.Version) + } // update new release with next revision number // so as to append to the old release's history @@ -172,14 +174,16 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install Recreate: false, Timeout: req.Timeout, } - s.recordRelease(r, false) + if err := s.recordRelease(r, false); err != nil { + return res, fmt.Errorf("Failed to record new Release v%d status. Aborting install, no resources were updated", r.Version) + } if err := s.ReleaseModule.Update(old, r, updateReq, s.env); err != nil { msg := fmt.Sprintf("Release replace %q failed: %s", r.Name, err) s.Log("warning: %s", msg) old.Info.Status.Code = release.Status_SUPERSEDED r.Info.Status.Code = release.Status_FAILED r.Info.Description = msg - s.recordRelease(old, true) + s.recordRelease(old, true) //ignore store errors as can't do much about them anyway s.recordRelease(r, true) return res, err } @@ -187,7 +191,9 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install default: // nothing to replace, create as normal // regular manifests - s.recordRelease(r, false) + if err := s.recordRelease(r, false); err != nil { + return res, fmt.Errorf("Failed to store initial Release. Aborting install, no resources were updated") + } if err := s.ReleaseModule.Create(r, req, s.env); err != nil { msg := fmt.Sprintf("Release %q failed: %s", r.Name, err) s.Log("warning: %s", msg) diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index 44d5d847a..b6e5a4c48 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -307,14 +307,15 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values return hooks, b, notes, nil } -func (s *ReleaseServer) recordRelease(r *release.Release, reuse bool) { +func (s *ReleaseServer) recordRelease(r *release.Release, reuse bool) (err error) { if reuse { - if err := s.env.Releases.Update(r); err != nil { + if err = s.env.Releases.Update(r); err != nil { s.Log("warning: Failed to update release %s: %s", r.Name, err) } - } else if err := s.env.Releases.Create(r); err != nil { + } else if err = s.env.Releases.Create(r); err != nil { s.Log("warning: Failed to record release %s: %s", r.Name, err) } + return err } func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook string, timeout int64) error { diff --git a/pkg/tiller/release_update.go b/pkg/tiller/release_update.go index 58a8a18c0..cada3b49c 100644 --- a/pkg/tiller/release_update.go +++ b/pkg/tiller/release_update.go @@ -42,7 +42,7 @@ func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease if !req.DryRun { s.Log("creating updated release for %s", req.Name) - if err := s.env.Releases.Create(updatedRelease); err != nil { + if err := s.recordRelease(updatedRelease, false); err != nil { return nil, err } }