This is a simple Cloud Native Buildpack wrapping the set of legacy Cloud Foundry buildpacks. It allows kpack to use legacy Cloud Foundry buildpacks on apps that previously built and ran in Cloud Foundry for VMs, but might not yet build or run successfully with the new Paketo buildpacks.
To build and install it in a cf-for-k8s cluster, run ./scripts/deploy.sh
in this repository.
The script builds the buildpack, pushes the image and patches the ClusterStore on the cluster.
The only manual step is to edit the kpack Builder in the cf-workloads-staging
namespace and replace all of the buildpacks there with this buildpack.
It should look something like:
apiVersion: kpack.io/v1alpha1
kind: Builder
name: cf-default-builder
namespace: cf-workloads-staging
...
spec:
order:
- group:
- id: org.cloudfoundry.buildpacks.legacy
...
The buildpack is configured by two environment variables - BUILDPACK_ORDER
and SKIP_DETECT
.
Since the cf buildpacks
family of commands now configure kpack instead of actually putting them in the blobstore, to override the default buildpacks, you need to either set them in staging-environment-variable-group or in the app manifest.
For example:
cf set-staging-environment-variable-group '{"BUILDPACK_ORDER":"<buildpack1-url>,<buildpack2-url>,...", SKIP_DETECT: true}'
or using the manifest:
---
applications:
- name: my-app
env:
BUILDPACK_ORDER: "<buildpack1-url>,<buildpack2-url>,..."
SKIP_DETECT: true
The default values are currently in the build script here. Note that this contains only the ruby, node, golang and static buildpacks used as a proof of concept.
The buildpack implements the cloud native buildpack spec by supplying the bin/build
and bin/detect
scripts.
The detect script always returns 0, because this buildpack contains all legacy buildpacks and overrides the new buildpacks.
The build script uses the legacy buildpackapplifecycle builder to perform the build, exactly as in Cloud Foundry for VMs.
It translates the environment from and to the CNB structure before and after the build.
The builder is given the buildpack order via the BUILDPACK_ORDER
env var and whether to skip detection with the SKIP_DETECT
env var.
The later is useful if you want to use a specific buildpack to build your app, that doesn't implement the detect script (for example the binary-buildpack).
The build script uses the caching built into CNBs to provide the required cache directory to the legacy builder.
It copies the buildcache to a directory in /tmp
prior to invoking the builder to overcome problems with hard links created by the buildpacks which might end up as cross-filesystem and erroring.
The buildcache layer is updated with the final cache state after the legacy build.
The legacy builder creates a droplet tarball which is extracted into a temporary layer, and then copied to the /workspace
directory.
Permissions, in particular setgid bits, prevent extracting directly to /workspace
.
The final step is to make the extracted droplet executable by the CNB launcher.
Rather than invoking the launcher from buildpackapplifecycle, its functionality is reproduced in a .profile
file sourced by the CNB lifecycle.
This sources all the files that the legacy launcher would have sourced, setting PATH and all the required environment variables, and changes the working directory to /workspace/app
.
Finally the start command is parsed from staging_info.yml
and set in the launch.toml.
Reproducing the launcher's CalcEnv in its entirety:
- Setting DATABASE_URL and VCAP_* env vars appropriately during launch
- Interpolating credhub secrets during launch