From d5fec1fa5442df341baf9129dcd56288e14b01e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Wed, 21 Aug 2024 16:04:54 +0200 Subject: [PATCH 1/8] Prepare util image to accomodate multiple cmds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As of now func-util image has only one command of our own -- "deploy". This commits prepares grounds for one additional command named "scaffolding". The commands will be implemented in one binary and dispatched over argv[0] using symlinks. Kinda like busybox does. Signed-off-by: Matej Vašek --- Dockerfile.utils | 5 +++-- cmd/{func-deployer => func-util}/main.go | 14 +++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) rename cmd/{func-deployer => func-util}/main.go (89%) diff --git a/Dockerfile.utils b/Dockerfile.utils index 0ccad03c9..31a83ec19 100644 --- a/Dockerfile.utils +++ b/Dockerfile.utils @@ -6,7 +6,7 @@ ARG TARGETARCH COPY . . -RUN GOARCH=$TARGETARCH go build -o deploy -trimpath -ldflags '-w -s' ./cmd/func-deployer +RUN GOARCH=$TARGETARCH go build -o func-util -trimpath -ldflags '-w -s' ./cmd/func-util ######################### @@ -16,7 +16,8 @@ RUN apk add --no-cache socat tar \ && addgroup func -g 1000 \ && adduser func -u 1001 -D -G func -COPY --from=builder /go/deploy /usr/local/bin/ +COPY --from=builder /go/func-util /usr/local/bin/ +RUN ln -s /usr/local/bin/func-util /usr/local/bin/deploy LABEL \ org.opencontainers.image.description="Knative Func Utils Image" \ diff --git a/cmd/func-deployer/main.go b/cmd/func-util/main.go similarity index 89% rename from cmd/func-deployer/main.go rename to cmd/func-util/main.go index 0ad583c19..27451aaed 100644 --- a/cmd/func-deployer/main.go +++ b/cmd/func-util/main.go @@ -25,12 +25,24 @@ func main() { os.Exit(137) }() - err := deploy(ctx) + var cmd func(context.Context) error = unknown + + switch os.Args[0] { + case "deploy": + cmd = deploy + } + + err := cmd(ctx) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) os.Exit(1) } } + +func unknown(_ context.Context) error { + return fmt.Errorf("unknown command: " + os.Args[0]) +} + func deploy(ctx context.Context) error { var err error deployer := knative.NewDeployer( From 91fd4c166542b30abbd2f061c289605aef774a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Sun, 25 Aug 2024 23:56:43 +0200 Subject: [PATCH 2/8] Add scaffolding for on-cluster build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added new build step in tekton pipeline that scaffolds main() for Go porject when using s2i builder. Signed-off-by: Matej Vašek --- Dockerfile.utils | 3 +- cmd/func-util/main.go | 47 +++++++++++++++++++++++++ pkg/pipelines/tekton/tasks.go | 29 +++++++++++++-- pkg/pipelines/tekton/templates.go | 3 ++ pkg/pipelines/tekton/templates_pack.go | 12 ++++++- pkg/pipelines/tekton/templates_s2i.go | 12 ++++++- test/oncluster/scenario_runtime_test.go | 2 +- 7 files changed, 102 insertions(+), 6 deletions(-) diff --git a/Dockerfile.utils b/Dockerfile.utils index 31a83ec19..3e12e176e 100644 --- a/Dockerfile.utils +++ b/Dockerfile.utils @@ -17,7 +17,8 @@ RUN apk add --no-cache socat tar \ && adduser func -u 1001 -D -G func COPY --from=builder /go/func-util /usr/local/bin/ -RUN ln -s /usr/local/bin/func-util /usr/local/bin/deploy +RUN ln -s /usr/local/bin/func-util /usr/local/bin/deploy && \ + ln -s /usr/local/bin/func-util /usr/local/bin/scaffold LABEL \ org.opencontainers.image.description="Knative Func Utils Image" \ diff --git a/cmd/func-util/main.go b/cmd/func-util/main.go index 27451aaed..aca930d8e 100644 --- a/cmd/func-util/main.go +++ b/cmd/func-util/main.go @@ -5,11 +5,14 @@ import ( "fmt" "os" "os/signal" + "path/filepath" "syscall" + "knative.dev/func/pkg/builders/s2i" fn "knative.dev/func/pkg/functions" "knative.dev/func/pkg/k8s" "knative.dev/func/pkg/knative" + "knative.dev/func/pkg/scaffolding" ) func main() { @@ -30,6 +33,8 @@ func main() { switch os.Args[0] { case "deploy": cmd = deploy + case "scaffold": + cmd = scaffold } err := cmd(ctx) @@ -43,6 +48,48 @@ func unknown(_ context.Context) error { return fmt.Errorf("unknown command: " + os.Args[0]) } +func scaffold(ctx context.Context) error { + + if len(os.Args) != 2 { + return fmt.Errorf("expected exactly one positional argument (function project path)") + } + + path := os.Args[1] + + f, err := fn.NewFunction(path) + if err != nil { + return fmt.Errorf("cannot load func project: %w", err) + } + + if f.Runtime != "go" || f.Build.Builder != "s2i" { + // Scaffolding is for now supported/needed only for Go S2I build. + return nil + } + + embeddedRepo, err := fn.NewRepository("", "") + if err != nil { + return fmt.Errorf("cannot initialize repository: %w", err) + } + + appRoot := filepath.Join(f.Root, ".s2i", "builds", "last") + _ = os.RemoveAll(appRoot) + + err = scaffolding.Write(appRoot, f.Root, f.Runtime, f.Invoke, embeddedRepo.FS()) + if err != nil { + return fmt.Errorf("cannot write the scaffolding: %w", err) + } + + if err := os.MkdirAll(filepath.Join(f.Root, ".s2i", "bin"), 0755); err != nil { + return fmt.Errorf("unable to create .s2i bin dir. %w", err) + } + + if err := os.WriteFile(filepath.Join(f.Root, ".s2i", "bin", "assemble"), []byte(s2i.GoAssembler), 0700); err != nil { + return fmt.Errorf("unable to write go assembler. %w", err) + } + + return nil +} + func deploy(ctx context.Context) error { var err error deployer := knative.NewDeployer( diff --git a/pkg/pipelines/tekton/tasks.go b/pkg/pipelines/tekton/tasks.go index 239ddec25..8251742ac 100644 --- a/pkg/pipelines/tekton/tasks.go +++ b/pkg/pipelines/tekton/tasks.go @@ -321,7 +321,7 @@ spec: cat /env-vars/env-file echo "------------------------------" - /usr/local/bin/s2i --loglevel=$(params.LOGLEVEL) build $(params.PATH_CONTEXT) $(params.BUILDER_IMAGE) \ + /usr/local/bin/s2i --loglevel=$(params.LOGLEVEL) build --keep-symlinks $(params.PATH_CONTEXT) $(params.BUILDER_IMAGE) \ --image-scripts-url $(params.S2I_IMAGE_SCRIPTS_URL) \ --as-dockerfile /gen-source/Dockerfile.gen --environment-file /env-vars/env-file @@ -413,9 +413,34 @@ spec: `, DeployerImage) } +func getScaffoldTask() string { + return fmt.Sprintf(`apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: func-scaffold + labels: + app.kubernetes.io/version: "0.1" + annotations: + tekton.dev/pipelines.minVersion: "0.12.1" + tekton.dev/categories: CLI + tekton.dev/tags: cli + tekton.dev/platforms: "linux/amd64" +spec: + params: + - name: path + description: Path to the function project + default: "" + steps: + - name: func-scaffold + image: %s + script: | + scaffold $(params.path) +`, DeployerImage) +} + // GetClusterTasks returns multi-document yaml containing tekton tasks used by func. func GetClusterTasks() string { - tasks := getBuildpackTask() + "\n---\n" + getS2ITask() + "\n---\n" + getDeployTask() + tasks := getBuildpackTask() + "\n---\n" + getS2ITask() + "\n---\n" + getDeployTask() + "\n---\n" + getScaffoldTask() tasks = strings.Replace(tasks, "kind: Task", "kind: ClusterTask", -1) tasks = strings.ReplaceAll(tasks, "apiVersion: tekton.dev/v1", "apiVersion: tekton.dev/v1beta1") return tasks diff --git a/pkg/pipelines/tekton/templates.go b/pkg/pipelines/tekton/templates.go index 41d6b112e..2471243ae 100644 --- a/pkg/pipelines/tekton/templates.go +++ b/pkg/pipelines/tekton/templates.go @@ -99,6 +99,7 @@ type templateData struct { FuncBuildpacksTaskRef string FuncS2iTaskRef string FuncDeployTaskRef string + FuncScaffoldTaskRef string // Reference for build task - whether it should run after fetch-sources task or not RunAfterFetchSources string @@ -128,6 +129,7 @@ func createPipelineTemplatePAC(f fn.Function, labels map[string]string) error { {getBuildpackTask(), &data.FuncBuildpacksTaskRef}, {getS2ITask(), &data.FuncS2iTaskRef}, {getDeployTask(), &data.FuncDeployTaskRef}, + {getScaffoldTask(), &data.FuncScaffoldTaskRef}, } { ts, err := getTaskSpec(val.ref) if err != nil { @@ -327,6 +329,7 @@ func createAndApplyPipelineTemplate(f fn.Function, namespace string, labels map[ {getBuildpackTask(), &data.FuncBuildpacksTaskRef}, {getS2ITask(), &data.FuncS2iTaskRef}, {getDeployTask(), &data.FuncDeployTaskRef}, + {getScaffoldTask(), &data.FuncScaffoldTaskRef}, } { ts, err := getTaskSpec(val.ref) if err != nil { diff --git a/pkg/pipelines/tekton/templates_pack.go b/pkg/pipelines/tekton/templates_pack.go index 88a2d76c4..52f2612a6 100644 --- a/pkg/pipelines/tekton/templates_pack.go +++ b/pkg/pipelines/tekton/templates_pack.go @@ -42,6 +42,15 @@ spec: type: array tasks: {{.GitCloneTaskRef}} + - name: scaffold + params: + - name: path + value: $(workspaces.source.path)/$(params.contextDir) + workspaces: + - name: source + workspace: source-workspace + {{.RunAfterFetchSources}} + {{.FuncScaffoldTaskRef}} - name: build params: - name: APP_IMAGE @@ -55,7 +64,8 @@ spec: - name: ENV_VARS value: - '$(params.buildEnvs[*])' - {{.RunAfterFetchSources}} + runAfter: + - scaffold {{.FuncBuildpacksTaskRef}} workspaces: - name: source diff --git a/pkg/pipelines/tekton/templates_s2i.go b/pkg/pipelines/tekton/templates_s2i.go index b78fc47a9..a78658774 100644 --- a/pkg/pipelines/tekton/templates_s2i.go +++ b/pkg/pipelines/tekton/templates_s2i.go @@ -46,6 +46,15 @@ spec: default: 'image:///usr/libexec/s2i' tasks: {{.GitCloneTaskRef}} + - name: scaffold + params: + - name: path + value: $(workspaces.source.path)/$(params.contextDir) + workspaces: + - name: source + workspace: source-workspace + {{.RunAfterFetchSources}} + {{.FuncScaffoldTaskRef}} - name: build params: - name: IMAGE @@ -61,7 +70,8 @@ spec: - '$(params.buildEnvs[*])' - name: S2I_IMAGE_SCRIPTS_URL value: $(params.s2iImageScriptsUrl) - {{.RunAfterFetchSources}} + runAfter: + - scaffold {{.FuncS2iTaskRef}} workspaces: - name: source diff --git a/test/oncluster/scenario_runtime_test.go b/test/oncluster/scenario_runtime_test.go index c783f9d7a..615d116ce 100644 --- a/test/oncluster/scenario_runtime_test.go +++ b/test/oncluster/scenario_runtime_test.go @@ -15,7 +15,7 @@ import ( var runtimeSupportMap = map[string][]string{ "node": {"pack", "s2i"}, - "go": {"pack"}, + "go": {"pack", "s2i"}, "rust": {"pack"}, "python": {"pack", "s2i"}, "quarkus": {"pack", "s2i"}, From e892963ef8da8ebe7293b16cf6f6c9fa3f21a63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Mon, 26 Aug 2024 00:44:32 +0200 Subject: [PATCH 3/8] Better docker build caching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will cache dependencies between docker builds. Signed-off-by: Matej Vašek --- Dockerfile.utils | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Dockerfile.utils b/Dockerfile.utils index 3e12e176e..ce3d44b87 100644 --- a/Dockerfile.utils +++ b/Dockerfile.utils @@ -4,6 +4,11 @@ ARG BUILDPLATFORM ARG TARGETPLATFORM ARG TARGETARCH +WORKDIR /workspace + +COPY go.mod go.sum ./ +RUN go mod download -x + COPY . . RUN GOARCH=$TARGETARCH go build -o func-util -trimpath -ldflags '-w -s' ./cmd/func-util @@ -16,7 +21,7 @@ RUN apk add --no-cache socat tar \ && addgroup func -g 1000 \ && adduser func -u 1001 -D -G func -COPY --from=builder /go/func-util /usr/local/bin/ +COPY --from=builder /workspace/func-util /usr/local/bin/ RUN ln -s /usr/local/bin/func-util /usr/local/bin/deploy && \ ln -s /usr/local/bin/func-util /usr/local/bin/scaffold From 942dec9999652e12c6726d74da383569d53b7e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Tue, 27 Aug 2024 14:57:19 +0200 Subject: [PATCH 4/8] fixup: perms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Vašek --- cmd/func-util/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/func-util/main.go b/cmd/func-util/main.go index aca930d8e..b2fae5dc2 100644 --- a/cmd/func-util/main.go +++ b/cmd/func-util/main.go @@ -83,7 +83,7 @@ func scaffold(ctx context.Context) error { return fmt.Errorf("unable to create .s2i bin dir. %w", err) } - if err := os.WriteFile(filepath.Join(f.Root, ".s2i", "bin", "assemble"), []byte(s2i.GoAssembler), 0700); err != nil { + if err := os.WriteFile(filepath.Join(f.Root, ".s2i", "bin", "assemble"), []byte(s2i.GoAssembler), 0755); err != nil { return fmt.Errorf("unable to write go assembler. %w", err) } From 69360dbd099baef868b4bf7e992026718782c5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Tue, 27 Aug 2024 16:05:04 +0200 Subject: [PATCH 5/8] fixup: remove broken check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Vašek --- cmd/func-util/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/func-util/main.go b/cmd/func-util/main.go index b2fae5dc2..9d868137c 100644 --- a/cmd/func-util/main.go +++ b/cmd/func-util/main.go @@ -61,8 +61,8 @@ func scaffold(ctx context.Context) error { return fmt.Errorf("cannot load func project: %w", err) } - if f.Runtime != "go" || f.Build.Builder != "s2i" { - // Scaffolding is for now supported/needed only for Go S2I build. + if f.Runtime != "go" { + // Scaffolding is for now supported/needed only for Go. return nil } From c55a77642d55b93a84e31cccd6409a81d2dd94ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Tue, 27 Aug 2024 16:51:56 +0200 Subject: [PATCH 6/8] fixup: remove test because of 'no space left on device' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Vašek --- test/oncluster/scenario_runtime_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/oncluster/scenario_runtime_test.go b/test/oncluster/scenario_runtime_test.go index 615d116ce..c783f9d7a 100644 --- a/test/oncluster/scenario_runtime_test.go +++ b/test/oncluster/scenario_runtime_test.go @@ -15,7 +15,7 @@ import ( var runtimeSupportMap = map[string][]string{ "node": {"pack", "s2i"}, - "go": {"pack", "s2i"}, + "go": {"pack"}, "rust": {"pack"}, "python": {"pack", "s2i"}, "quarkus": {"pack", "s2i"}, From 7f2ee94f9253ce85c63f04b7a3048d2429f279c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Tue, 27 Aug 2024 14:51:38 +0200 Subject: [PATCH 7/8] Updated git-clone task --- pkg/pipelines/tekton/tasks.go | 6 ++++-- pkg/pipelines/tekton/templates.go | 2 +- pkg/pipelines/tekton/templates_pack.go | 3 +++ pkg/pipelines/tekton/templates_s2i.go | 3 +++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pkg/pipelines/tekton/tasks.go b/pkg/pipelines/tekton/tasks.go index 8251742ac..9cb4ab686 100644 --- a/pkg/pipelines/tekton/tasks.go +++ b/pkg/pipelines/tekton/tasks.go @@ -66,7 +66,7 @@ spec: default: "1001" - name: GROUP_ID description: The group ID of the builder image user. - default: "0" + default: "65532" ############################################################## ##### "default" has been changed to "0" for Knative Functions - name: PLATFORM_DIR @@ -108,6 +108,8 @@ spec: fi done + chmod -R g+w "$(workspaces.source.path)" + echo "> Parsing additional configuration..." parsing_flag="" envs=() @@ -187,7 +189,7 @@ spec: runAsUser: 1001 ################################################################# ##### "runAsGroup" has been changed to "0" for Knative Functions - runAsGroup: 0 + runAsGroup: 65532 - name: results image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6 diff --git a/pkg/pipelines/tekton/templates.go b/pkg/pipelines/tekton/templates.go index 2471243ae..0ced18214 100644 --- a/pkg/pipelines/tekton/templates.go +++ b/pkg/pipelines/tekton/templates.go @@ -57,7 +57,7 @@ const ( - name: name value: git-clone - name: version - value: "0.4" + value: "0.9" workspaces: - name: output workspace: source-workspace` diff --git a/pkg/pipelines/tekton/templates_pack.go b/pkg/pipelines/tekton/templates_pack.go index 52f2612a6..c9210789f 100644 --- a/pkg/pipelines/tekton/templates_pack.go +++ b/pkg/pipelines/tekton/templates_pack.go @@ -113,6 +113,9 @@ metadata: {{end}} generateName: {{.PipelineRunName}} spec: + podTemplate: + securityContext: + fsGroup: 65532 params: - name: gitRepository value: {{.RepoUrl}} diff --git a/pkg/pipelines/tekton/templates_s2i.go b/pkg/pipelines/tekton/templates_s2i.go index a78658774..66e7a451a 100644 --- a/pkg/pipelines/tekton/templates_s2i.go +++ b/pkg/pipelines/tekton/templates_s2i.go @@ -118,6 +118,9 @@ metadata: {{end}} generateName: {{.PipelineRunName}} spec: + podTemplate: + securityContext: + fsGroup: 65532 params: - name: gitRepository value: {{.RepoUrl}} From 57d5371752ec6b9c365bf467aa7b8b644196eb75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Tue, 27 Aug 2024 22:42:08 +0200 Subject: [PATCH 8/8] fixup: uid/gid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Vašek --- Dockerfile.utils | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.utils b/Dockerfile.utils index ce3d44b87..e7b0a26fe 100644 --- a/Dockerfile.utils +++ b/Dockerfile.utils @@ -18,8 +18,8 @@ RUN GOARCH=$TARGETARCH go build -o func-util -trimpath -ldflags '-w -s' ./cmd/fu FROM --platform=$TARGETPLATFORM index.docker.io/library/alpine:latest RUN apk add --no-cache socat tar \ - && addgroup func -g 1000 \ - && adduser func -u 1001 -D -G func + && addgroup func -g 65532 \ + && adduser func -u 65532 -D -G func COPY --from=builder /workspace/func-util /usr/local/bin/ RUN ln -s /usr/local/bin/func-util /usr/local/bin/deploy && \