From 53b01949a86f9d0f8bdef5207f100b079dbe4272 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Fri, 2 Sep 2016 17:59:59 -0600 Subject: [PATCH 1/2] fix(tiller): store failed release on post-inst failure This fixes a bug where post-install hooks did not result in recording a failure. --- cmd/tiller/release_server.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go index 00af55e5c..c20bc4d50 100644 --- a/cmd/tiller/release_server.go +++ b/cmd/tiller/release_server.go @@ -538,8 +538,8 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install kubeCli := s.env.KubeClient b := bytes.NewBufferString(r.Manifest) 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) + r.Info.Status.Code = release.Status_FAILED s.recordRelease(r, req.ReuseName) return res, fmt.Errorf("release %s failed: %s", r.Name, err) } @@ -547,6 +547,9 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install // post-install hooks if !req.DisableHooks { 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) return res, err } } From 663f2b0f1db33c9c223a9e8b968c573c33cd5aa5 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 6 Sep 2016 18:00:08 -0600 Subject: [PATCH 2/2] fix(tiller): add test for failed hooks --- cmd/tiller/release_server.go | 2 +- cmd/tiller/release_server_test.go | 35 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go index c20bc4d50..52ee7228c 100644 --- a/cmd/tiller/release_server.go +++ b/cmd/tiller/release_server.go @@ -588,7 +588,7 @@ func (s *releaseServer) execHook(hs []*release.Hook, name, namespace, hook strin b := bytes.NewBufferString(h.Manifest) if err := kubeCli.Create(namespace, b); err != nil { - log.Printf("wrning: Release %q pre-install %s failed: %s", name, h.Path, err) + log.Printf("warning: Release %q pre-install %s failed: %s", name, h.Path, err) return err } // No way to rewind a bytes.Buffer()? diff --git a/cmd/tiller/release_server_test.go b/cmd/tiller/release_server_test.go index a9d042ab5..339f9e3f5 100644 --- a/cmd/tiller/release_server_test.go +++ b/cmd/tiller/release_server_test.go @@ -17,7 +17,9 @@ limitations under the License. package main import ( + "errors" "fmt" + "io" "os" "regexp" "strings" @@ -431,6 +433,25 @@ func TestInstallReleaseNoHooks(t *testing.T) { } } +func TestInstallReleaseFailedHooks(t *testing.T) { + c := context.Background() + rs := rsFixture() + rs.env.Releases.Create(releaseStub()) + rs.env.KubeClient = newHookFailingKubeClient() + + req := &services.InstallReleaseRequest{ + Chart: chartStub(), + } + res, err := rs.InstallRelease(c, req) + if err == nil { + t.Error("Expected failed install") + } + + if hl := res.Release.Info.Status.Code; hl != release.Status_FAILED { + t.Errorf("Expected FAILED release. Got %d", hl) + } +} + func TestInstallReleaseReuseName(t *testing.T) { c := context.Background() rs := rsFixture() @@ -912,6 +933,20 @@ func mockEnvironment() *environment.Environment { return e } +func newHookFailingKubeClient() *hookFailingKubeClient { + return &hookFailingKubeClient{ + PrintingKubeClient: environment.PrintingKubeClient{Out: os.Stdout}, + } +} + +type hookFailingKubeClient struct { + environment.PrintingKubeClient +} + +func (h *hookFailingKubeClient) WatchUntilReady(ns string, r io.Reader) error { + return errors.New("Failed watch") +} + type mockListServer struct { val *services.ListReleasesResponse }