From 0e6f9a5af47022bae3ace06ad6709c2589397ea1 Mon Sep 17 00:00:00 2001 From: fibonacci1729 Date: Tue, 25 Oct 2016 11:19:53 -0600 Subject: [PATCH] feat(998): append to history on install --replace --- cmd/tiller/release_server.go | 63 ++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go index 2215e0184..a66b9e940 100644 --- a/cmd/tiller/release_server.go +++ b/cmd/tiller/release_server.go @@ -502,7 +502,6 @@ func (s *releaseServer) prepareRollback(req *services.RollbackReleaseRequest) (* return nil, nil, err } - // Store a new release object with previous release's configuration // Store a new release object with previous release's configuration target := &release.Release{ Name: req.Name, @@ -536,9 +535,14 @@ func (s *releaseServer) uniqName(start string, reuse bool) (string, error) { return "", fmt.Errorf("release name %q exceeds max length of %d", start, releaseNameMaxLen) } - if rel, err := s.env.Releases.Get(start, 1); err == driver.ErrReleaseNotFound { + h, err := s.env.Releases.History(start) + if err != nil || len(h) < 1 { return start, nil - } else if st := rel.Info.Status.Code; reuse && (st == release.Status_DELETED || st == release.Status_FAILED) { + } + relutil.Reverse(h, relutil.SortByRevision) + rel := h[0] + + if st := rel.Info.Status.Code; reuse && (st == release.Status_DELETED || st == release.Status_FAILED) { // Allowe re-use of names if the previous release is marked deleted. log.Printf("reusing name %q", start) return start, nil @@ -603,6 +607,7 @@ func (s *releaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re name, err := s.uniqName(req.Name, req.ReuseName) if err != nil { + log.Printf("FAILING HERE: %s\n", err) return nil, err } @@ -737,14 +742,45 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install } } - // regular manifests - kubeCli := s.env.KubeClient - b := bytes.NewBufferString(r.Manifest) - if err := kubeCli.Create(r.Namespace, b); err != nil { - log.Printf("warning: Release %q failed: %s", r.Name, err) - r.Info.Status.Code = release.Status_FAILED - s.recordRelease(r, req.ReuseName) - return res, fmt.Errorf("release %s failed: %s", r.Name, err) + // if this is a replace operation, append to the release history + if req.ReuseName { + switch h, err := s.env.Releases.History(req.Name); { + case err == nil && len(h) >= 1: + // get latest release revision + relutil.Reverse(h, relutil.SortByRevision) + + // old release + old := h[0] + + // update old release status + old.Info.Status.Code = release.Status_SUPERSEDED + s.recordRelease(old, true) + + // update new release with next revision number + // so as to append to the old release's history + r.Version = old.Version + 1 + + if err := s.performKubeUpdate(old, r); err != nil { + log.Printf("warning: Release replace %q failed: %s", r.Name, err) + old.Info.Status.Code = release.Status_SUPERSEDED + r.Info.Status.Code = release.Status_FAILED + s.recordRelease(old, true) + s.recordRelease(r, false) + return res, err + } + + default: + // nothing to replace + } + } else { + // regular manifests + b := bytes.NewBufferString(r.Manifest) + if err := s.env.KubeClient.Create(r.Namespace, b); err != nil { + log.Printf("warning: Release %q failed: %s", r.Name, err) + r.Info.Status.Code = release.Status_FAILED + s.recordRelease(r, false) + return res, fmt.Errorf("release %s failed: %s", r.Name, err) + } } // post-install hooks @@ -752,7 +788,7 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install if err := s.execHook(r.Hooks, r.Name, r.Namespace, postInstall); err != nil { log.Printf("warning: Release %q failed post-install: %s", r.Name, err) r.Info.Status.Code = release.Status_FAILED - s.recordRelease(r, req.ReuseName) + s.recordRelease(r, false) return res, err } } @@ -765,7 +801,8 @@ 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 - s.recordRelease(r, req.ReuseName) + s.recordRelease(r, false) + return res, nil }