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

(updated with latest main) Allow setting environment variables using the build image #962

Merged
merged 4 commits into from
Nov 22, 2022
Merged
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*~
.tool-versions
/out

.vscode
acceptance/testdata/*/**/container/cnb/lifecycle/*
acceptance/testdata/*/**/container/docker-config/*
acceptance/testdata/exporter/container/layers/*analyzed.toml
Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,3 @@ docker-run-windows:
docker run -v lifecycle-out:c:/lifecycle/out -e LIFECYCLE_VERSION -e PLATFORM_API -e BUILDPACK_API -v gopathcache:c:/gopath -v '\\.\pipe\docker_engine:\\.\pipe\docker_engine' --isolation=process --interactive --tty --rm $(SOURCE_COMPILATION_IMAGE) $(DOCKER_CMD)
docker run -v lifecycle-out:c:/lifecycle/out --rm $(SOURCE_COMPILATION_IMAGE) tar -cf- out | tar -xf-
@docker volume rm -f lifecycle-out

59 changes: 22 additions & 37 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,22 @@ type Platform interface {
type BuildEnv interface {
AddRootDir(baseDir string) error
AddEnvDir(envDir string, defaultAction env.ActionType) error
WithPlatform(platformDir string) ([]string, error)
WithOverrides(platformDir string, baseConfigDir string) ([]string, error)
List() []string
}

type Builder struct {
AppDir string
LayersDir string
PlatformDir string
BuildExecutor buildpack.BuildExecutor
DirStore DirStore
Group buildpack.Group
Logger log.Logger
Out, Err io.Writer
Plan platform.BuildPlan
PlatformAPI *api.Version
AppDir string
BuildConfigDir string
LayersDir string
PlatformDir string
BuildExecutor buildpack.BuildExecutor
DirStore DirStore
Group buildpack.Group
Logger log.Logger
Out, Err io.Writer
Plan platform.BuildPlan
PlatformAPI *api.Version
}

func (b *Builder) Build() (*platform.BuildMetadata, error) {
Expand All @@ -61,10 +62,7 @@ func (b *Builder) Build() (*platform.BuildMetadata, error) {
slices []layers.Slice
)
processMap := newProcessMap()
inputs, err := b.getCommonInputs()
if err != nil {
return nil, err
}
inputs := b.getBuildInputs()
inputs.Env = env.NewBuildEnv(os.Environ())
filteredPlan := b.Plan

Expand Down Expand Up @@ -113,8 +111,7 @@ func (b *Builder) Build() (*platform.BuildMetadata, error) {

if b.PlatformAPI.AtLeast("0.8") {
b.Logger.Debug("Copying SBOM files")
err = b.copySBOMFiles(inputs.LayersDir, bomFiles)
if err != nil {
if err := b.copySBOMFiles(inputs.LayersDir, bomFiles); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -150,27 +147,15 @@ func (b *Builder) Build() (*platform.BuildMetadata, error) {
}, nil
}

func (b *Builder) getCommonInputs() (buildpack.BuildInputs, error) {
appDir, err := filepath.Abs(b.AppDir)
if err != nil {
return buildpack.BuildInputs{}, err
}
layersDir, err := filepath.Abs(b.LayersDir)
if err != nil {
return buildpack.BuildInputs{}, err
}
platformDir, err := filepath.Abs(b.PlatformDir)
if err != nil {
return buildpack.BuildInputs{}, err
}

func (b *Builder) getBuildInputs() buildpack.BuildInputs {
return buildpack.BuildInputs{
AppDir: appDir,
LayersDir: layersDir,
PlatformDir: platformDir,
Out: b.Out,
Err: b.Err,
}, nil
AppDir: b.AppDir,
BuildConfigDir: b.BuildConfigDir,
LayersDir: b.LayersDir,
PlatformDir: b.PlatformDir,
Out: b.Out,
Err: b.Err,
}
}

// copySBOMFiles() copies any BOM files written by buildpacks during the Build() process
Expand Down
6 changes: 6 additions & 0 deletions builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) {
}}
executor.EXPECT().Build(*bpA, gomock.Any(), gomock.Any()).DoAndReturn(
func(_ buildpack.BpDescriptor, inputs buildpack.BuildInputs, _ llog.Logger) (buildpack.BuildOutputs, error) {
h.AssertEq(t, inputs.AppDir, builder.AppDir)
h.AssertEq(t, inputs.BuildConfigDir, builder.BuildConfigDir)
h.AssertEq(t, inputs.PlatformDir, builder.PlatformDir)
h.AssertEq(t, inputs.Plan, expectedPlanA)
return buildpack.BuildOutputs{
MetRequires: []string{"some-dep"},
Expand All @@ -164,6 +167,9 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) {
}}
executor.EXPECT().Build(*bpB, gomock.Any(), gomock.Any()).Do(
func(_ buildpack.BpDescriptor, inputs buildpack.BuildInputs, _ llog.Logger) (buildpack.BuildOutputs, error) {
h.AssertEq(t, inputs.AppDir, builder.AppDir)
h.AssertEq(t, inputs.BuildConfigDir, builder.BuildConfigDir)
h.AssertEq(t, inputs.PlatformDir, builder.PlatformDir)
h.AssertEq(t, inputs.Plan, expectedPlanB)
return buildpack.BuildOutputs{}, nil
})
Expand Down
27 changes: 14 additions & 13 deletions buildpack/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,19 @@ const (
)

type BuildInputs struct {
AppDir string
LayersDir string
PlatformDir string
Env BuildEnv
Out, Err io.Writer
Plan Plan
AppDir string
BuildConfigDir string
LayersDir string
PlatformDir string
Env BuildEnv
Out, Err io.Writer
Plan Plan
}

type BuildEnv interface {
AddRootDir(baseDir string) error
AddEnvDir(envDir string, defaultAction env.ActionType) error
WithPlatform(platformDir string) ([]string, error)
WithOverrides(platformDir string, buildConfigDir string) ([]string, error)
List() []string
}

Expand Down Expand Up @@ -138,12 +139,12 @@ func runBuildCmd(d BpDescriptor, bpLayersDir, planPath string, inputs BuildInput

var err error
if d.Buildpack.ClearEnv {
cmd.Env = buildEnv.List()
cmd.Env, err = buildEnv.WithOverrides("", inputs.BuildConfigDir)
} else {
cmd.Env, err = buildEnv.WithPlatform(inputs.PlatformDir)
if err != nil {
return err
}
cmd.Env, err = buildEnv.WithOverrides(inputs.PlatformDir, inputs.BuildConfigDir)
}
if err != nil {
return err
}
cmd.Env = append(cmd.Env, EnvBuildpackDir+"="+d.WithRootDir)
if api.MustParse(d.WithAPI).AtLeast("0.8") {
Expand All @@ -154,7 +155,7 @@ func runBuildCmd(d BpDescriptor, bpLayersDir, planPath string, inputs BuildInput
)
}

if err := cmd.Run(); err != nil {
if err = cmd.Run(); err != nil {
return NewError(err, ErrTypeBuildpack)
}
return nil
Expand Down
27 changes: 15 additions & 12 deletions buildpack/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
inputs buildpack.BuildInputs
tmpDir string
appDir string
buildConfigDir string
layersDir string
platformDir string
mockEnv *testmock.MockBuildEnv
Expand Down Expand Up @@ -87,34 +88,35 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
h.AssertNil(t, err)
layersDir = filepath.Join(tmpDir, "launch")
appDir = filepath.Join(layersDir, "app")
buildConfigDir = filepath.Join(tmpDir, "build-config")
platformDir = filepath.Join(tmpDir, "platform")
h.Mkdir(t, layersDir, appDir, filepath.Join(platformDir, "env"))

// make inputs
mockEnv = testmock.NewMockBuildEnv(mockCtrl)
stdout, stderr = &bytes.Buffer{}, &bytes.Buffer{}
inputs = buildpack.BuildInputs{
AppDir: appDir,
LayersDir: layersDir,
PlatformDir: platformDir,
Env: mockEnv,
Out: stdout,
Err: stderr,
AppDir: appDir,
BuildConfigDir: buildConfigDir,
LayersDir: layersDir,
PlatformDir: platformDir,
Env: mockEnv,
Out: stdout,
Err: stderr,
}

logger = &log.Logger{Handler: logHandler}
})

it.After(func() {
os.RemoveAll(tmpDir)
_ = os.RemoveAll(tmpDir)
mockCtrl.Finish()
})

when("#Build", func() {
when("env", func() {
when("clear", func() {
it.Before(func() {
mockEnv.EXPECT().List().Return(append(os.Environ(), "TEST_ENV=cleared"))
mockEnv.EXPECT().WithOverrides("", buildConfigDir).Return(append(os.Environ(), "TEST_ENV=cleared"), nil)

descriptor.Buildpack.Version = "v1.clear"
descriptor.WithRootDir = filepath.Join(dirStore, "A", "v1.clear")
Expand Down Expand Up @@ -163,7 +165,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {

when("full", func() {
it.Before(func() {
mockEnv.EXPECT().WithPlatform(platformDir).Return(append(os.Environ(), "TEST_ENV=Av1"), nil)
mockEnv.EXPECT().WithOverrides(platformDir, buildConfigDir).Return(append(os.Environ(), "TEST_ENV=Av1"), nil)
})

it("provides a full env", func() {
Expand Down Expand Up @@ -219,7 +221,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
})

it("errors when <platform>/env cannot be loaded", func() {
mockEnv.EXPECT().WithPlatform(platformDir).Return(nil, errors.New("some error"))
mockEnv.EXPECT().WithOverrides(platformDir, buildConfigDir).Return(nil, errors.New("some error"))
if _, err := executor.Build(descriptor, inputs, logger); err == nil {
t.Fatal("Expected error.\n")
} else if !strings.Contains(err.Error(), "some error") {
Expand All @@ -229,7 +231,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {

when("any", func() {
it.Before(func() {
mockEnv.EXPECT().WithPlatform(platformDir).Return(append(os.Environ(), "TEST_ENV=Av1"), nil).AnyTimes()
mockEnv.EXPECT().WithOverrides(platformDir, buildConfigDir).Return(append(os.Environ(), "TEST_ENV=Av1"), nil).AnyTimes()
})

it("ensures the buildpack's layers dir exists and processes build layers", func() {
Expand Down Expand Up @@ -301,6 +303,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
var appendErr error

it.Before(func() {
mockEnv.EXPECT().WithOverrides(platformDir, buildConfigDir).Return(append(os.Environ(), "TEST_ENV=Av1"), nil).AnyTimes()
appendErr = errors.New("some error")
})

Expand Down
51 changes: 15 additions & 36 deletions buildpack/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ const (
)

type DetectInputs struct {
AppDir string
PlatformDir string
Env BuildEnv
AppDir string
BuildConfigDir string
PlatformDir string
Env BuildEnv
}

type DetectOutputs struct {
Expand Down Expand Up @@ -57,18 +58,13 @@ func (e *DefaultDetectExecutor) Detect(d Descriptor, inputs DetectInputs, logger
}

func detectBp(d BpDescriptor, inputs DetectInputs, logger log.Logger) DetectOutputs {
appDir, platformDir, err := processPlatformPaths(inputs)
if err != nil {
return DetectOutputs{Code: -1, Err: err}
}

planDir, planPath, err := processBuildpackPaths()
defer os.RemoveAll(planDir)
if err != nil {
return DetectOutputs{Code: -1, Err: err}
}

result := runDetect(&d, platformDir, planPath, appDir, inputs.Env, EnvBuildpackDir)
result := runDetect(&d, inputs, planPath, EnvBuildpackDir)
if result.Code != 0 {
return result
}
Expand Down Expand Up @@ -99,11 +95,6 @@ func detectBp(d BpDescriptor, inputs DetectInputs, logger log.Logger) DetectOutp
}

func detectExt(d ExtDescriptor, inputs DetectInputs, logger log.Logger) DetectOutputs {
appDir, platformDir, err := processPlatformPaths(inputs)
if err != nil {
return DetectOutputs{Code: -1, Err: err}
}

planDir, planPath, err := processBuildpackPaths()
defer os.RemoveAll(planDir)
if err != nil {
Expand All @@ -119,7 +110,7 @@ func detectExt(d ExtDescriptor, inputs DetectInputs, logger log.Logger) DetectOu
return DetectOutputs{Code: -1, Err: err}
}
} else {
result = runDetect(&d, platformDir, planPath, appDir, inputs.Env, EnvExtensionDir)
result = runDetect(&d, inputs, planPath, EnvExtensionDir)
if result.Code != 0 {
return result
}
Expand All @@ -144,18 +135,6 @@ func detectExt(d ExtDescriptor, inputs DetectInputs, logger log.Logger) DetectOu
return result
}

func processPlatformPaths(inputs DetectInputs) (string, string, error) {
appDir, err := filepath.Abs(inputs.AppDir)
if err != nil {
return "", "", nil
}
platformDir, err := filepath.Abs(inputs.PlatformDir)
if err != nil {
return "", "", nil
}
return appDir, platformDir, nil
}

func processBuildpackPaths() (string, string, error) {
planDir, err := os.MkdirTemp("", "plan.")
if err != nil {
Expand All @@ -174,31 +153,31 @@ type detectable interface {
RootDir() string
}

func runDetect(d detectable, platformDir, planPath, appDir string, bpEnv BuildEnv, envRootDirKey string) DetectOutputs {
func runDetect(d detectable, inputs DetectInputs, planPath string, envRootDirKey string) DetectOutputs {
out := &bytes.Buffer{}
cmd := exec.Command(
filepath.Join(d.RootDir(), "bin", "detect"),
platformDir,
inputs.PlatformDir,
planPath,
) // #nosec G204
cmd.Dir = appDir
cmd.Dir = inputs.AppDir
cmd.Stdout = out
cmd.Stderr = out

var err error
if d.ClearEnv() {
cmd.Env = bpEnv.List()
cmd.Env, err = inputs.Env.WithOverrides("", inputs.BuildConfigDir)
} else {
cmd.Env, err = bpEnv.WithPlatform(platformDir)
if err != nil {
return DetectOutputs{Code: -1, Err: err}
}
cmd.Env, err = inputs.Env.WithOverrides(inputs.PlatformDir, inputs.BuildConfigDir)
}
if err != nil {
return DetectOutputs{Code: -1, Err: err}
}
cmd.Env = append(cmd.Env, envRootDirKey+"="+d.RootDir())
if api.MustParse(d.API()).AtLeast("0.8") {
cmd.Env = append(
cmd.Env,
EnvPlatformDir+"="+platformDir,
EnvPlatformDir+"="+inputs.PlatformDir,
EnvBuildPlanPath+"="+planPath,
)
}
Expand Down
Loading