Skip to content

Commit

Permalink
Support static stack out of the box.
Browse files Browse the repository at this point in the history
- Add necessary flags/env for static linking.
  • Loading branch information
robdimsdale committed Oct 10, 2023
1 parent effb901 commit 2da89e8
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 19 deletions.
20 changes: 18 additions & 2 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import (
"github.com/paketo-buildpacks/packit/v2/scribe"
)

const (
// JammyStaticStackID is the ID for the Cloud Native Buildpacks jammy static stack.
JammyStaticStackID = "io.buildpacks.stacks.jammy.static"
)

//go:generate faux --interface BuildProcess --output fakes/build_process.go
type BuildProcess interface {
Execute(config GoBuildConfiguration) (binaries []string, err error)
Expand Down Expand Up @@ -70,14 +75,21 @@ func Build(
return packit.BuildResult{}, err
}

binaries, err := buildProcess.Execute(GoBuildConfiguration{
config := GoBuildConfiguration{
Workspace: path,
Output: filepath.Join(targetsLayer.Path, "bin"),
GoPath: goPath,
GoCache: goCacheLayer.Path,
Flags: configuration.Flags,
Targets: configuration.Targets,
})
}

if isStaticStack(context.Stack) && !containsFlag(config.Flags, "-buildmode") {
config.DisableCGO = true
config.Flags = append(config.Flags, "-buildmode", "default")
}

binaries, err := buildProcess.Execute(config)
if err != nil {
return packit.BuildResult{}, err
}
Expand Down Expand Up @@ -152,3 +164,7 @@ func Build(
}, nil
}
}

func isStaticStack(stack string) bool {
return stack == JammyStaticStackID
}
52 changes: 49 additions & 3 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,12 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
})
})

context("when the stack is tiny", func() {
it("marks the launch process as direct", func() {
context("when the stack is static", func() {
it("sets CGO_ENABLED=0 and -buildmode=default", func() {
result, err := build(packit.BuildContext{
WorkingDir: workingDir,
CNBPath: cnbDir,
Stack: "io.paketo.stacks.tiny",
Stack: "io.buildpacks.stacks.jammy.static",
BuildpackInfo: packit.BuildpackInfo{
Name: "Some Buildpack",
Version: "some-version",
Expand All @@ -295,6 +295,52 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
Direct: true,
},
}))

receivedConfig := buildProcess.ExecuteCall.Receives.Config

Expect(receivedConfig.DisableCGO).To(BeTrue())
Expect(receivedConfig.Flags).To(Equal([]string{"some-flag", "other-flag", "-buildmode", "default"}))
})

context("there is a pre-existing -buildmode flag", func() {
it.Before(func() {
parser.ParseCall.Returns.BuildConfiguration = gobuild.BuildConfiguration{
Flags: []string{"-buildmode", "some-provided-buildmode"},
}
})

it("does not set CGO_ENABLED=0 or -buildmode=default", func() {
result, err := build(packit.BuildContext{
WorkingDir: workingDir,
CNBPath: cnbDir,
Stack: "io.buildpacks.stacks.jammy.static",
BuildpackInfo: packit.BuildpackInfo{
Name: "Some Buildpack",
Version: "some-version",
},
Layers: packit.Layers{Path: layersDir},
})
Expect(err).NotTo(HaveOccurred())

Expect(result.Launch.Processes).To(Equal([]packit.Process{
{
Type: "some-start-command",
Command: "path/some-start-command",
Direct: true,
Default: true,
},
{
Type: "another-start-command",
Command: "path/another-start-command",
Direct: true,
},
}))

receivedConfig := buildProcess.ExecuteCall.Receives.Config

Expect(receivedConfig.DisableCGO).To(BeFalse())
Expect(receivedConfig.Flags).To(Equal([]string{"-buildmode", "some-provided-buildmode"}))
})
})
})

Expand Down
17 changes: 11 additions & 6 deletions go_build_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ type Executable interface {
}

type GoBuildConfiguration struct {
Workspace string
Output string
GoPath string
GoCache string
Targets []string
Flags []string
Workspace string
Output string
GoPath string
GoCache string
Targets []string
Flags []string
DisableCGO bool
}

type GoBuildProcess struct {
Expand Down Expand Up @@ -70,6 +71,10 @@ func (p GoBuildProcess) Execute(config GoBuildConfiguration) ([]string, error) {
}
env = append(env, "GO111MODULE=auto")

if config.DisableCGO {
env = append(env, "CGO_ENABLED=0")
}

printedArgs := []string{"go"}
for _, arg := range args {
printedArgs = append(printedArgs, formatArg(arg))
Expand Down
18 changes: 18 additions & 0 deletions go_build_process_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,24 @@ func testGoBuildProcess(t *testing.T, context spec.G, it spec.S) {
Expect(logs.String()).To(ContainSubstring(" Completed in 1s"))
})

it("propagates the disable cgo flag", func() {
binaries, err := buildProcess.Execute(gobuild.GoBuildConfiguration{
Workspace: workspacePath,
Output: filepath.Join(layerPath, "bin"),
GoPath: goPath,
GoCache: goCache,
Targets: []string{"./some-target"},
DisableCGO: true,
})
Expect(err).NotTo(HaveOccurred())

Expect(binaries).To(Equal([]string{
filepath.Join(layerPath, "bin", "some-target"),
}))

Expect(executable.ExecuteCall.Receives.Execution.Env).To(ContainElement("CGO_ENABLED=0"))
})

context("when there are build flags", func() {
it.Before(func() {
Expect(os.WriteFile(filepath.Join(workspacePath, "go.mod"), nil, 0644)).To(Succeed())
Expand Down
10 changes: 8 additions & 2 deletions integration.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@
"go-dist": "github.com/paketo-buildpacks/go-dist",
"watchexec": "github.com/paketo-buildpacks/watchexec",
"tiny-builder": "paketobuildpacks/builder-jammy-buildpackless-tiny",
"tiny-run-image": "index.docker.io/paketobuildpacks/run-jammy-tiny"
}
"tiny-run-image": "index.docker.io/paketobuildpacks/run-jammy-tiny",
"builders": [
"paketobuildpacks/builder-jammy-buildpackless-static",
"paketobuildpacks/builder-jammy-buildpackless-tiny",
"paketobuildpacks/builder-jammy-buildpackless-base",
"paketobuildpacks/builder-jammy-buildpackless-full"
]
}
2 changes: 1 addition & 1 deletion integration/build_failure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func testBuildFailure(t *testing.T, context spec.G, it spec.S) {
Expect(logs).To(ContainLines(
MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)),
" Executing build process",
fmt.Sprintf(" Running 'go build -o /layers/%s/targets/bin -buildmode pie -trimpath .'", strings.ReplaceAll(settings.Buildpack.ID, "/", "_")),
MatchRegexp(fmt.Sprintf(`Running 'go build -o /layers/%s/targets/bin -buildmode ([^\s]+) -trimpath .'`, strings.ReplaceAll(settings.Buildpack.ID, "/", "_"))),
))
Expect(logs).To(ContainLines(
MatchRegexp(` Failed after ([0-9]*(\.[0-9]*)?[a-z]+)+`),
Expand Down
11 changes: 7 additions & 4 deletions integration/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,20 @@ func testDefault(t *testing.T, context spec.G, it spec.S) {
Expect(logs).To(ContainLines(
MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)),
" Executing build process",
fmt.Sprintf(" Running 'go build -o /layers/%s/targets/bin -buildmode pie -trimpath .'", strings.ReplaceAll(settings.Buildpack.ID, "/", "_")),
MatchRegexp(fmt.Sprintf(`Running 'go build -o /layers/%s/targets/bin -buildmode ([^\s]+) -trimpath .'`, strings.ReplaceAll(settings.Buildpack.ID, "/", "_"))),
MatchRegexp(` Completed in ([0-9]*(\.[0-9]*)?[a-z]+)+`),
"",
))
Expect(logs).To(ContainLines(
fmt.Sprintf(" Generating SBOM for /layers/%s/targets/bin", strings.ReplaceAll(settings.Buildpack.ID, "/", "_")),
MatchRegexp(` Completed in ([0-9]*(\.[0-9]*)?[a-z]+)+`),
"",
))
Expect(logs).To(ContainLines(
" Writing SBOM in the following format(s):",
" application/vnd.cyclonedx+json",
" application/spdx+json",
" application/vnd.syft+json",
"",
))
Expect(logs).To(ContainLines(
" Assigning launch processes:",
fmt.Sprintf(" workspace (default): /layers/%s/targets/bin/workspace", strings.ReplaceAll(settings.Buildpack.ID, "/", "_")),
))
Expand Down
11 changes: 10 additions & 1 deletion integration/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
. "github.com/onsi/gomega"
)

var builder occam.Builder

var settings struct {
Buildpacks struct {
GoDist struct {
Expand Down Expand Up @@ -46,7 +48,9 @@ var settings struct {

func TestIntegration(t *testing.T) {
format.MaxLength = 0

Expect := NewWithT(t).Expect
pack := occam.NewPack()

file, err := os.Open("../integration.json")
Expect(err).NotTo(HaveOccurred())
Expand Down Expand Up @@ -107,17 +111,22 @@ func TestIntegration(t *testing.T) {
err = docker.Pull.Execute(settings.Config.TinyRunImage)
Expect(err).ToNot(HaveOccurred())

builder, err = pack.Builder.Inspect.Execute()
Expect(err).NotTo(HaveOccurred())

SetDefaultEventuallyTimeout(10 * time.Second)

suite := spec.New("Integration", spec.Report(report.Terminal{}), spec.Parallel())
suite("BuildFailure", testBuildFailure)
suite("BuildFlags", testBuildFlags)
suite("Default", testDefault)
suite("ImportPath", testImportPath)
suite("KeepFiles", testKeepFiles)
suite("Mod", testMod)
suite("Rebuild", testRebuild)
suite("Targets", testTargets)
suite("Vendor", testVendor)
if builder.BuilderName != "paketobuildpacks/builder-jammy-buildpackless-static" {
suite("BuildFlags", testBuildFlags)
}
suite.Run(t)
}

0 comments on commit 2da89e8

Please sign in to comment.