Signed-off-by: Gerard Nguyen <gerard@replicated.com>
pull/30616/head
Gerard Nguyen 2 years ago committed by Andrea Tartaglia
parent 5aeedb18ca
commit d6d6fc01f7
No known key found for this signature in database

@ -17,6 +17,9 @@ package action
import ( import (
"bytes" "bytes"
"fmt"
"log"
"slices"
"sort" "sort"
"time" "time"
@ -88,6 +91,11 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
// Mark hook as succeeded or failed // Mark hook as succeeded or failed
if err != nil { if err != nil {
h.LastRun.Phase = release.HookPhaseFailed h.LastRun.Phase = release.HookPhaseFailed
// If a hook is failed, check the annotation of the hook to determine if we should copy the logs client side
if errOutputting := cfg.outputLogsByPolicy(h, rl.Namespace, release.HookOutputOnFailed); errOutputting != nil {
// We log the error here as we want to propagate the hook failure upwards to the release object.
log.Printf("error outputting logs for hook failure: %v", errOutputting)
}
// If a hook is failed, check the annotation of the hook to determine whether the hook should be deleted // If a hook is failed, check the annotation of the hook to determine whether the hook should be deleted
// under failed condition. If so, then clear the corresponding resource object in the hook // under failed condition. If so, then clear the corresponding resource object in the hook
if errDeleting := cfg.deleteHookByPolicy(h, release.HookFailed, waitStrategy, timeout); errDeleting != nil { if errDeleting := cfg.deleteHookByPolicy(h, release.HookFailed, waitStrategy, timeout); errDeleting != nil {
@ -158,6 +166,13 @@ func (cfg *Configuration) deleteHookByPolicy(h *release.Hook, policy release.Hoo
if err := waiter.WaitForDelete(resources, timeout); err != nil { if err := waiter.WaitForDelete(resources, timeout); err != nil {
return err return err
} }
// wait for resources until they are deleted to avoid conflicts
if kubeClient, ok := cfg.KubeClient.(kube.InterfaceExt); ok {
if err := kubeClient.WaitForDelete(resources, timeout); err != nil {
return err
}
}
} }
return nil return nil
} }
@ -195,14 +210,35 @@ func (cfg *Configuration) hookSetDeletePolicy(h *release.Hook) {
} }
} }
// deleteHooksByPolicy deletes all hooks if the hook policy instructs it to // outputLogsByPolicy outputs a pods logs if the hook policy instructs it to
func (cfg *Configuration) deleteHooksByPolicy(hooks []*release.Hook, policy release.HookDeletePolicy) error { func (cfg *Configuration) outputLogsByPolicy(h *release.Hook, releaseNamespace string, policy release.HookOutputLogPolicy) error {
for _, h := range hooks { if !hookHasOutputLogPolicy(h, policy) {
if err := cfg.deleteHookByPolicy(h, policy); err != nil { return nil
}
namespace, err := cfg.deriveNamespace(h, releaseNamespace)
if err != nil {
return err
}
switch h.Kind {
case "Job":
return cfg.outputContainerLogsForListOptions(namespace, metav1.ListOptions{LabelSelector: fmt.Sprintf("job-name=%s", h.Name)})
case "Pod":
return cfg.outputContainerLogsForListOptions(namespace, metav1.ListOptions{FieldSelector: fmt.Sprintf("metadata.name=%s", h.Name)})
default:
return nil
}
}
func (cfg *Configuration) outputContainerLogsForListOptions(namespace string, listOptions metav1.ListOptions) error {
// TODO Helm 4: Remove this check when GetPodList and OutputContainerLogsForPodList are moved from InterfaceLogs to Interface
if kubeClient, ok := cfg.KubeClient.(kube.InterfaceLogs); ok {
podList, err := kubeClient.GetPodList(namespace, listOptions)
if err != nil {
return err return err
} }
err = kubeClient.OutputContainerLogsForPodList(podList, namespace, cfg.HookOutputFunc)
return err
} }
return nil return nil
} }

Loading…
Cancel
Save