From f0dc89c83bc7c07c58aaf8ada4058bf407e4c54d Mon Sep 17 00:00:00 2001 From: Noah Lackstein Date: Thu, 27 Aug 2020 11:15:09 -0700 Subject: [PATCH] feat(helm): add support for a `pre-ready` hook Adds a new `pre-ready` hook type that runs after resources have been created or updated, but before they're necessarily in a ready state. This allows for charts that provision a resources using a subchart, use a hook to configure those resources (for example, migrating a database), and require that subchart resources be configured before the pods in their chart are in a ready state. Using the `--wait` flag with Helm will currently fail with these charts, making them incompatible with the chart-testing tool. Fixes #7740, fixes helm/chart-testing#202 Signed-off-by: Noah Lackstein --- pkg/action/install.go | 6 +++++ pkg/release/hook.go | 1 + pkg/releaseutil/manifest_sorter.go | 1 + pkg/releaseutil/manifest_sorter_test.go | 32 +++++++++++++++++++------ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/pkg/action/install.go b/pkg/action/install.go index 00fb208b0..d14ad7864 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -344,6 +344,12 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release. } } + if !i.DisableHooks { + if err := i.cfg.execHook(rel, release.HookPreReady, i.Timeout); err != nil { + return i.failRelease(rel, fmt.Errorf("failed pre-ready: %s", err)) + } + } + if i.Wait { if err := i.cfg.KubeClient.Wait(resources, i.Timeout); err != nil { return i.failRelease(rel, err) diff --git a/pkg/release/hook.go b/pkg/release/hook.go index 662320f06..5420615d1 100644 --- a/pkg/release/hook.go +++ b/pkg/release/hook.go @@ -33,6 +33,7 @@ const ( HookPostUpgrade HookEvent = "post-upgrade" HookPreRollback HookEvent = "pre-rollback" HookPostRollback HookEvent = "post-rollback" + HookPreReady HookEvent = "pre-ready" HookTest HookEvent = "test" ) diff --git a/pkg/releaseutil/manifest_sorter.go b/pkg/releaseutil/manifest_sorter.go index e83414500..7657509dc 100644 --- a/pkg/releaseutil/manifest_sorter.go +++ b/pkg/releaseutil/manifest_sorter.go @@ -61,6 +61,7 @@ var events = map[string]release.HookEvent{ release.HookPostUpgrade.String(): release.HookPostUpgrade, release.HookPreRollback.String(): release.HookPreRollback, release.HookPostRollback.String(): release.HookPostRollback, + release.HookPreReady.String(): release.HookPreReady, release.HookTest.String(): release.HookTest, // Support test-success for backward compatibility with Helm 2 tests "test-success": release.HookTest, diff --git a/pkg/releaseutil/manifest_sorter_test.go b/pkg/releaseutil/manifest_sorter_test.go index 20d809317..3500649ab 100644 --- a/pkg/releaseutil/manifest_sorter_test.go +++ b/pkg/releaseutil/manifest_sorter_test.go @@ -62,7 +62,8 @@ metadata: annotations: "helm.sh/hook": post-install `, - }, { + }, + { name: []string{"third"}, path: "three", kind: []string{"ReplicaSet"}, @@ -74,7 +75,8 @@ metadata: annotations: "helm.sh/hook": no-such-hook `, - }, { + }, + { name: []string{"fourth"}, path: "four", kind: []string{"Pod"}, @@ -85,7 +87,8 @@ metadata: name: fourth annotations: nothing: here`, - }, { + }, + { name: []string{"fifth"}, path: "five", kind: []string{"ReplicaSet"}, @@ -97,14 +100,16 @@ metadata: annotations: "helm.sh/hook": post-delete, post-install `, - }, { + }, + { // Regression test: files with an underscore in the base name should be skipped. name: []string{"sixth"}, path: "six/_six", kind: []string{"ReplicaSet"}, hooks: map[string][]release.HookEvent{"sixth": nil}, manifest: `invalid manifest`, // This will fail if partial is not skipped. - }, { + }, + { // Regression test: files with no content should be skipped. name: []string{"seventh"}, path: "seven", @@ -130,6 +135,19 @@ metadata: name: example-test annotations: "helm.sh/hook": test +`, + }, + { + name: []string{"ninth"}, + path: "nine", + kind: []string{"ReplicaSet"}, + hooks: map[string][]release.HookEvent{"ninth": {release.HookPreReady}}, + manifest: `kind: ReplicaSet +apiVersion: v1beta1 +metadata: + name: ninth + annotations: + "helm.sh/hook": pre-ready `, }, } @@ -149,8 +167,8 @@ metadata: t.Errorf("Expected 2 generic manifests, got %d", len(generic)) } - if len(hs) != 4 { - t.Errorf("Expected 4 hooks, got %d", len(hs)) + if len(hs) != 5 { + t.Errorf("Expected 5 hooks, got %d", len(hs)) } for _, out := range hs {