Skip to content

Commit

Permalink
On cluster s2i build for Go (alternative version) (#2471)
Browse files Browse the repository at this point in the history
* Prepare util image to accomodate multiple cmds

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 <[email protected]>

* Add scaffolding for on-cluster build

Added new build step in tekton pipeline that scaffolds main() for Go
porject when using s2i builder.

Signed-off-by: Matej Vašek <[email protected]>

* Better docker build caching

This will cache dependencies between docker builds.

Signed-off-by: Matej Vašek <[email protected]>

* fixup: perms

Signed-off-by: Matej Vašek <[email protected]>

* fixup: remove broken check

Signed-off-by: Matej Vašek <[email protected]>

* fixup: remove test because of 'no space left on device'

Signed-off-by: Matej Vašek <[email protected]>

* Make func-util rootfull

Signed-off-by: Matej Vašek <[email protected]>

---------

Signed-off-by: Matej Vašek <[email protected]>
  • Loading branch information
matejvasek committed Sep 3, 2024
1 parent 82d0653 commit 2e4d157
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 11 deletions.
17 changes: 11 additions & 6 deletions Dockerfile.utils
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,29 @@ 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 deploy -trimpath -ldflags '-w -s' ./cmd/func-deployer
RUN GOARCH=$TARGETARCH go build -o func-util -trimpath -ldflags '-w -s' ./cmd/func-util

#########################

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
RUN apk add --no-cache socat tar

COPY --from=builder /go/deploy /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

LABEL \
org.opencontainers.image.description="Knative Func Utils Image" \
org.opencontainers.image.source="https://github.com/knative/func" \
org.opencontainers.image.vendor="https://github.com/knative/func" \
org.opencontainers.image.url="https://github.com/knative/func/pkgs/container/func-utils"

USER func:func
USER 0:0
61 changes: 60 additions & 1 deletion cmd/func-deployer/main.go → cmd/func-util/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -25,12 +28,68 @@ func main() {
os.Exit(137)
}()

err := deploy(ctx)
var cmd func(context.Context) error = unknown

switch os.Args[0] {
case "deploy":
cmd = deploy
case "scaffold":
cmd = scaffold
}

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 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" {
// Scaffolding is for now supported/needed only for Go.
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), 0755); 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(
Expand Down
29 changes: 27 additions & 2 deletions pkg/pipelines/tekton/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions pkg/pipelines/tekton/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 11 additions & 1 deletion pkg/pipelines/tekton/templates_pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -55,7 +64,8 @@ spec:
- name: ENV_VARS
value:
- '$(params.buildEnvs[*])'
{{.RunAfterFetchSources}}
runAfter:
- scaffold
{{.FuncBuildpacksTaskRef}}
workspaces:
- name: source
Expand Down
12 changes: 11 additions & 1 deletion pkg/pipelines/tekton/templates_s2i.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -61,7 +70,8 @@ spec:
- '$(params.buildEnvs[*])'
- name: S2I_IMAGE_SCRIPTS_URL
value: $(params.s2iImageScriptsUrl)
{{.RunAfterFetchSources}}
runAfter:
- scaffold
{{.FuncS2iTaskRef}}
workspaces:
- name: source
Expand Down

0 comments on commit 2e4d157

Please sign in to comment.