Skip to content
Draft
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
32 changes: 27 additions & 5 deletions cmd/func-util/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,31 @@ func socat(ctx context.Context) error {
}

func scaffold(ctx context.Context) error {

if len(os.Args) != 2 {
return fmt.Errorf("expected exactly one positional argument (function project path)")
if len(os.Args) != 3 {
return fmt.Errorf("expected exactly two positional arguments (function project path, builder)")
}

path := os.Args[1]
builder := os.Args[2]

f, err := fn.NewFunction(path)
if err != nil {
return fmt.Errorf("cannot load func project: %w", err)
}

// TODO: gauron99 - Set the builder from the passed argument if not already set in the function config.
// This is necessary because the builder value needs to be known during scaffolding to
// determine the correct build directory (.s2i/builds/last vs .func/builds/last), but it
// may not be persisted to func.yaml yet. By passing it as an argument from the Tekton
// pipeline, we ensure the correct builder is used even when the function config is incomplete.
if f.Build.Builder == "" {
f.Build.Builder = builder
}

fmt.Printf("#### scaffold: builder='%s', runtime='%s'\n", f.Build.Builder, f.Runtime)

if f.Runtime != "go" && f.Runtime != "python" {
// Scaffolding is for now supported/needed only for Go.
// Scaffolding is for now supported/needed only for Go&Python
return nil
}

Expand All @@ -97,13 +108,25 @@ func scaffold(ctx context.Context) error {
}

appRoot := filepath.Join(f.Root, ".s2i", "builds", "last")
if f.Build.Builder != "s2i" {
// TODO: gauron99 - change this completely
appRoot = filepath.Join(f.Root, ".func", "builds", "last")
}
fmt.Printf("appRoot is '%s'\n", appRoot)
_ = os.RemoveAll(appRoot)

// build step now includes scaffolding for go-pack
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 f.Build.Builder != "s2i" {
return nil
}

// add s2i specific changes

if err := os.MkdirAll(filepath.Join(f.Root, ".s2i", "bin"), 0755); err != nil {
return fmt.Errorf("unable to create .s2i bin dir. %w", err)
}
Expand All @@ -121,7 +144,6 @@ func scaffold(ctx context.Context) error {
if err := os.WriteFile(filepath.Join(f.Root, ".s2i", "bin", "assemble"), []byte(asm), 0755); err != nil {
return fmt.Errorf("unable to write go assembler. %w", err)
}

return nil
}

Expand Down
49 changes: 46 additions & 3 deletions pkg/builders/buildpacks/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ import (
"knative.dev/func/pkg/builders"
"knative.dev/func/pkg/docker"
fn "knative.dev/func/pkg/functions"
"knative.dev/func/pkg/scaffolding"
)

// DefaultName when no WithName option is provided to NewBuilder
const DefaultName = builders.Pack

var DefaultBaseBuilder = "ghcr.io/knative/builder-jammy-base:latest"
var DefaultTinyBuilder = "ghcr.io/knative/builder-jammy-tiny:latest"
var DefaultBaseBuilder = "ghcr.io/knative/builder-jammy-base:v2"
var DefaultTinyBuilder = "ghcr.io/knative/builder-jammy-tiny:v2"

var (
DefaultBuilderImages = map[string]string{
Expand Down Expand Up @@ -116,7 +117,7 @@ func WithTimestamp(v bool) Option {
}
}

var DefaultLifecycleImage = "docker.io/buildpacksio/lifecycle:553c041"
var DefaultLifecycleImage = "docker.io/buildpacksio/lifecycle:3659764"

// Build the Function at path.
func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platform) (err error) {
Expand Down Expand Up @@ -171,6 +172,12 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
Volumes []string
}{Network: "", Volumes: nil},
}

// TODO: gauron99 this will be extracted into separate client.Scaffold method
if err = scaffold(f); err != nil {
return
}

if b.withTimestamp {
now := time.Now()
opts.CreationTime = &now
Expand All @@ -186,6 +193,12 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
opts.Env["BPE_DEFAULT_LISTEN_ADDRESS"] = "[::]:8080"
}

// go specific workdir set to directory of main
if f.Runtime == "go" {
if _, ok := opts.Env["BP_GO_WORKDIR"]; !ok {
opts.Env["BP_GO_WORKDIR"] = ".func/builds/last"
}
}
var bindings = make([]string, 0, len(f.Build.Mounts))
for _, m := range f.Build.Mounts {
bindings = append(bindings, fmt.Sprintf("%s:%s", m.Source, m.Destination))
Expand Down Expand Up @@ -312,3 +325,33 @@ type ErrRuntimeNotSupported struct {
func (e ErrRuntimeNotSupported) Error() string {
return fmt.Sprintf("Pack builder has no default builder image for the '%v' language runtime. Please provide one.", e.Runtime)
}

// TODO: gauron99 - unify this with other builders
// This is temporary for the go pack
//
// scaffold the project
func scaffold(f fn.Function) error {
// Scaffolding is currently only supported by the Go runtime
// Python currently uses an injector instead of this
if f.Runtime != "go" {
return nil
}

contextDir := filepath.Join(".func", "builds", "last")
appRoot := filepath.Join(f.Root, contextDir)
_ = os.RemoveAll(appRoot)

// The embedded repository contains the scaffolding code itself which glues
// together the middleware and a function via main
embeddedRepo, err := fn.NewRepository("", "") // default is the embedded fs
if err != nil {
return fmt.Errorf("unable to load the embedded scaffolding. %w", err)
}

// Write scaffolding to .func/builds/last
err = scaffolding.Write(appRoot, f.Root, f.Runtime, f.Invoke, embeddedRepo.FS())
if err != nil {
return fmt.Errorf("unable to build due to a scaffold error. %w", err)
}
return nil
}
4 changes: 1 addition & 3 deletions pkg/builders/buildpacks/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestBuild_BuilderImageTrustedLocalhost(t *testing.T) {
}
}

// TestBuild_BuilderImageDefault ensures that a Function bing built which does not
// TestBuild_BuilderImageDefault ensures that a Function being built which does not
// define a Builder Image will get the internally-defined default.
func TestBuild_BuilderImageDefault(t *testing.T) {
var (
Expand All @@ -76,7 +76,6 @@ func TestBuild_BuilderImageDefault(t *testing.T) {
if err := b.Build(context.Background(), f, nil); err != nil {
t.Fatal(err)
}

}

// TestBuild_BuildpacksDefault ensures that, if there are default buildpacks
Expand All @@ -100,7 +99,6 @@ func TestBuild_BuildpacksDefault(t *testing.T) {
if err := b.Build(context.Background(), f, nil); err != nil {
t.Fatal(err)
}

}

// TestBuild_BuilderImageConfigurable ensures that the builder will use the builder
Expand Down
5 changes: 4 additions & 1 deletion pkg/pipelines/tekton/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,13 +440,16 @@ spec:
- name: path
description: Path to the function project
default: ""
- name: builder
description: Builder to be used (pack or s2i)
default: ""
workspaces:
- name: source
description: The workspace containing the function project
steps:
- name: func-scaffold
image: %s
command: ["scaffold", "$(params.path)"]
command: ["scaffold", "$(params.path)", "$(params.builder)"]
`, ScaffoldImage)
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/pipelines/tekton/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,11 @@ func createAndApplyPipelineRunTemplate(f fn.Function, namespace string, labels m
}
}

// add BP_GO_WORKDIR for go-build buildpack
if f.Runtime == "go" {
buildEnvs = append(buildEnvs, "BP_GO_WORKDIR=.func/builds/last")
}

s2iImageScriptsUrl := defaultS2iImageScriptsUrl
if f.Runtime == "quarkus" {
s2iImageScriptsUrl = quarkusS2iImageScriptsUrl
Expand Down
2 changes: 2 additions & 0 deletions pkg/pipelines/tekton/templates_pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ spec:
params:
- name: path
value: $(workspaces.source.path)/$(params.contextDir)
- name: builder
value: pack
workspaces:
- name: source
workspace: source-workspace
Expand Down
2 changes: 2 additions & 0 deletions pkg/pipelines/tekton/templates_s2i.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ spec:
params:
- name: path
value: $(workspaces.source.path)/$(params.contextDir)
- name: builder
value: s2i
workspaces:
- name: source
workspace: source-workspace
Expand Down
2 changes: 1 addition & 1 deletion pkg/scaffolding/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
// fs: filesytem which contains scaffolding at '[runtime]/scaffolding'
// (exclusive with 'repo')
func Write(out, src, runtime, invoke string, fs filesystem.Filesystem) (err error) {

fmt.Println("#### scaffolding.Write")
// detect the signature of the source code in the given location, presuming
// a runtime and invocation hint (default "http")
s, err := detectSignature(src, runtime, invoke)
Expand Down
Loading