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

RFC: System Buildpacks #179

Merged
merged 17 commits into from
Mar 4, 2022
Merged
Changes from 11 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
145 changes: 145 additions & 0 deletions text/0000-system-buildpacks-in-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Meta
[meta]: #meta
- Name: System Buildpacks in Builder Images
- Start Date: 2021-07-24
- Author(s): [@jkutner](https://github.com/jkutner)
- RFC Pull Request: (leave blank)
- CNB Pull Request: (leave blank)
- CNB Issue: (leave blank)
- Supersedes: N/A

# Summary
[summary]: #summary

This is a proposal for a mechanism that would allow a builder to contain a default set of buildpacks that participate in every detection group, regardless of the buildpack order passed by the platform.

# Definitions
[definitions]: #definitions

* _system buildpacks_ - a standard buildpack, conforming to the Buildpack API, which participate in all groups

# Motivation
[motivation]: #motivation

Forthcoming changes to the lifecycle (such as [removal of shell-specific logic](https://github.com/buildpacks/rfcs/pull/168)) will remove capabilities that users have come to expect. This includes mechanisms like `.profile`, which allows a buildpack user to customize the environment a process type runs in. We seek to replace these lost mechanisms with buildpacks, in an effort to preserve the capability while still removing complexity from the lifecycle.

# What it is
[what-it-is]: #what-it-is

We introduce a `[system]` table in the `builder.toml` schema with the following structure:

```
[[system.pre.buildpacks]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = false

[[system.post.buildpacks]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = false
```

The fields in the `system.pre.buildpacks` table and `system.post.buildpacks` table match the fields in the existing [`order.group` table](https://buildpacks.io/docs/reference/config/builder-config/#order-_list-required_).

When a builder includes one or more `system.*.buildpacks` entry, the detect phase will prepend and append all `pre` and `post` buildpacks to each detection group in the provided order, respectively.

**Note:** A non-`optional` system buildpack creates the possibility that a user provided group with all optional buildpacks could pass detection when it otherwise would not. We leave that up to the platform/builder owner. As long as the platform has a mechanism to disable system buildpacks (and `pack` will), then there is an escape valve for this situation.

# How it Works
[how-it-works]: #how-it-works

Unless otherwise stated, system buildpacks conform to the [buildpack API](https://github.com/buildpacks/spec/blob/main/buildpack.md).
jkutner marked this conversation as resolved.
Show resolved Hide resolved

The `system.*pre*.buildpacks` will be provided to the lifecycle into a new file, `system.toml`. The `[system]` table in `system.toml` will be processed by the lifecycle, and each `pre`/`post` buildpack will run during the detect phase. Those that pass detection will run during the build phase.

## Detection

The exit code of detection by system buildpacks MUST influence the selected buildpack group. If a system buildpack is non-optional and fails detection, then detection MUST for that group fail. If a system buildpack is optional and passes detection, then detection MAY pass for that group.

System buildpacks may require/provide in the build plan following standard buildpack API specification.
Copy link
Member

@hone hone Aug 11, 2021

Choose a reason for hiding this comment

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

Do you have use cases for system buildpacks you're thinking of that would use the Build Plan? I think with how much you want to "hide" system buildpacks if it's bad that they'd influence the other buildpack execution.

Copy link
Member Author

Choose a reason for hiding this comment

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

I have no specific examples/use-cases. I only wanted to default to the having them be the "same" as normal buildpacks

Copy link
Member

Choose a reason for hiding this comment

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

I am not so sure on including system buildpacks in the buildplan if they are not interacting with the normal buildpacks in a group. Could we either limit the system buildpacks plan resolution to their respective groups? pre system buildpacks need to match up all their plan entries separately, normal buildpacks separately and post buildpacks separately.

Given that we want to discourage people from using system buildpacks as hidden buildpacks and given that these are mainly supposed to be utility buildpacks - would a simplifying assumption be to remove system buildpacks from contributing to the build plan entirely? And limit them to just detect pass or fail?

Copy link
Member Author

Choose a reason for hiding this comment

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

Could we either limit the system buildpacks plan resolution to their respective groups?

Meaning they have their own plan, distinct from user defined buildpacks? I think that's a good idea.

I'm fine with any of these, but I agree that I should probably be more specific about which behavior we want in the RFC.

Copy link
Member

Choose a reason for hiding this comment

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

Should we just have buildpacks not be part of the buildplan for now if we don't have a use case for it?


## Build

System buildpacks that have passed detection will be added to `group.toml` and treated like any other buildpack for the remainder of the build.

If a system buildpack exits with a status of `100`, the build will fail.

# Drawbacks
[drawbacks]: #drawbacks

- Default system buildpacks are hidden from the user before the build and their execution may be unexpected.
jkutner marked this conversation as resolved.
Show resolved Hide resolved
jkutner marked this conversation as resolved.
Show resolved Hide resolved

# Alternatives
[alternatives]: #alternatives

## Do Nothing

End users would have to add buildpacks like the `profile-buildpack` or other buildpacks that implement system/spec behaviors themselves.

## Use the `[[order]]` table

Instead of a new `[system]` table, we could put `pre` and `post` in the `[[order]]` table. However, this could imply that there is a interaction/override/etc between these buildpacks and the `pre`/`post` buildpacks in `project.toml`. But there is not.
Copy link
Member

Choose a reason for hiding this comment

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

I kind of like this alternative builder.toml schema? But it's not a strong preference.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't have a strong preference


## Use the `[lifecycle]` table

```
[lifecycle]
version = "<string>"

[[lifecycle.pre.buildpacks]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = false

[[lifecycle.post.buildpacks]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = false
```

# Prior Art
[prior-art]: #prior-art

- [RFC-0078: Group additions to Builder order](https://github.com/buildpacks/rfcs/blob/main/text/0078-group-additions.md)

# Unresolved Questions
[unresolved-questions]: #unresolved-questions

- Should the system buildpacks that pass detection be added to the buildpack group? This might make it difficult to hide them.
- disposition: yes. hiding is optional and up to the platform
jkutner marked this conversation as resolved.
Show resolved Hide resolved
- Should the system buildpacks output to stdout/stderr and should that be displayed?
- disposition: it may be
jkutner marked this conversation as resolved.
Show resolved Hide resolved

# Spec. Changes (OPTIONAL)
[spec-changes]: #spec-changes

## `detector` in Platform specifiction

This proposal introduces a `--system` option on the `detector`.

```
/cnb/lifecycle/detector \
[--system <system>]\
```

Where:

* the lifecycle SHALL merge the `pre` group with each group from `<system>` such that the `pre` buildpacks are placed at the beginning of each order group before running detection.
* SHALL merge the `post` group with each group from `<system>` such that the `post` buildpacks are placed at the end of each order group before running detection.

#### `system.toml` (TOML)

```toml
[[system.pre.buildpacks]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = true

[[system.post.buildpacks]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = true
```