-
Notifications
You must be signed in to change notification settings - Fork 70
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
Idea for major (breaking) change: merge cache and launch directories #23
Comments
I am very excited about the simplification this allows for buildpack authors, and removing their code to copy between cache and launch layers. I don't personally object to
My feeling is to try and get some benchmarks for performance of Everything else looks great to me. |
My concern is that wide use of this functionality would unnecessarily increase build time and data transfer. Currently, builds don't have any mandatory network requirements. If buildpack authors use this feature often, FS layer downloads from the registry would be required in many or most scenarios before a build can start. However, considering:
as well as requests for the functionality in certain cases (#8, as well as the need to preserve |
Note: I removed the build plan changes due to feedback pointing out that it wouldn't work without adding a |
This would be a welcome change, especially when working on buildpacks for interpreted languages, such as nodejs, where there are multiple starting states and edge cases to handle: vendored vs unvendored node_modules, location of the package.json, how to handle the npm-cache, etc. In practice, there is a lot of minutiae (and many code branches... and many potential bugs/pitfalls) in determining where and when to place dependencies, all while trying to gain an understanding of the V3 spec as a new buildpack author. Any complexity we can push into the platform while maintaining functionality (our cache and launch layers almost always end up the same) is useful. |
New proposal for the build plan: #24 |
As @djoyahoy mentioned this simplifies things immensely for buildpacks for interpreted languages. I recently created a ruby buildpack to be used for a blog post about how to create buildpacks. In doing so I created the same buildpack multiple times from scratch to help myself explain the buildpack to my co-author and even with that we had bugs in our code related to copying things (eg. ruby) between the cache dir and the launch dir. Combining the directories would remove about half (of my admittedly simplistic) buildpack. (https://github.com/dgodd/ruby-cnb-buildpack) I also found it very hard to explain to my co-author, or in the blog post why we had to copy directories around so much, and why that was better than not doing so. One of my fears is that with the current copy around approach, almost no buildpacks will correctly implement the ability for later buildpacks to use their interpreter during staging, either due to incorrect copying (or not) of directories, or environment variables that point to launch directories in both staging and launch (and ofcourse the launch directory will often not be there during staging) |
Updated to reflect 10/30/2018 WG discussion. Note the "Behavior Changes" section for the complexity/performance trade-offs. Please leave feedback, or 👍 if you would like this change to be integrated into the spec and lifecycle. |
If we're going ahead with the combination of layers, then we should move the export fields into the |
@nebhale updated |
We currently have two ways to specify environment variables depending on whether the layer is used for build or launch. Given that many times the same environment variables need to be set in both cases ( If they should be different, should there be two different ways of specifying those variables, or should the |
Given that this proposal allows a layer to be used for both build and launch, I think that layer will need the ability to specify separate build-time and run-time environment variables. I think it's worth exploring whether we should have a shortcut for setting them at the same time.
I went ahead and split |
Update: After considering the different combinations of options and applying to them to various buildpack use cases, I think we can reduce the four options to just three:
Where:
This should further reduce buildpack complexity. |
@sclevine that's a nice improvement. Are those the defaults you're proposing? Do we want to default |
@sclevine What is the use case for |
Sorry, didn't mean to suggest defaults yet. Defaults could be all false (layer is just a temporary storage location for the current buildpack), or just
|
@sclevine i understand the mechanics of |
Note: This proposal has been edited. Comments below it may be outdated. See the edit history for previous versions.
After reviewing the various initial buildpack implementations, I've observed these patterns, anti-patterns, and limitations:
launch
andbuild
booleans as top-level keys in the build plan #22)./bin/build
script to make a symlink from the app directory to a layer that remains unbroken during both build and launch. Separately, relative symlinks from layers to the app directory are easy to break when copying layer directories between cache and launch dirs.Proposal
Instead of providing separate launch and cache directories to each buildpack, we could provide a single
<layers>
directory with the following extra, top-level fields in each<layer>.toml
:Rules:
<layer>.toml
is always restored.launch && cache && !persist-cache
, but the local layer contents do not match the remote layer contents, then the cached local layer is deleted before the build and the remote metadata is provided. This ensures that recovered local layers are never out of sync with remote layers.!launch && cache && persist-cache
, the build fails unless/until we decide to support a persistent cache that isn't used in the remote image.launch
to!launch
, then the remote layer is deleted.cache && persist-cache
as long as the cached layers are only restored when they are identical to the remote launch layers.!build
layers should always be moved such that they are inaccessible to subsequent buildpacks.The combined
<layers>
directory would continue to look like this:The new interface would be:
Executable:
/bin/build <platform[AR]> <layers[EI]>
, Working Dir:<app[AI]>
/dev/stdin
<platform>/env/
<platform>/#
/dev/stdout
/dev/stderr
<layers>/launch.toml
<layers>/<layer>.toml
<layers>/<layer>/bin/
<layers>/<layer>/lib/
<layers>/<layer>/profile.d/
<layers>/<layer>/include/
<layers>/<layer>/pkgconfig/
<layers>/<layer>/env/
<layers>/<layer>/env.build/
<layers>/<layer>/env.run/
<layers>/<layer>/*
READ THIS: New Behavior Introduced:
persist-cache
requires downloading layers from the registry before the build, but provides a guaranteed, globally-persistent cache.<layers>/<layer>/env/
directory is split into<layers>/<layer>/env/build/
and<layers>/<layer>/env/run/
to make the behavior of the directory more clear and to provide a safer, more convenient way to set runtime environment variables.Advantages:
Disadvantages:
persist-cache
due to registry downloadingPossible Extensions:
!launch && cache && persist-cache
in the future using a dedicated image repository (or tag in the same repository). This would be entirely backwards-compatible when introduced.Thoughts? If desired, we should make this change before ratifying v3.0.0 of the specification.
@nebhale @jkutner @hone @ekcasey @dgodd @jchesterpivotal @ameyer-pivotal
The text was updated successfully, but these errors were encountered: