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

Move analyzer before detector #197

Merged
merged 15 commits into from
Apr 29, 2021
168 changes: 82 additions & 86 deletions platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,16 @@ Examples of a platform might include:
- [Rebase](#rebase)
- [Launch](#launch)
- [Usage](#usage)
- [`detector`](#detector)
- [`analyzer`](#analyzer)
- [Inputs](#inputs)
- [Outputs](#outputs)
- [`analyzer`](#analyzer)
- [`detector`](#detector)
- [Inputs](#inputs-1)
- [Outputs](#outputs-1)
- [Layer analysis](#layer-analysis)
- [`restorer`](#restorer)
- [Inputs](#inputs-2)
- [Outputs](#outputs-2)
- [Layer restoration](#layer-restoration)
- [Layer Restoration](#layer-restoration)
- [`builder`](#builder)
- [Inputs](#inputs-3)
- [Outputs](#outputs-3)
Expand Down Expand Up @@ -177,7 +176,7 @@ The platform SHOULD ensure that:
- The image config's `Label` field has the label `io.buildpacks.stack.distro.version` set to the version of the stack's OS distro.
- The image config's `Label` field has the label `io.buildpacks.stack.released` set to the release date of the stack.
- The image config's `Label` field has the label `io.buildpacks.stack.description` set to the description of the stack.
- The image config's `Label` field has the label `io.buildpacks.stack.metadata` set to additional metadata related to the stack.
- The image config's `Label` field has the label `io.buildpacks.stack.metadata` set to additional metadata related to the stack.

### Run Image

Expand All @@ -196,7 +195,7 @@ The platform SHOULD ensure that:
- The image config's `Label` field has the label `io.buildpacks.stack.distro.version` set to the version of the stack's OS distro.
- The image config's `Label` field has the label `io.buildpacks.stack.released` set to the release date of the stack.
- The image config's `Label` field has the label `io.buildpacks.stack.description` set to the description of the stack.
- The image config's `Label` field has the label `io.buildpacks.stack.metadata` set to additional metadata related to the stack.
- The image config's `Label` field has the label `io.buildpacks.stack.metadata` set to additional metadata related to the stack.

### Mixins

Expand Down Expand Up @@ -237,15 +236,15 @@ If `CNB_PLATFORM_API` is set in the lifecycle's execution environment, the lifec
#### Build
A single app image build* consists of the following phases:

1. Detection
1. Analysis
1. Detection
1. Cache Restoration
1. Build*
1. Export

A platform MUST execute these phases either by invoking the following phase-specific lifecycle binaries in order:
1. `/cnb/lifecycle/detector`
1. `/cnb/lifecycle/analyzer`
1. `/cnb/lifecycle/detector`
1. `/cnb/lifecycle/restorer`
1. `/cnb/lifecycle/builder`
1. `/cnb/lifecycle/exporter`
Expand All @@ -264,7 +263,7 @@ This entire operation is referred to as rebasing the app image.
Rebasing allows for fast runtime OS-level dependency updates for app images without requiring a rebuild. A rebase requires minimal data transfer when the app and run images are colocated on a Docker registry that supports [Cross Repository Blob Mounts](https://docs.docker.com/registry/spec/api/#cross-repository-blob-mount).

To rebase an app image a platform MUST execute the `/cnb/lifecycle/rebaser` or perform an equivalent operation.

#### Launch
`/cnb/lifecycle/launcher` is responsible for launching user and buildpack provided processes in the correct execution environment.
`/cnb/lifecycle/launcher` SHALL be the `ENTRYPOINT` for all app images.
Expand All @@ -276,10 +275,58 @@ All lifecycle phases:
- MUST read `CNB_PLATFORM_API` from the execution environment and evaluate compatibility before attempting to parse other inputs (see [Platform API Compatibility](#platform-api-compatibility))
- MUST give command line inputs precedence over other inputs

#### `analyzer`
Usage:
```
/cnb/lifecycle/analyzer \
[-analyzed <analyzed>] \
[-daemon] \ # sets <daemon>
[-gid <gid>] \
[-group <group>] \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the lifecycle PR: it looks like group is only defined for earlier platform apis, is that intended?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I'm remembering how all of this works... we can't have group if analyze goes first...

Suggested change
[-group <group>] \

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have group, but not order

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't have group right? There is no group until detection.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the future we will support stack-group in order to validate mixins, but not group?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I confused myself with the names. We need <order>, not <group>. Fixed in 6480d2e

[-layers <layers>] \
[-log-level <log-level>] \
[-previous-image <previous-image> ] \
[-uid <uid>]
```

##### Inputs
| Input | Environment Variable | Default Value | Description
|-------------------|-----------------------|--------------------------|----------------------
| `<analyzed>` | `CNB_ANALYZED_PATH` | `<layers>/analyzed.toml` | Path to output analysis metadata (see [`analyzed.toml`](#analyzedtoml-toml)
| `<daemon>` | `CNB_USE_DAEMON` | `false` | Analyze image from docker daemon
| `<gid>` | `CNB_GROUP_ID` | | Primary GID of the stack `User`
| `<group>` | `CNB_GROUP_PATH` | `<layers>/group.toml` | Path to group definition (see [`group.toml`](#grouptoml-toml))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `<group>` | `CNB_GROUP_PATH` | `<layers>/group.toml` | Path to group definition (see [`group.toml`](#grouptoml-toml))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 6480d2e

| `<layers>` | `CNB_LAYERS_DIR` | `/layers` | Path to layers directory
| `<log-level>` | `CNB_LOG_LEVEL` | `info` | Log Level
| `<previous-image>`| `CNB_PREVIOUS_IMAGE` | `<image>` | Image reference to be analyzed (usually the result of the previous build)
| `<uid>` | `CNB_USER_ID` | | UID of the stack `User`

- **If** `<daemon>` is `false`, `<image>` MUST be a valid image reference
- **If** `<daemon>` is `true`, `<image>` MUST be either a valid image reference or an imageID
- The lifecycle MUST accept valid references to non-existent images without error.

##### Outputs
| Output | Description
|--------------------|----------------------------------------------
| [exit status] | (see Exit Code table below for values)
| `/dev/stdout` | Logs (info)
| `/dev/stderr` | Logs (warnings, errors)
| `<analyzed>` | Analysis metadata (see [`analyzed.toml`](#analyzedtoml-toml)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we are writing run-image metadata in this output. analyzed.toml needs to be an input to exporter and stack.toml can be removed as an exporter input.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<analyzed> is already an input, I removed <stack> in 6480d2e


| Exit Code | Result|
|-----------|-------|
| `0` | Success
| `11` | Platform API incompatibility error
| `12` | Buildpack API incompatibility error
| `1-10`, `13-99` | Generic lifecycle errors
| `200-299` | Analysis-specific lifecycle errors

- The lifecycle MUST write [analysis metadata](#analyzedtoml-toml) to `<analyzed>` if `<image>` is accessible.

#### `detector`
The platform MUST execute `detector` in the **build environment**

Usage:
Usage:
```
/cnb/lifecycle/detector \
[-app <app>] \
Expand Down Expand Up @@ -327,126 +374,75 @@ The lifecycle:
- SHALL detect a single group from `<order>` and write it to `<group>` using the [detection process](buildpack.md#phase-1-detection) outlined in the Buildpack Interface Specification
- SHALL write the resolved build plan from the detected group to `<plan>`

#### `analyzer`
Usage:
#### `restorer`
Usage:
```
/cnb/lifecycle/analyzer \
/cnb/lifecycle/restorer \
[-analyzed <analyzed>] \
[-cache-dir <cache-dir>] \
[-cache-image <cache-image>] \
[-daemon] \ # sets <daemon>
[-gid <gid>] \
[-group <group>] \
[-layers <layers>] \
[-log-level <log-level>] \
[-skip-layers <skip-layers>] \
[-uid <uid>] \
<image>
[-uid <uid>]
```

##### Inputs
| Input | Environment Variable | Default Value | Description
|----------------|-----------------------|--------------------------|----------------------
| `<analyzed>` | `CNB_ANALYZED_PATH` | `<layers>/analyzed.toml` | Path to output analysis metadata (see [`analyzed.toml`](#analyzedtoml-toml)
| `<cache-dir>` | `CNB_CACHE_DIR` | | Location of cache, provided as a directory
| `<cache-image>`| `CNB_CACHE_IMAGE` | | Location of cache, provided as an image
| `<daemon>` | `CNB_USE_DAEMON` | `false` | Analyze image from docker daemon
| `<analyzed>` | `CNB_ANALYZED_PATH` | `<layers>/analyzed.toml` | Path to analysis metadata (see [`analyzed.toml`](#analyzedtoml-toml)
| `<cache-dir>` | `CNB_CACHE_DIR` | | Path to a cache directory
| `<cache-image>`| `CNB_CACHE_IMAGE` | | Reference to a cache image in an OCI image registry
| `<gid>` | `CNB_GROUP_ID` | | Primary GID of the stack `User`
| `<group>` | `CNB_GROUP_PATH` | `<layers>/group.toml` | Path to group definition (see [`group.toml`](#grouptoml-toml))
| `<image>` | | | Image reference to be analyzed (usually the result of the previous build)
| `<layers>` | `CNB_LAYERS_DIR` | `/layers` | Path to layers directory
| `<log-level>` | `CNB_LOG_LEVEL` | `info` | Log Level
| `<skip-layers>`| `CNB_SKIP_LAYERS` | `false` | Do not perform layer analysis
| `<uid>` | `CNB_USER_ID` | | UID of the stack `User`

- **If** `<daemon>` is `false`, `<image>` MUST be a valid image reference
- **If** `<daemon>` is `true`, `<image>` MUST be either a valid image reference or an imageID
- The lifecycle MUST accept valid references to non-existent images without error.
| `<skip-layers>`| `CNB_SKIP_LAYERS` | `false` | Do not perform [layer restoration]((#layer-restoration)

##### Outputs
| Output | Description
|--------------------|----------------------------------------------
| [exit status] | (see Exit Code table below for values)
| `/dev/stdout` | Logs (info)
| `/dev/stderr` | Logs (warnings, errors)
| `<analyzed>` | Analysis metadata (see [`analyzed.toml`](#analyzedtoml-toml)
| `<layers>/<buidpack-id>/<layer>.sha` | Files containing the diffID of each analyzed layer
| Output | Description
|---------------------------------------|----------------------------------------------
| [exit status] | (see Exit Code table below for values)
| `/dev/stdout` | Logs (info)
| `/dev/stderr` | Logs (warnings, errors)
| `<layers>/<buidpack-id>/store.toml` | Persistent metadata (see data format in [Buildpack Interface Specification](buildpack.md))
| `<layers>/<buidpack-id>/<layer>.toml` | Files containing the layer content metadata of each analyzed layer (see data format in [Buildpack Interface Specification](buildpack.md))
| `<layers>/<buidpack-id>/<layer>/*`. | Restored layer contents

| Exit Code | Result|
|-----------|-------|
| `0` | Success
| `11` | Platform API incompatibility error
| `12` | Buildpack API incompatibility error
| `1-10`, `13-99` | Generic lifecycle errors
| `200-299` | Analysis-specific lifecycle errors
| `300-399` | Restoration-specific lifecycle errors

- The lifecycle MUST write [analysis metadata](#analyzedtoml-toml) to `<analyzed>` if `<image>` is accessible.
- **If** `<skip-layers>` is `true` the lifecycle MUST NOT perform layer analysis.
- **Else** the lifecycle MUST analyze any app image layers or cached layers created by any buildpack present in the provided `<group>`.
- For each buildpack in `<group>`, if persistent metadata for that buildpack exists in the analysis metadata, lifecycle MUST write a toml representation of the persistent metadata to `<layers>/<buildpack-id>/store.toml`
- **If** `<skip-layers>` is `true` the lifecycle MUST NOT perform layer restoration.
- **Else** the lifecycle MUST perform [layer restoration](#layer-restoration) for any app image layers or cached layers created by any buildpack present in the provided `<group>`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this apply to app image layers? #layer-restoration only talks about the cache.


##### Layer analysis
When analyzing a given layer the lifecycle SHALL:
##### Layer Restoration
When restoring a given layer the lifecycle SHALL:
- **If** `build=true`, `cache=false`:
- Do nothing
- **Else if** `launch=true`:
- Write layer metadata read from the analyzed image to `<layers>/<buildpack-id>/<layer-name>.toml`
- Write the layer diffID from the analyzed image to `<layers>/<buildpack-id>/<layer-name>.sha`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Write the layer diffID from the analyzed image to `<layers>/<buildpack-id>/<layer-name>.sha`

We don't need the .sha files anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 6480d2e

- **Else if** `cache=true` AND the cache DOES NOT contain a layer with matching diffID
- Must not write layer metadata
- **Else if** `cache=true`:
- Write layer metadata read from the cache to `<layers>/<buildpack-id>/<layer-name>.toml`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we are missing a description of when to restore cached layer contents? In the interest of normalized independent API maybe we should just refer out to https://github.com/buildpacks/spec/blob/main/buildpack.md#layer-types for a description of what to restore when. Then, any future changes could be a buildpack API concern. We merely need to say that the lifecycle must use the provided cache-dir or cache-image to retrieve layer contents.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a stab at removing all the detail here, but I might've removed too much. Let me know what you think. Fixed in 6480d2e

- Write the layer diffID from the cache to `<layers>/<buildpack-id>/<layer-name>.sha`

#### `restorer`
Usage:
```
/cnb/lifecycle/restorer \
[-cache-dir <cache-dir>]
[-cache-image <cache-image>]
[-gid <gid>] \
[-group <group>] \
[-layers <layers>] \
[-log-level <log-level>] \
[-uid <uid>]
```

##### Inputs
| Input | Environment Variable | Default Value | Description
|----------------|-----------------------|-----------------------|----------------------
| `<cache-dir>` | `CNB_CACHE_DIR` | | Path to a cache directory
| `<cache-image>`| `CNB_CACHE_IMAGE` | | Reference to a cache image in an OCI image registry
| `<gid>` | `CNB_GROUP_ID` | | Primary GID of the stack `User`
| `<group>` | `CNB_GROUP_PATH` | `<layers>/group.toml` | Path to group definition (see [`group.toml`](#grouptoml-toml))
| `<layers>` | `CNB_LAYERS_DIR` | `/layers` | Path to layers directory
| `<log-level>` | `CNB_LOG_LEVEL` | `info` | Log Level
| `<uid>` | `CNB_USER_ID` | | UID of the stack `User`
| `<layers>/<buidpack-id>/<layer>.sha` || | Files containing the diffID of each analyzed layer
| `<layers>/<buidpack-id>/<layer>.toml` || | Files containing the layer content metadata of each analyzed layer (see data format in [Buildpack Interface Specification](buildpack.md))

##### Outputs
| Output | Description
|------------------------------------|----------------------------------------------
| [exit status] | (see Exit Code table below for values)
| `/dev/stdout` | Logs (info)
| `/dev/stderr` | Logs (warnings, errors)
| `<layers>/<buidpack-id>/<layer>/*` | Restored layer contents

| Exit Code | Result|
|-----------|-------|
| `0` | Success
| `11` | Platform API incompatibility error
| `12` | Buildpack API incompatibility error
| `1-10`, `13-99` | Generic lifecycle errors
| `300-399` | Restoration-specific lifecycle errors

##### Layer restoration
For each layer metadata file found in the `<layers>` directory, the lifecycle:
- MUST restore cached layer contents if the cache contains a layer with matching diffID
- MUST remove layer metadata if `cache=true` AND the cache DOES NOT contain a layer with matching diffID

#### `builder`
The platform MUST execute `builder` in the **build environment**

Usage:
Usage:
```
/cnb/lifecycle/builder \
[-app <app>] \
Expand Down Expand Up @@ -808,7 +804,7 @@ The following variables SHOULD be set in the lifecycle execution environment and
|-----------------|--------------------------------------
| `CNB_STACK_ID` | Chosen stack ID
| `HOME` | Current user's home directory

The following variables SHOULD be set in the lifecycle execution environment and MAY be modified by prior buildpacks before they are provided to a given buildpack:

| Env Variable | Layer Path | Contents
Expand Down