Proof of Concept for Execution Environment RFC
Summary
This PR is intended to be an initial implementation of the Execution Environment RFC. it uses an initial implementation on lifecycle developed by @jabrown85 in the following branch
The RFC is in a voting state; we must include those changes in some API version and the current code should be updated afterward.
Changes added
- New flag to
pack buildcommand was added,--exec-env, to pass through the execution environment during the build process. By default, the value will be production
Output
Before
The Execution Environment feature doesn't exist, nothing to show here.
After
I added a bunch of unit tests to the updated toml files, but to test all together I used our sample repo. The hello-moon buildpack prints some environment variables during its execution.
Using a current lifecycle.
- I compiled
packwith the changes made in this PR - I built our sample ruby application, using our sample builder available in docker hub, using the new
--exec-envflag
Notice in the following log how pack is sending the CNB_EXEC_ENV environment variable with the value we set in the --exec-env flag to the lifecycle
~/go/src/github.com/buildpacks/pack/out/pack build my-sample-ruby-app:no-exec-env --builder cnbs/sample-builder:alpine --path ./ruby-bundler/ -v --trust-builder --exec-env test
Running the creator on OS linux from image index.docker.io/cnbs/sample-builder:alpine with:
Container Settings:
Args: /cnb/lifecycle/creator -daemon -launch-cache /launch-cache -log-level debug -app /workspace -cache-dir /cache -run-image cnbs/sample-base-run:alpine my-sample-ruby-app:no-exec-env
System Envs: CNB_PLATFORM_API=0.13 CNB_EXEC_ENV=test
Image: index.docker.io/cnbs/sample-builder:alpine
User: root
Labels: map[author:pack]
Also notice, because this lifecycle version doesn't know anything about the CNB_EXEC_ENV when our hello-moon buildpacks runs, we don't see the environment variable there.
===> ANALYZING
===> DETECTING
Timer: Detector started at 2025-02-03T12:38:09Z
======== Results ========
..
Timer: Restorer ran for 411.809µs and ended at 2025-02-03T12:38:09Z
===> BUILDING
Timer: Builder started at 2025-02-03T12:38:09Z
Running build for buildpack samples/[email protected]
Looking up buildpack
Finding plan
Creating plan directory
Preparing paths
Running build command
---> Hello World buildpack
platform_dir files:
/platform:
env_dir: /platform/env
env vars:
declare -x CNB_BP_PLAN_PATH="/tmp/samples_hello-world-1025312133/samples_hello-world/plan.toml"
declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-world/0.0.1"
declare -x CNB_LAYERS_DIR="/layers/samples_hello-world"
declare -x CNB_PLATFORM_DIR="/platform"
declare -x CNB_STACK_ID="io.buildpacks.samples.stacks.alpine"
declare -x CNB_TARGET_ARCH="amd64"
declare -x CNB_TARGET_DISTRO_NAME="alpine"
declare -x CNB_TARGET_DISTRO_VERSION="3.18.3"
declare -x CNB_TARGET_OS="linux"
declare -x HOME="/home/cnb"
declare -x HOSTNAME="9dd21023870a"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/workspace"
declare -x SHLVL="1"
layers_dir: /layers/samples_hello-world
plan_path: /tmp/samples_hello-world-1025312133/samples_hello-world/plan.toml
plan contents:
[[entries]]
name = "some-world"
[[entries]]
name = "some-world"
[entries.metadata]
world = "Earth-616"
---> Done
Processing layers
Running build command
---> Hello Moon buildpack
env_dir: /platform/env
env vars:
declare -x CNB_BP_PLAN_PATH="/tmp/samples_hello-moon-3157340986/samples_hello-moon/plan.toml"
declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-moon/0.0.1"
declare -x CNB_LAYERS_DIR="/layers/samples_hello-moon"
declare -x CNB_PLATFORM_DIR="/platform"
declare -x CNB_STACK_ID="io.buildpacks.samples.stacks.alpine"
declare -x CNB_TARGET_ARCH="amd64"
declare -x CNB_TARGET_DISTRO_NAME="alpine"
declare -x CNB_TARGET_DISTRO_VERSION="3.18.3"
declare -x CNB_TARGET_OS="linux"
declare -x HOME="/home/cnb"
declare -x HOSTNAME="9dd21023870a"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/workspace"
declare -x SHLVL="1"
layers_dir: /layers/samples_hello-moon
plan_path: /tmp/samples_hello-moon-3157340986/samples_hello-moon/plan.toml
plan contents:
---> Done
...
Timer: Builder ran for 6.917745ms and ended at 2025-02-03T12:38:09Z
===> EXPORTING
Successfully built image my-sample-ruby-app:no-exec-env
Using a lifecycle compiled from Jesse's branch
As I mentioned before, @jabrown85 created a lifecycle implementation for this RFC, I compiled a lifecycle from that branch and created a sample builder with it. I built the sample ruby application using that builder.
Similar to our previous example, pack sends the CNB_EXEC_ENV with the value we specified in the command line.
> ~/go/src/github.com/buildpacks/pack/out/pack build sample-ruby-app:with-exec-env --builder my-exec-env-builder:alpine --path ./ruby-bundler/ -v --trust-builder --exec-env test
ning the creator on OS linux from image index.docker.io/library/my-exec-env-builder:alpine with:
Container Settings:
Args: /cnb/lifecycle/creator -daemon -launch-cache /launch-cache -log-level debug -app /workspace -cache-dir /cache -run-image cnbs/sample-base-run:alpine sample-ruby-app:with-exec-env
System Envs: CNB_PLATFORM_API=0.13 CNB_EXEC_ENV=test
Image: index.docker.io/library/my-exec-env-builder:alpine
User: root
Labels: map[author:pack]
Now, we can see the environment variable CNB_EXEC_ENV is available to the buildpack at execution time to the build/detect binaries.
===> BUILDING
Timer: Builder started at 2025-02-03T12:39:11Z
env vars:
declare -x CNB_BP_PLAN_PATH="/tmp/samples_hello-world-3047059202/samples_hello-world/plan.toml"
declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-world/0.0.1"
declare -x CNB_EXEC_ENV="test"
declare -x CNB_LAYERS_DIR="/layers/samples_hello-world"
declare -x CNB_PLATFORM_DIR="/platform"
declare -x CNB_STACK_ID="io.buildpacks.samples.stacks.alpine"
declare -x CNB_TARGET_ARCH="amd64"
declare -x CNB_TARGET_DISTRO_NAME="alpine"
declare -x CNB_TARGET_DISTRO_VERSION="3.18.3"
declare -x CNB_TARGET_OS="linux"
Documentation
- Should this change be documented?
- [X] Yes, see #___
- [ ] No
Related
Resolves #___
Codecov Report
:x: Patch coverage is 14.92537% with 57 lines in your changes missing coverage. Please review.
:white_check_mark: Project coverage is 60.64%. Comparing base (d1a30b6) to head (0285c59).
Additional details and impacted files
@@ Coverage Diff @@
## main #2324 +/- ##
==========================================
- Coverage 60.76% 60.64% -0.12%
==========================================
Files 254 255 +1
Lines 19165 19228 +63
==========================================
+ Hits 11643 11658 +15
- Misses 6712 6759 +47
- Partials 810 811 +1
| Flag | Coverage Δ | |
|---|---|---|
| os_linux | 60.28% <14.93%> (-0.12%) |
:arrow_down: |
| os_macos-arm64 | 58.06% <14.93%> (-0.11%) |
:arrow_down: |
| os_windows | 60.14% <14.93%> (-0.11%) |
:arrow_down: |
| unit | 60.64% <14.93%> (-0.12%) |
:arrow_down: |
Flags with carried forward coverage won't be shown. Click here to find out more.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
For anyone else following along with this work - there is now a tracking issue for implementing the RFC at: https://github.com/buildpacks/rfcs/issues/327