Skip to content

Conversation

@jjbustamante
Copy link
Member

@jjbustamante jjbustamante commented Jan 26, 2025

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 build command 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 pack with the changes made in this PR
  • I built our sample ruby application, using our sample builder available in docker hub, using the new --exec-env flag

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/hello-world@0.0.1
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?
    • Yes, see #___
    • No

Related

Resolves #___

Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
@github-actions github-actions bot added this to the 0.37.0 milestone Jan 26, 2025
@github-actions github-actions bot added the type/enhancement Issue that requests a new feature or improvement. label Jan 26, 2025
@jjbustamante jjbustamante changed the title WIP - adding flag to set the CNB_EXEC_ENV Proof of Concept for Execution Environment RFC Jan 26, 2025
@codecov
Copy link

codecov bot commented Jan 26, 2025

Codecov Report

❌ Patch coverage is 14.92537% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.64%. Comparing base (d1a30b6) to head (0285c59).

Additional details and impacted files

Impacted file tree graph

@@            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%) ⬇️
os_macos-arm64 58.06% <14.93%> (-0.11%) ⬇️
os_windows 60.14% <14.93%> (-0.11%) ⬇️
unit 60.64% <14.93%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
…in progress

Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
@github-actions github-actions bot added this to the 0.37.0 milestone Mar 5, 2025
@jjbustamante jjbustamante modified the milestones: 0.37.0, 0.38.0 Mar 14, 2025
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
@edmorley
Copy link
Contributor

For anyone else following along with this work - there is now a tracking issue for implementing the RFC at:
buildpacks/rfcs#327

Resolved conflicts by keeping both features:
- ExecutionEnv/CNBExecutionEnv from execution-environment-poc branch
- InsecureRegistries from main branch

Files with resolved conflicts:
- internal/commands/build.go
- internal/commands/build_test.go
- pkg/client/build.go
  Changes Made:

  1. internal/build/lifecycle_executor.go (2 lines added)
    - Added Platform API versions 0.14 and 0.15 to SupportedPlatformAPIVersions
    - This allows pack to support the new execution environment feature which requires Platform API 0.15
  2. internal/build/phase_config_provider.go (1 line changed)
    - Updated the Platform API version check from 0.13 to 0.15 for the CNB_EXEC_ENV environment variable
  3. internal/build/fakes/fake_builder.go (7 lines added)
    - Added WithExecutionEnvironment() helper function for tests
    - Allows tests to easily set the execution environment in lifecycle options
  4. internal/build/phase_config_provider_test.go (41 lines added)
    - Added comprehensive tests for the execution environment feature:
        - ✅ Test that CNB_EXEC_ENV is set when Platform API >= 0.15
      - ✅ Test that CNB_EXEC_ENV is NOT set when Platform API < 0.15
    - Added import for "github.com/buildpacks/lifecycle/api" package

  Existing Test Coverage (Already in PR):

  1. internal/commands/build_test.go
    - ✅ Tests that default exec-env is 'production'
    - ✅ Tests with valid characters (letters, numbers, dots, hyphens)
    - ✅ Tests with invalid characters (shows proper error)
    - ✅ Comprehensive validation tests for exec-env flag
  2. builder/config_reader_test.go
    - ✅ Tests reading exec-env from builder configuration
  3. pkg/project/project_test.go
    - ✅ Tests reading exec-env from project.toml (schema v0.3)
    - ✅ Tests for buildpack groups, pre-groups, and post-groups

  Test Results:

  - All phase config provider tests: PASSING ✅
  - All build command tests: PASSING ✅
  - Coverage for exec-env flag validation: COMPLETE ✅
  - Coverage for CNB_EXEC_ENV environment variable: COMPLETE ✅
  - Coverage for Platform API version gating: COMPLETE ✅

  The test coverage for your ExecutionEnvironment feature is now comprehensive and covers:
  - Command-line flag validation
  - Environment variable setting based on Platform API version
  - Builder and project configuration reading
  - Edge cases and error conditions

Signed-off-by: Juan Bustamante <bustamantejj@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/enhancement Issue that requests a new feature or improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants