Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions integration/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2050,6 +2050,7 @@ func TestRenderWithPostRenderHook(t *testing.T) {
description string
projectDir string
expectedOutput string
expectedStderr string
args []string
}{
{
Expand Down Expand Up @@ -2160,12 +2161,38 @@ spec:
name: module2
`,
},
{
description: "single module project, one hook with changes, other without changes and with output",
projectDir: "testdata/post-render-hooks",
args: []string{"-m", "m1", "-p", "one-change-two-without-change-but-with-output", "-t", "customtag"},
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
labels:
app1: before-change-1
app2: after-change-2
name: module1
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module1:customtag
name: module1
`,
expectedStderr: `Starting post-render hooks...
running post-render hook 1
running post-render hook 2
Completed post-render hooks`,
},
}

for _, test := range tests {
testutil.Run(t, test.description, func(t *testutil.T) {
output := skaffold.Render(test.args...).InDir(test.projectDir).RunOrFailOutput(t.T)
t.CheckDeepEqual(test.expectedOutput, string(output), testutil.YamlObj(t.T))
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
skaffold.Render(test.args...).InDir(test.projectDir).RunWithStdoutAndStderrOrFail(t.T, stdout, stderr)
t.CheckDeepEqual(test.expectedOutput, stdout.String(), testutil.YamlObj(t.T))
if test.expectedStderr != "" {
t.CheckMatches(test.expectedStderr, stderr.String())
}
})
}
}
Expand Down
22 changes: 22 additions & 0 deletions integration/skaffold/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,28 @@ func (b *RunBuilder) RunOrFailOutput(t *testing.T) []byte {
return out
}

// RunWithStdoutAndStderrOrFail runs the Skaffold command copying the stdout and stderr to the given writers.
// Fails if there is an error.
func (b *RunBuilder) RunWithStdoutAndStderrOrFail(t *testing.T, stdout, stderr io.Writer) {
t.Helper()

cmd := b.cmd(context.Background())
cmd.Stdout = stdout
cmd.Stderr = stderr
t.Logf("Running %s in %s", cmd.Args, cmd.Dir)

start := time.Now()
err := cmd.Run()
if err != nil {
if ee, ok := err.(*exec.ExitError); ok {
defer t.Errorf(string(ee.Stderr))
}
t.Fatalf("skaffold %s: %v, %s", b.command, err, stderr)
}

t.Logf("Ran %s in %v", cmd.Args, timeutil.Humanize(time.Since(start)))
}

func (b *RunBuilder) cmd(ctx context.Context) *exec.Cmd {
args := []string{b.command}
command := b.getCobraCommand()
Expand Down
16 changes: 15 additions & 1 deletion integration/testdata/post-render-hooks/module1/skaffold.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,18 @@ profiles:
- host:
command:
- "sed"
- "s/before-change-1/after-change-1/g"
- "s/before-change-1/after-change-1/g"

- name: one-change-two-without-change-but-with-output
manifests:
hooks:
after:
- host:
command: ["sh", "-c", "echo running post-render hook 1"]
- host:
command:
- "sed"
- "s/before-change-2/after-change-2/g"
withChange: true
- host:
command: ["sh", "-c", "echo running post-render hook 2"]
15 changes: 10 additions & 5 deletions pkg/skaffold/hooks/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"sync"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/kubernetes/manifest"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/output"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/output/log"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest"
)
Expand Down Expand Up @@ -69,8 +70,10 @@ func (r renderRunner) RunPreHooks(ctx context.Context, out io.Writer) error {
}

func (r renderRunner) RunPostHooks(ctx context.Context, list manifest.ManifestList, out io.Writer) (manifest.ManifestList, error) {
logWriter := log.GetWriter()

if len(r.PostHooks) > 0 {
log.Entry(context.TODO()).Errorf("Starting %s hooks...", phases.PostRender)
output.Default.Fprintln(logWriter, fmt.Sprintf("Starting %s hooks...", phases.PostRender))
}
updated, err := manifest.Load(list.Reader())
if err != nil {
Expand Down Expand Up @@ -100,14 +103,14 @@ func (r renderRunner) RunPostHooks(ctx context.Context, list manifest.ManifestLi
return manifest.ManifestList{}, fmt.Errorf("failed to load manifest")
}
} else {
if err := hook.run(ctx, updated.Reader(), &b); err != nil && !errors.Is(err, &Skip{}) {
if err := hook.run(ctx, updated.Reader(), logWriter); err != nil && !errors.Is(err, &Skip{}) {
return manifest.ManifestList{}, err
}
}
}
}
if len(r.PostHooks) > 0 {
log.Entry(context.TODO()).Errorf("Completed %s hooks", phases.PostRender)
output.Default.Fprintln(logWriter, fmt.Sprintf("Completed %s hooks", phases.PostRender))
}
return updated, nil
}
Expand All @@ -119,8 +122,10 @@ func (r renderRunner) getEnv() []string {
}

func (r renderRunner) run(ctx context.Context, out io.Writer, hooks []latest.RenderHookItem, phase phase) error {
logWriter := log.GetWriter()

if len(hooks) > 0 {
log.Entry(context.TODO()).Errorf("Starting %s hooks...", phase)
output.Default.Fprintln(logWriter, fmt.Sprintf("Starting %s hooks...", phase))
}
env := r.getEnv()
for _, h := range hooks {
Expand All @@ -132,7 +137,7 @@ func (r renderRunner) run(ctx context.Context, out io.Writer, hooks []latest.Ren
}
}
if len(hooks) > 0 {
log.Entry(context.TODO()).Errorf("Completed %s hooks...", phase)
output.Default.Fprintln(logWriter, fmt.Sprintf("Completed %s hooks...", phase))
}
return nil
}
5 changes: 5 additions & 0 deletions pkg/skaffold/output/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ func Entry(ctx context.Context) *logrus.Entry {
})
}

// Returns the output used by the logger to write its content.
func GetWriter() io.Writer {
return logger.Out
}

// IsDebugLevelEnabled returns true if debug level log is enabled.
func IsDebugLevelEnabled() bool {
return logger.IsLevelEnabled(logrus.DebugLevel)
Expand Down