From e0b9ef060198e7836bde9408699254196cce9c8f Mon Sep 17 00:00:00 2001 From: Simon Alling Date: Thu, 9 Dec 2021 16:04:16 +0100 Subject: [PATCH] Make getHookLog a field in action.Configuration Signed-off-by: Simon Alling --- pkg/action/action.go | 26 ++++++++++++++++++++++++++ pkg/action/action_test.go | 5 +++++ pkg/action/hooks.go | 26 +------------------------- pkg/action/release_testing.go | 2 +- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/pkg/action/action.go b/pkg/action/action.go index f093ed7f8..48212c98e 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -18,7 +18,9 @@ package action import ( "bytes" + "context" "fmt" + "io" "os" "path" "path/filepath" @@ -26,6 +28,7 @@ import ( "strings" "github.com/pkg/errors" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/discovery" @@ -95,6 +98,8 @@ type Configuration struct { Capabilities *chartutil.Capabilities Log func(string, ...interface{}) + + GetHookLog func(rel *release.Release, hook *release.Hook) (release.HookLog, error) } // renderResources renders the templates in a chart @@ -276,6 +281,26 @@ func (cfg *Configuration) getCapabilities() (*chartutil.Capabilities, error) { return cfg.Capabilities, nil } +// getHookLogFromCluster gets the log from the pod associated with the given hook, which is expected to be a test hook. +func (cfg *Configuration) getHookLogFromCluster(rel *release.Release, hook *release.Hook) (release.HookLog, error) { + var nothing release.HookLog + client, err := cfg.KubernetesClientSet() + if err != nil { + return nothing, errors.Wrapf(err, "unable to create Kubernetes client set to fetch pod logs") + } + req := client.CoreV1().Pods(rel.Namespace).GetLogs(hook.Name, &v1.PodLogOptions{}) + responseBody, err := req.Stream(context.Background()) + if err != nil { + return nothing, errors.Wrapf(err, "unable to get pod logs for %s", hook.Name) + } + stringBuilder := new(strings.Builder) + _, err = io.Copy(stringBuilder, responseBody) + if err != nil { + return nothing, errors.Wrapf(err, "unable to get pod logs for %s", hook.Name) + } + return release.HookLog(stringBuilder.String()), nil +} + // KubernetesClientSet creates a new kubernetes ClientSet based on the configuration func (cfg *Configuration) KubernetesClientSet() (kubernetes.Interface, error) { conf, err := cfg.RESTClientGetter.ToRESTConfig() @@ -415,6 +440,7 @@ func (cfg *Configuration) Init(getter genericclioptions.RESTClientGetter, namesp cfg.KubeClient = kc cfg.Releases = store cfg.Log = log + cfg.GetHookLog = cfg.getHookLogFromCluster return nil } diff --git a/pkg/action/action_test.go b/pkg/action/action_test.go index f8bdff3b7..3baec6afd 100644 --- a/pkg/action/action_test.go +++ b/pkg/action/action_test.go @@ -50,6 +50,10 @@ func actionConfigFixture(t *testing.T) *Configuration { t.Fatal(err) } + mockHookLogGetter := func(rel *release.Release, hook *release.Hook) (release.HookLog, error) { + return release.HookLog("example test pod log output"), err + } + return &Configuration{ Releases: storage.Init(driver.NewMemory()), KubeClient: &kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: ioutil.Discard}}, @@ -61,6 +65,7 @@ func actionConfigFixture(t *testing.T) *Configuration { t.Logf(format, v...) } }, + GetHookLog: mockHookLogGetter, } } diff --git a/pkg/action/hooks.go b/pkg/action/hooks.go index 6a8e2d1d3..93eb90b4e 100644 --- a/pkg/action/hooks.go +++ b/pkg/action/hooks.go @@ -17,14 +17,10 @@ package action import ( "bytes" - "context" - "io" "sort" - "strings" "time" "github.com/pkg/errors" - v1 "k8s.io/api/core/v1" "helm.sh/helm/v3/pkg/release" helmtime "helm.sh/helm/v3/pkg/time" @@ -89,7 +85,7 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent, h.LastRun.CompletedAt = helmtime.Now() if isTestHook(h) { - hookLog, err := getHookLog(cfg, rl, h) + hookLog, err := cfg.GetHookLog(rl, h) if err != nil { return err } @@ -120,26 +116,6 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent, return nil } -// getHookLog gets the log from the pod associated with the given hook, which is expected to be a test hook. -func getHookLog(cfg *Configuration, rel *release.Release, hook *release.Hook) (release.HookLog, error) { - var nothing release.HookLog - client, err := cfg.KubernetesClientSet() - if err != nil { - return nothing, errors.Wrapf(err, "unable to create Kubernetes client set to fetch pod logs") - } - req := client.CoreV1().Pods(rel.Namespace).GetLogs(hook.Name, &v1.PodLogOptions{}) - responseBody, err := req.Stream(context.Background()) - if err != nil { - return nothing, errors.Wrapf(err, "unable to get pod logs for %s", hook.Name) - } - stringBuilder := new(strings.Builder) - _, err = io.Copy(stringBuilder, responseBody) - if err != nil { - return nothing, errors.Wrapf(err, "unable to get pod logs for %s", hook.Name) - } - return release.HookLog(stringBuilder.String()), nil -} - // hookByWeight is a sorter for hooks type hookByWeight []*release.Hook diff --git a/pkg/action/release_testing.go b/pkg/action/release_testing.go index 849b69dab..3c5ee0757 100644 --- a/pkg/action/release_testing.go +++ b/pkg/action/release_testing.go @@ -102,7 +102,7 @@ func (r *ReleaseTesting) Run(name string) (*release.Release, error) { func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error { for _, h := range rel.Hooks { if isTestHook(h) { - hookLog, err := getHookLog(r.cfg, rel, h) + hookLog, err := r.cfg.GetHookLog(rel, h) if err != nil { return err }