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

Change lifecycle to support Linux and Windows #62

Closed
wants to merge 2 commits into from
Closed
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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,31 @@ A **platform** is software that orchestrates a lifecycle to make buildpack funct

## Notational Conventions

### Key Words
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in [RFC 2119](http://tools.ietf.org/html/rfc2119).

The key words "unspecified", "undefined", and "implementation-defined" are to be interpreted as described in the [rationale for the C99 standard](http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf#page=18).

An implementation is not compliant if it fails to satisfy one or more of the MUST, MUST NOT, REQUIRED, SHALL, or SHALL NOT requirements for the protocols it implements.
An implementation is compliant if it satisfies all the MUST, MUST NOT, REQUIRED, SHALL, and SHALL NOT requirements for the protocols it implements.

### Operating System Conventions

When a word or bullet point is prefixed with a <a name="linux-only">†</a>, it SHALL be assumed to apply only to Linux stacks.

When a word or bullet point is prefixed with a <a name="windows-only">‡</a>, it SHALL be assumed to apply only to Windows stacks.
micahyoung marked this conversation as resolved.
Show resolved Hide resolved


When the specification denotes a "shell", Linux stacks MUST use the Bourne Again Shell (`bash`) version 3 or greater and Windows stacks MUST use Command Prompt (`cmd.exe`) unless otherwise specified.

#### Interpreting Paths for Windows

When the specification denotes a filesystem path using POSIX path notation (e.g. `/cnb/lifecycle`), this notation SHALL be interpreted to represent a path where all POSIX file path separators are replaced with the Windows filepath separator (`\`) and absolute paths are assumed to be rooted in the default drive (e.g. `C:\cnb\lifecycle`).

When the specification refers to an executable file with POSIX path notation (e.g. `/cnb/buildpacks/bp-a/1.2.3/bin/detect`), this notation SHALL be interpreted to represent one of two possible files: one with the suffix `.exe` (e.g. `C:\cnb\buildpacks\bp-a\1.2.3\bin\detect.exe`) or with the suffix `.bat` (e.g. `C:\cnb\buildpacks\bp-a\1.2.3\bin\detect.bat`).

When the specification refers to a path in the context of an OCI layer tar (e.g. `/cnb/buildpacks/bp-a/1.2.3/`), this path SHALL be interpreted to be prefixed with `Files` (e.g. `Files/cnb/buildpacks/bp-a/1.2.3/`). Note: path separators in OCI layer tar headers MUST be `/` regardless of operating system.

## Sections

- [Buildpack Interface Specification](buildpack.md)
Expand Down
63 changes: 34 additions & 29 deletions buildpack.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ Executable: `/bin/detect <platform[AR]> <plan[E]>`, Working Dir: `<app[AR]>`
| Output | Description
|--------------------|----------------------------------------------
| [exit status] | Pass (0), fail (100), or error (1-99, 101+)
| `/dev/stdout` | Logs (info)
| `/dev/stderr` | Logs (warnings, errors)
| Standard output | Logs (info)
| Standard error | Logs (warnings, errors)
| `<plan>` | Contributions to the the Build Plan (TOML)


Expand All @@ -90,15 +90,15 @@ Executable: `/bin/build <layers[EIC]> <platform[AR]> <plan[E]>`, Working Dir: `<
| Output | Description
|--------------------------------|-----------------------------------------------
| [exit status] | Success (0) or failure (1+)
| `/dev/stdout` | Logs (info)
| `/dev/stderr` | Logs (warnings, errors)
| Standard output | Logs (info)
| Standard error | Logs (warnings, errors)
| `<plan>` | Refinements to the [Buildpack Plan](#buildpack-plan-toml) (TOML)
| `<layers>/launch.toml` | App metadata (see [launch.toml](#launch.toml-toml))
| `<layers>/store.toml` | Persistent metadata (see [store.toml](#store.toml-toml))
| `<layers>/<layer>.toml` | Layer metadata (see [Layer Content Metadata](#layer-content-metadata-toml))
| `<layers>/<layer>/bin/` | Binaries for launch and/or subsequent buildpacks
| `<layers>/<layer>/lib/` | Shared libraries for launch and/or subsequent buildpacks
| `<layers>/<layer>/profile.d/` | Scripts sourced by Bash before launch
| `<layers>/<layer>/lib/` | [†](README.md#linux-only)Shared libraries for launch and/or subsequent buildpacks
| `<layers>/<layer>/profile.d/` | Scripts sourced by shell before launch
| `<layers>/<layer>/include/` | C/C++ headers for subsequent buildpacks
| `<layers>/<layer>/pkgconfig/` | Search path for pkg-config for subsequent buildpacks
| `<layers>/<layer>/env/` | Env vars for launch and/or subsequent buildpacks
Expand Down Expand Up @@ -160,9 +160,10 @@ The lifecycle MUST consider layers that are marked `launch = false` and `build =

## App Interface

| Output | Description
|------------------|----------------------------------------------
| `<app>/.profile` | Script sourced by bash before launch
| Output | Description
|------------------------|----------------------------------------------
| `<app>/.profile` | [†](README.md#linux-only) Bash-formatted script sourced by shell before launch
| `<app>/.profile.bat` | [‡](README.md#windows-only) BAT-formatted script sourced by shell before launch

## Phase #1: Detection

Expand All @@ -176,8 +177,9 @@ These buildpacks must be compatible with the app.
### Process

**GIVEN:**
- An ordered list of buildpack groups resolved into buildpack implementations as described in [Order Resolution](#order-resolution) and
- A directory containing application source code,
- An ordered list of buildpack groups resolved into buildpack implementations as described in [Order Resolution](#order-resolution)
- A directory containing application source code
- A shell, if needed,

For each buildpack in each group in order, the lifecycle MUST execute `/bin/detect`.

Expand Down Expand Up @@ -355,7 +357,7 @@ This is achieved by:
- The Buildpack Plan,
- Any `<layers>/<layer>.toml` files placed on the filesystem during the analysis phase,
- Any locally cached `<layers>/<layer>` directories, and
- Bash version 3 or greater, if needed,
- A shell, if needed,

For each buildpack in the group in order, the lifecycle MUST execute `/bin/build`.

Expand Down Expand Up @@ -497,7 +499,7 @@ The purpose of launch is to modify the running app environment using app-provide
**GIVEN:**
- An OCI image exported by the lifecycle,
- An optional process type specified by `CNB_PROCESS_TYPE`, and
- Bash version 3 or greater, if needed,
- A shell, if needed,

First, the lifecycle MUST locate a start command and choose an execution strategy.

Expand Down Expand Up @@ -525,15 +527,14 @@ To choose an execution strategy,

1. **IF** the value of `CMD` is chosen as the start command,
1. **IF** the first parameter of `CMD` is not `--`,
**THEN** the lifecycle MUST invoke the value as a command using Bash with subsequent entries as arguments.
**THEN** the lifecycle MUST invoke the value as a command using the shell with subsequent entries as arguments.

2. **IF** the first parameter of `CMD` is `--` and the length of `CMD` is greater than one,
**THEN** the lifecycle MUST invoke the second entry using the `execve` syscall with subsequent entries as arguments.


2. **IF** a buildpack-provided process type is chosen as the start command,
1. **IF** the process type does not have `direct` set to `true`,
**THEN** the lifecycle MUST invoke the value of `command` as a command using Bash with values of `args` provided as arguments.
**THEN** the lifecycle MUST invoke the value of `command` as a command using the shell with values of `args` provided as arguments.

2. **IF** the process type does have `direct` set to `true`,
**THEN** the lifecycle MUST invoke the value of `command` using the `execve` syscall with values of `args` provided as arguments.
Expand All @@ -542,17 +543,20 @@ Given the start command and execution strategy,

1. The lifecycle MUST set all buildpack-provided launch environment variables as described in the [Environment](#environment) section.

2. If using an execution strategy involving Bash, the lifecycle MUST use a single Bash process to
2. If using an execution strategy involving a shell, the lifecycle MUST use a single shell process to
1. source each file in each `<layers>/<layer>/profile.d` directory,
1. Firstly, in order of `/bin/build` execution used to construct the OCI image.
2. Secondly, in alphabetically ascending order by layer directory name.
3. Thirdly, in alphabetically ascending order by file name.
2. source `<app>/.profile` if it is present.
2. source [†](README.md#linux-only)`<app>/.profile` or [‡](README.md#windows-only)`<app>/.profile.bat` if it is present.

3. The lifecycle MUST invoke the start command with the decided execution strategy.

When executing a process using any execution strategy, the lifecycle SHOULD replace the lifecycle process in memory without forking it.
When executing a process with Bash, the lifecycle SHOULD additionally replace the Bash process in memory without forking it.
[†](README.md#linux-only)When executing a process using any execution strategy, the lifecycle SHOULD replace the lifecycle process in memory without forking it.

[†](README.md#linux-only)When executing a process with Bash, the lifecycle SHOULD additionally replace the Bash process in memory without forking it.

[‡](README.md#windows-only)When executing a process with Command Prompt, the lifecycle SHOULD start a new process with the same security context, terminal, working directory, STDIN/STDOUT/STDERR handles and environment variables as the Command Prompt process.

## Environment

Expand All @@ -570,15 +574,16 @@ In either case,

- The lifecycle MUST order all `<layer>` paths to reflect the reversed order of the buildpack group.
- The lifecycle MUST order all `<layer>` paths provided by a given buildpack alphabetically ascending.
- The lifecycle MUST separate each path with the OS path list separator (e.g., `:` on Linux).
- The lifecycle MUST separate each path with the OS path list separator (e.g. `:` on Linux, `;` on Windows).

| Env Variable | Layer Path | Contents | Build | Launch |
|--------------------------------------------|--------------|------------------|-------|--------|
| `PATH` | `/bin` | binaries | [x] | [x] |
| [†](README.md#linux-only)`LD_LIBRARY_PATH` | `/lib` | shared libraries | [x] | [x] |
| [†](README.md#linux-only)`LIBRARY_PATH` | `/lib` | static libraries | [x] | |
| `CPATH` | `/include` | header files | [x] | |
| `PKG_CONFIG_PATH` | `/pkgconfig` | pc files | [x] | |

| Env Variable | Layer Path | Contents | Build | Launch
|-------------------|--------------|------------------|-------|--------
| `PATH` | `/bin` | binaries | [x] | [x]
| `LD_LIBRARY_PATH` | `/lib` | shared libraries | [x] | [x]
| `LIBRARY_PATH` | `/lib` | static libraries | [x] |
| `CPATH` | `/include` | header files | [x] |
| `PKG_CONFIG_PATH` | `/pkgconfig` | pc files | [x] |

### Provided by the Platform

Expand Down Expand Up @@ -704,7 +709,7 @@ For each process, the buildpack:

- MUST specify a `type` that is not identical to other process types provided by the same buildpack.
- MUST specify a `command` that is either:
- A command sequence that is valid when executed using the Bash 3+ shell, if `args` is not specified.
- A command sequence that is valid when executed using the shell, if `args` is not specified.
- A path to an executable or the file name of an executable in `$PATH`, if `args` is a list with zero or more elements.
- MAY specify an `args` list to be passed directly to the specified executable.
- MAY specify a `direct` boolean that bypasses the shell.
Expand Down
6 changes: 3 additions & 3 deletions platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ The platform MUST ensure that:

- The image config's `User` field is set to a non-root user with a writable home directory.
- The image config's `Env` field has the environment variable `CNB_STACK_ID` set to the stack ID.
- The image config's `Env` field has the environment variable `CNB_USER_ID` set to the UID of the user specified in the `User` field.
- The image config's `Env` field has the environment variable `CNB_GROUP_ID` set to the primary GID of the user specified in the `User` field.
- The image config's `Env` field has the environment variable `CNB_USER_ID` set to the user [†](README.md#linux-only)UID/[‡](README.md#windows-only)SID of the user specified in the `User` field.
- The image config's `Env` field has the environment variable `CNB_GROUP_ID` set to the primary group [†](README.md#linux-only)GID/[‡](README.md#windows-only)SID of the user specified in the `User` field.
- The image config's `Label` field has the label `io.buildpacks.stack.id` set to the stack ID.
- The image config's `Label` field has the label `io.buildpacks.stack.mixins` set to a JSON array containing mixin names for each mixin applied to the image.

Expand Down Expand Up @@ -115,7 +115,7 @@ The platform MUST provide the lifecycle with a reference to the run image during

The platform MUST ensure that:

- The image config's `User` field is set to a user with the same UID and primary GID as in the build image.
- The image config's `User` field is set to a user with the same user [†](README.md#linux-only)UID/[‡](README.md#windows-only)SID and primary group [†](README.md#linux-only)GID/[‡](README.md#windows-only)SID as in the build image.
- The image config's `Label` field has the label `io.buildpacks.stack.id` set to the stack ID.
- The image config's `Label` field has the label `io.buildpacks.stack.mixins` set to a JSON array containing mixin names for each mixin applied to the image.

Expand Down