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

Add RFC to define mixins for the Bionic stack #40

Merged
merged 10 commits into from
Mar 29, 2020
87 changes: 87 additions & 0 deletions text/0000-bionic-mixins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Meta
[meta]: #meta
- Name: Defining Mixins for io.buildpacks.stacks.bionic
- Start Date: 2019-12-05
- CNB Pull Request: (leave blank)
- CNB Issue: (leave blank)
- Supersedes: (put "N/A" unless this replaces an existing RFC, then link to that RFC)

# Summary
[summary]: #summary

The Platform API specification allows stack maintainers to define stack mixins for a given stack.
The Cloud Native Buildpacks project informally defines stack build and run images with ID `io.buildpacks.stacks.bionic` as containing exactly the set of Ubuntu packages in the `ubuntu:bionic` image on Docker Hub.
This RFC proposes that we formalize the existing definition of `io.buildpacks.stacks.bionic` and define mixins on that stack to be Ubuntu 18.04 LTS packages.

In general, a stack is a contract that should be more like "Ubuntu Bionic" and less like "Platform XYZ's Re-distribution of Ubuntu Bionic."
Stack images can still be provided by platforms/vendors, but they should use the standard CNB stack contracts where applicable.

# Proposal
[proposal]: #proposal

This RFC proposes that apply the following set of restrictions to base images marked with stack ID `io.buildpacks.stacks.bionic`:
1. The base set of packages is the set of packages distributed in `ubuntu:bionic` with `ca-certificates`, `libssl1.1`, and `openssl` added. The base image does not have to be derived from the `ubuntu:bionic` image, but must contain packages that provide exactly the same functionality to processes running as the CNB-specified, non-root user.
2. When invoked as root, `apt-get` must be configured to use at minimum the set of package repositories that `ubuntu:bionic` is configured to use. `apt-get update` may be needed to download the package repository indices before `apt-get install` is functional.
Comment on lines +23 to +24
Copy link
Member Author

Choose a reason for hiding this comment

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

@briandealwis do these clarifications address your concerns?

Copy link
Contributor

Choose a reason for hiding this comment

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

lgtm, thanks

3. Mixins without an `=` are Ubuntu 18.04 LTS package names without version or architecture info from official package mirrors.
4. Mixins that begin with `set=` are defined by the project as such:
a. `build:set=shell-utils` represents the change set: `build:curl`, `build:jq`, and yj CLI at build-time.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
a. `build:set=shell-utils` represents the change set: `build:curl`, `build:jq`, and yj CLI at build-time.
a. `build:set=shell-utils` represents the change set: `build:curl`, `build:jq`, and `build:yj` at build-time.

Copy link
Member Author

Choose a reason for hiding this comment

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

yj is not available as an Ubuntu package, so I went with "yj CLI at build-time" instead of "build:yj."

Maybe it's worth defining build:set=yj as well?



# Motivation
[motivation]: #motivation

This will allow:
1. Buildpack authors to publish buildpacks that are compatible with more stack images without requiring those authors to explicitly specify vendor-specific stack IDs.
Copy link
Contributor

Choose a reason for hiding this comment

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

How can a platform specify that their custom stack adheres to io.buildpacks.stacks.bionic? (How would heroku/buildpacks:18 transition, considering there are Buildpacks in the wild relying on the heroku-18 stack ID?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Platforms could publish new images with the io.buildpacks.stacks.bionic ID to new image tags and deprecate their bespoke stack image tags once everyone has migrated.

Alternatively, platforms could give buildpack authors a certain amount of time to add both stacks to their buildpack.toml files before publishing images with the io.buildpacks.stacks.bionic ID over the existing image tags.

2. Vendor-specific buildpacks to work together in the same build, as long as those buildpacks support `io.buildpacks.stacks.bionic`.
Copy link
Member

Choose a reason for hiding this comment

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

Definitely interested in this use case on the Heroku side as we've working more with the Riff folks. Forking a buildpack just to change the buildpack.toml isn't great.

3. App developers to create custom stack images that are compatible with any set of buildpacks that support `io.buildpacks.stacks.bionic`.

# Example
[example]: #example

Say `org.cloudfoundry.stacks.cfbionicstack` is `ubuntu:bionic`, but with `build-essentials` in the build image and `git` in both build and run images.

We would change the image metadata from:
```
run stackID: "org.cloudfoundry.stacks.cfbionicstack"
run mixins: []
build stackID: "org.cloudfoundry.stacks.cfbionicstack"
build mixins: []
```
To:
```
run stackID: "io.buildpacks.stacks.bionic"
Copy link
Member

Choose a reason for hiding this comment

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

I would imagine that you may keep the cfbionicstack as a stackID. A stack image may not just be the base image + some packages. I was originally expecting some linkage that heroku-18 is ubuntu:bionic plus some extra mixins as far as a buildpack is concerned, but is also its own stackID.

Copy link
Member

Choose a reason for hiding this comment

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

Even if the image includes things beyond "base image + some packages", do the buildpacks depend on those differences to execute successfully?

If not, these images can still declare their stack ID to be io.buildpacks.stacks.bionic despite these differences. If so, these buildpacks won't be interoperable with other platforms.

run mixins: ["git"]
build stackID: "io.buildpacks.stacks.bionic"
build mixins: ["build:build-essential", "git"]
```

And buildpack authors would update their `buildpack.toml` files from:
```toml
[[stacks]]
id = "org.cloudfoundry.stacks.cfbionicstack"
```
To:
```toml
[[stacks]]
id = "io.buildpacks.stacks.bionic"
mixins = ["build:build-essential", "git"] # NOTE: only need to list mixins they actually require!
```

# Drawbacks
[drawbacks]: #drawbacks

- This could encourage buildpack authors and app developers to create a large number of unmaintained stack images that have different sets of Ubuntu packages.
- Breaking change for buildpack authors once old stack images are removed.

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

- Neither the spec nor this RFC suggest whether or not stack authors or app developers are allowed to make additional changes to stack images without using mixin metadata.
- When package groups (like `build-essential`) or dependent packages are installed, must stack images always specify all the packages added? Or is it only necessary when stack image authors want buildpacks to be able to depend on the dependent packages?
Copy link
Contributor

Choose a reason for hiding this comment

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

The latter. In order to make a mixin as broadly compatible as possible you'll probably want to list both the package group and all the packages that it includes.

Copy link
Member Author

Choose a reason for hiding this comment

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

So your suggestion is that stack authors should add all packages to the mixin list, but are not required to? Would this imply that a given stack run/build image can have arbitrary contents that aren't specified by the ID or mixins, as long as those contents don't disappear when newer versions are published?

- For usability, should we create a single-mixin "shortcut" notation for the stack ID (e.g., `io.buildpacks.stacks.bionic#shell-utils`)? This would require a spec change and updates to pack, the lifecycle, and other CNB tools, so I'd like to leave it for a different RFC.
- Where should we list all of the package sets for `io.buildpacks.stacks.bionic`? On buildpacks.io? In a new section of the spec?

# Alternatives
[alternatives]: #alternatives

- Continue to maintain separate vendor-specific stack IDs.