Make getHookLog a field in action.Configuration

Signed-off-by: Simon Alling <alling.simon@gmail.com>
pull/9677/head
Simon Alling 4 years ago
parent 2dff115c56
commit e0b9ef0601

@ -18,7 +18,9 @@ package action
import ( import (
"bytes" "bytes"
"context"
"fmt" "fmt"
"io"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -26,6 +28,7 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
@ -95,6 +98,8 @@ type Configuration struct {
Capabilities *chartutil.Capabilities Capabilities *chartutil.Capabilities
Log func(string, ...interface{}) Log func(string, ...interface{})
GetHookLog func(rel *release.Release, hook *release.Hook) (release.HookLog, error)
} }
// renderResources renders the templates in a chart // renderResources renders the templates in a chart
@ -276,6 +281,26 @@ func (cfg *Configuration) getCapabilities() (*chartutil.Capabilities, error) {
return cfg.Capabilities, nil 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 // KubernetesClientSet creates a new kubernetes ClientSet based on the configuration
func (cfg *Configuration) KubernetesClientSet() (kubernetes.Interface, error) { func (cfg *Configuration) KubernetesClientSet() (kubernetes.Interface, error) {
conf, err := cfg.RESTClientGetter.ToRESTConfig() conf, err := cfg.RESTClientGetter.ToRESTConfig()
@ -415,6 +440,7 @@ func (cfg *Configuration) Init(getter genericclioptions.RESTClientGetter, namesp
cfg.KubeClient = kc cfg.KubeClient = kc
cfg.Releases = store cfg.Releases = store
cfg.Log = log cfg.Log = log
cfg.GetHookLog = cfg.getHookLogFromCluster
return nil return nil
} }

@ -50,6 +50,10 @@ func actionConfigFixture(t *testing.T) *Configuration {
t.Fatal(err) 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{ return &Configuration{
Releases: storage.Init(driver.NewMemory()), Releases: storage.Init(driver.NewMemory()),
KubeClient: &kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: ioutil.Discard}}, KubeClient: &kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: ioutil.Discard}},
@ -61,6 +65,7 @@ func actionConfigFixture(t *testing.T) *Configuration {
t.Logf(format, v...) t.Logf(format, v...)
} }
}, },
GetHookLog: mockHookLogGetter,
} }
} }

@ -17,14 +17,10 @@ package action
import ( import (
"bytes" "bytes"
"context"
"io"
"sort" "sort"
"strings"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
"helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/release"
helmtime "helm.sh/helm/v3/pkg/time" 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() h.LastRun.CompletedAt = helmtime.Now()
if isTestHook(h) { if isTestHook(h) {
hookLog, err := getHookLog(cfg, rl, h) hookLog, err := cfg.GetHookLog(rl, h)
if err != nil { if err != nil {
return err return err
} }
@ -120,26 +116,6 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
return nil 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 // hookByWeight is a sorter for hooks
type hookByWeight []*release.Hook type hookByWeight []*release.Hook

@ -102,7 +102,7 @@ func (r *ReleaseTesting) Run(name string) (*release.Release, error) {
func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error { func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error {
for _, h := range rel.Hooks { for _, h := range rel.Hooks {
if isTestHook(h) { if isTestHook(h) {
hookLog, err := getHookLog(r.cfg, rel, h) hookLog, err := r.cfg.GetHookLog(rel, h)
if err != nil { if err != nil {
return err return err
} }

Loading…
Cancel
Save