From a8cbf3aa51d98bf75e3f437e84eb084d5370bf16 Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Tue, 27 May 2025 11:40:46 -0600 Subject: [PATCH] fix: action hooks delete policy mutex Signed-off-by: Terry Howe --- pkg/action/action.go | 3 +++ pkg/action/hooks.go | 28 +++++++++++++++++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/pkg/action/action.go b/pkg/action/action.go index 6905f3f44..40194dfd7 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -26,6 +26,7 @@ import ( "path" "path/filepath" "strings" + "sync" "text/template" "k8s.io/apimachinery/pkg/api/meta" @@ -86,6 +87,8 @@ type Configuration struct { // HookOutputFunc called with container name and returns and expects writer that will receive the log output. HookOutputFunc func(namespace, pod, container string) io.Writer + + mutex sync.Mutex } // renderResources renders the templates in a chart diff --git a/pkg/action/hooks.go b/pkg/action/hooks.go index 591371e44..7f265797b 100644 --- a/pkg/action/hooks.go +++ b/pkg/action/hooks.go @@ -49,13 +49,7 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent, for i, h := range executingHooks { // Set default delete policy to before-hook-creation - if len(h.DeletePolicies) == 0 { - // TODO(jlegrone): Only apply before-hook-creation delete policy to run to completion - // resources. For all other resource types update in place if a - // resource with the same name already exists and is owned by the - // current release. - h.DeletePolicies = []release.HookDeletePolicy{release.HookBeforeHookCreation} - } + cfg.hookSetDeletePolicy(h) if err := cfg.deleteHookByPolicy(h, release.HookBeforeHookCreation, waitStrategy, timeout); err != nil { return err @@ -154,7 +148,7 @@ func (cfg *Configuration) deleteHookByPolicy(h *release.Hook, policy release.Hoo if h.Kind == "CustomResourceDefinition" { return nil } - if hookHasDeletePolicy(h, policy) { + if cfg.hookHasDeletePolicy(h, policy) { resources, err := cfg.KubeClient.Build(bytes.NewBufferString(h.Manifest), false) if err != nil { return fmt.Errorf("unable to build kubernetes object for deleting hook %s: %w", h.Path, err) @@ -188,10 +182,26 @@ func (cfg *Configuration) deleteHooksByPolicy(hooks []*release.Hook, policy rele // hookHasDeletePolicy determines whether the defined hook deletion policy matches the hook deletion polices // supported by helm. If so, mark the hook as one should be deleted. -func hookHasDeletePolicy(h *release.Hook, policy release.HookDeletePolicy) bool { +func (cfg *Configuration) hookHasDeletePolicy(h *release.Hook, policy release.HookDeletePolicy) bool { + cfg.mutex.Lock() + defer cfg.mutex.Unlock() return slices.Contains(h.DeletePolicies, policy) } +// hookClearDeletePolicy determines whether the defined hook deletion policy matches the hook deletion polices +// supported by helm. If so, mark the hook as one should be deleted. +func (cfg *Configuration) hookSetDeletePolicy(h *release.Hook) { + cfg.mutex.Lock() + defer cfg.mutex.Unlock() + if len(h.DeletePolicies) == 0 { + // TODO(jlegrone): Only apply before-hook-creation delete policy to run to completion + // resources. For all other resource types update in place if a + // resource with the same name already exists and is owned by the + // current release. + h.DeletePolicies = []release.HookDeletePolicy{release.HookBeforeHookCreation} + } +} + // outputLogsByPolicy outputs a pods logs if the hook policy instructs it to func (cfg *Configuration) outputLogsByPolicy(h *release.Hook, releaseNamespace string, policy release.HookOutputLogPolicy) error { if !hookHasOutputLogPolicy(h, policy) {