Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Skaffold post renderer #9203

Merged
Merged
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
64 changes: 63 additions & 1 deletion docs-v2/content/en/schemas/v4beta9.json
Original file line number Diff line number Diff line change
@@ -3445,6 +3445,68 @@
"description": "describes a resource to port forward.",
"x-intellij-html-description": "describes a resource to port forward."
},
"PostRenderHookItem": {
"properties": {
"host": {
"$ref": "#/definitions/PostRenderHostHook",
"description": "describes a single lifecycle hook to run on the host machine.",
"x-intellij-html-description": "describes a single lifecycle hook to run on the host machine."
}
},
"preferredOrder": [
"host"
],
"additionalProperties": false,
"type": "object",
"description": "describes a single lifecycle hook to execute after each render step.",
"x-intellij-html-description": "describes a single lifecycle hook to execute after each render step."
},
"PostRenderHostHook": {
"required": [
"command"
],
"properties": {
"command": {
"items": {
"type": "string"
},
"type": "array",
"description": "command to execute.",
"x-intellij-html-description": "command to execute.",
"default": "[]"
},
"dir": {
"type": "string",
"description": "specifies the working directory of the command. If empty, the command runs in the calling process's current directory.",
"x-intellij-html-description": "specifies the working directory of the command. If empty, the command runs in the calling process's current directory."
},
"os": {
"items": {
"type": "string"
},
"type": "array",
"description": "an optional slice of operating system names. If the host machine OS is different, then it skips execution.",
"x-intellij-html-description": "an optional slice of operating system names. If the host machine OS is different, then it skips execution.",
"default": "[]"
},
"withChange": {
"type": "boolean",
"description": "preserves changes made on the manifests by the hook.",
"x-intellij-html-description": "preserves changes made on the manifests by the hook.",
"default": "false"
}
},
"preferredOrder": [
"command",
"os",
"dir",
"withChange"
],
"additionalProperties": false,
"type": "object",
"description": "describes a post render hook definition to execute on the host machine.",
"x-intellij-html-description": "describes a post render hook definition to execute on the host machine."
},
"Profile": {
"required": [
"name"
@@ -3699,7 +3761,7 @@
"properties": {
"after": {
"items": {
"$ref": "#/definitions/RenderHookItem"
"$ref": "#/definitions/PostRenderHookItem"
},
"type": "array",
"description": "describes the list of lifecycle hooks to execute *after* each render step.",
2 changes: 2 additions & 0 deletions integration/examples/lifecycle-hooks/k8s-pod.yaml
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@ apiVersion: v1
kind: Pod
metadata:
name: getting-started
labels:
tier: test-1
spec:
containers:
- name: getting-started
159 changes: 133 additions & 26 deletions integration/render_test.go
Original file line number Diff line number Diff line change
@@ -444,29 +444,6 @@ spec:
containers:
- image: skaffold-helm:latest
name: skaffold-helm
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: skaffold-helm
skaffold.dev/run-id: phony-run-id
name: skaffold-helm
namespace: helm-namespace-2
spec:
replicas: 2
selector:
matchLabels:
app: skaffold-helm
template:
metadata:
labels:
app: skaffold-helm
skaffold.dev/run-id: phony-run-id
spec:
containers:
- image: skaffold-helm:latest
name: skaffold-helm
`,
}, {
description: "Template with Release.namespace set from skaffold.yaml file deploy.helm.releases.namespace - v1 skaffold schema",
@@ -495,7 +472,8 @@ spec:
- image: skaffold-helm:latest
name: skaffold-helm
`,
}, {
},
{
description: "Template replicaCount with --set flag",
dir: "testdata/helm-render-simple",
args: []string{"--set", "replicaCount=3"},
@@ -523,7 +501,8 @@ spec:
- image: skaffold-helm:latest
name: skaffold-helm
`,
}, {
},
{
description: "With Helm global flags",
dir: "testdata/helm-render",
args: []string{"-p", "helm-render-with-global-flags"},
@@ -573,7 +552,7 @@ spec:
skaffold.dev/run-id: phony-run-id
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/skaffold-helm:sha256-nonsenselettersandnumbers
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/skaffold-helm:latest
imagePullPolicy: always
name: skaffold-helm
ports:
@@ -1052,6 +1031,7 @@ spec:
apiVersion: v1
kind: Pod
metadata:
namespace: mynamespace
labels:
this-is-from: kustomization.yaml
name: my-pod-1
@@ -1995,6 +1975,133 @@ spec:
}
}

func TestRenderWithPostRenderHook(t *testing.T) {
MarkIntegrationTest(t, CanRunWithoutGcp)

tests := []struct {
description string
projectDir string
expectedOutput string
args []string
}{
{
description: "a single module project, one hook with change",
projectDir: "testdata/post-render-hooks",
args: []string{"-m", "m1", "-p", "change1", "-t", "customtag"},
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: module1
labels:
app1: after-change-1
app2: before-change-2

spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module1:customtag
name: module1
`,
},
{
description: "a single module project, two hook with change",
projectDir: "testdata/post-render-hooks",
args: []string{"-m", "m1", "-p", "two-changes", "-t", "customtag"},
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: module1
labels:
app1: after-change-1
app2: after-change-2
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module1:customtag
name: module1
`,
},
{
description: "a single module project, two hooks, one with change, one not",
projectDir: "testdata/post-render-hooks",
args: []string{"-m", "m1", "-p", "one-change-one-not", "-t", "customtag"},
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: module1
labels:
app1: before-change-1
app2: after-change-2
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module1:customtag
name: module1
`,
},
{
description: "multi-module project, two hooks, two changes",
projectDir: "testdata/post-render-hooks",
args: []string{"-m", "m1,m2", "-p", "change1", "-t", "customtag"},
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
labels:
app1: after-change-1
app2: before-change-2
name: module1
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module1:customtag
name: module1
---
apiVersion: v1
kind: Pod
metadata:
labels:
app1: before-change-1
name: module2
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module2:customtag
name: module2
`,
},
{
description: "multi-module project, one pipeline with two hooks have changes, one pipeline has no changes",
projectDir: "testdata/post-render-hooks",
args: []string{"-m", "m1,m2", "-p", "change1,nochange2", "-t", "customtag"},
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
labels:
app1: after-change-1
app2: before-change-2
name: module1
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module1:customtag
name: module1
---
apiVersion: v1
kind: Pod
metadata:
labels:
app1: before-change-1
name: module2
spec:
containers:
- image: us-central1-docker.pkg.dev/k8s-skaffold/testing/multi-config-module2:customtag
name: module2
`,
},
}

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))
})
}
}

func TestKptRender(t *testing.T) {
tests := []struct {
description string
13 changes: 13 additions & 0 deletions integration/testdata/post-render-hooks/module1/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang:1.18 as builder
WORKDIR /code
COPY main.go .
# `skaffold debug` sets SKAFFOLD_GO_GCFLAGS to disable compiler optimizations
ARG SKAFFOLD_GO_GCFLAGS
RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -trimpath -o /app main.go

FROM alpine:3
# Define GOTRACEBACK to mark this container as using the Go language runtime
# for `skaffold debug` (https://skaffold.dev/docs/workflows/debug/).
ENV GOTRACEBACK=single
CMD ["./app"]
COPY --from=builder /app .
11 changes: 11 additions & 0 deletions integration/testdata/post-render-hooks/module1/k8s/k8s-pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Pod
metadata:
name: module1
labels:
app1: before-change-1
app2: before-change-2
spec:
containers:
- name: module1
image: multi-config-module1
15 changes: 15 additions & 0 deletions integration/testdata/post-render-hooks/module1/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"fmt"
"runtime"
"time"
)

func main() {
for {
fmt.Printf("Hello module-1! Running on %s/%s\n", runtime.GOOS, runtime.GOARCH)

time.Sleep(time.Second * 1)
}
}
50 changes: 50 additions & 0 deletions integration/testdata/post-render-hooks/module1/skaffold.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: skaffold/v4beta9
kind: Config
metadata:
name: m1
build:
artifacts:
- image: multi-config-module1
context: .
manifests:
rawYaml:
- k8s/k8s-pod.yaml
deploy:
kubectl: {}
profiles:
- name: change1
manifests:
hooks:
after:
- host:
command:
- "sed"
- "s/before-change-1/after-change-1/g"
withChange: true
- name: two-changes
manifests:
hooks:
after:
- host:
command:
- "sed"
- "s/before-change-2/after-change-2/g"
withChange: true
- host:
command:
- "sed"
- "s/before-change-1/after-change-1/g"
withChange: true
- name: one-change-one-not
manifests:
hooks:
after:
- host:
command:
- "sed"
- "s/before-change-2/after-change-2/g"
withChange: true
- host:
command:
- "sed"
- "s/before-change-1/after-change-1/g"
13 changes: 13 additions & 0 deletions integration/testdata/post-render-hooks/module2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang:1.18 as builder
WORKDIR /code
COPY main.go .
# `skaffold debug` sets SKAFFOLD_GO_GCFLAGS to disable compiler optimizations
ARG SKAFFOLD_GO_GCFLAGS
RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -trimpath -o /app main.go

FROM alpine:3
# Define GOTRACEBACK to mark this container as using the Go language runtime
# for `skaffold debug` (https://skaffold.dev/docs/workflows/debug/).
ENV GOTRACEBACK=single
CMD ["./app"]
COPY --from=builder /app .
Loading