Skip to content

Commit

Permalink
Simplify caching example in author guide
Browse files Browse the repository at this point in the history
Work out the gremlins in the caching example. We now cache
only the layer creating the runtime.

Signed-off-by: Aidan Delaney <[email protected]>
  • Loading branch information
AidanDelaney committed Nov 17, 2023
1 parent 2af0fd1 commit d0a0200
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@ One of the benefits of buildpacks is they can also populate the app image with m

You can find some of this information using `pack` via its `inspect-image` command. The bill-of-materials information will be available using `pack sbom download`.

<!-- test:exec -->
```bash
pack inspect-image test-node-js-app
```
<!--+- "{{execute}}"+-->
You should see the following:

<!-- test:assert=contains;ignore-lines=... -->
```text
Run Images:
cnbs/sample-base-run:jammy
Expand Down Expand Up @@ -123,29 +120,29 @@ plan=$3
node_js_layer="${layersdir}"/node-js
mkdir -p "${node_js_layer}"

# ======= MODIFIED =======
# 3. DOWNLOAD node-js
node_js_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "node-js") | .metadata.version') || "18.18.1"
node_js_url=https://nodejs.org/dist/v18.18.1/node-v${node_js_version}-linux-x64.tar.xz
remote_nodejs_version=$(cat "${layersdir}/node-js.toml" 2> /dev/null | yj -t | jq -r .metadata.nodejs-version 2>/dev/null || echo 'NOT FOUND')
default_node_js_version="18.18.1"
node_js_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "node-js") | .metadata.version' || echo ${default_node_js_version})
node_js_url=https://nodejs.org/dist/v${node_js_version}/node-v${node_js_version}-linux-x64.tar.xz
remote_nodejs_version=$(cat "${layersdir}/node-js.toml" 2> /dev/null | yj -t | jq -r .metadata.nodejs_version 2>/dev/null || echo 'NOT FOUND')
if [[ "${node_js_url}" != *"${remote_nodejs_version}"* ]] ; then
echo "-----> Downloading and extracting NodeJS"
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
cat >> "${layersdir}/node-js.toml" << EOL
[metadata]
nodejs-version = "${node_js_version}"
EOL
else
echo "-----> Reusing NodeJS"
fi

# 4. MAKE node-js AVAILABLE DURING LAUNCH and CACHE the LAYER
echo -e '[types]\ncache = true\nlaunch = true' > "${layersdir}/node-js.toml"
cat > "${layersdir}/node-js.toml" << EOL
[types]
cache = true
launch = true
[metadata]
nodejs_version = "${node_js_version}"
EOL

# ========== ADDED ===========
# 5. SET DEFAULT START COMMAND
cat > "${layersdir}/launch.toml" << EOL
cat >> "${layersdir}/launch.toml" << EOL
[[processes]]
type = "web"
command = "node app.js"
Expand All @@ -154,8 +151,8 @@ EOL

# ========== ADDED ===========
# 6. ADD A SBOM
node-jsbom="${layersdir}/node-js.sbom.cdx.json"
cat >> ${node-jsbom} << EOL
node_jsbom="${layersdir}/node-js.sbom.cdx.json"
cat >> ${node_jsbom} << EOL
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
Expand Down Expand Up @@ -196,7 +193,6 @@ cat layers/sbom/launch/examples_node-js/node-js/sbom.cdx.json | jq -M

You should find that the included `node-js` version is `18.18.1` as expected.

<!-- test:assert=contains;ignore-lines=... -->
```text
{
"bomFormat": "CycloneDX",
Expand All @@ -207,7 +203,7 @@ You should find that the included `node-js` version is `18.18.1` as expected.
"type": "library",
"name": "node-js",
"version": "18.18.1"
},
}
...
]
}
Expand Down
32 changes: 18 additions & 14 deletions content/docs/buildpack-author-guide/create-buildpack/caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Reusing layer 'examples/node-js:node-js'

## Caching dependencies

Now, let's implement the caching logic. We need to record the version of the NodeJS runtime that is used in a build. On subsequent builds, the caching logic will detect the current requested NodeJS version and restore the previous layer from the cache if the current requested NodeJS version matches the previous NodeJS runtime version.
Now, let's implement the caching logic. We need to record the version of the NodeJS runtime that is used in a build. On subsequent builds, the caching logic will detect if the NodeJS version is the same as the version in the cached layer. We restore the previous layer from the cache if the current requested NodeJS version matches the previous NodeJS runtime version.

<!-- test:file=node-js-buildpack/bin/build -->
```
Expand All @@ -97,39 +97,43 @@ layersdir=$1
node_js_layer="${layersdir}"/node-js
mkdir -p "${node_js_layer}"
# ======= MODIFIED =======
# 3. DOWNLOAD node-js
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
remote_nodejs_version=$(cat "${layersdir}/node-js.toml" 2> /dev/null | yj -t | jq -r .metadata.nodejs-version 2>/dev/null || echo 'NOT FOUND')
if [[ "${node_js_url}" != *"${remote_nodejs_version}"* ]] ; then
node_js_version="18.18.1"
node_js_url=https://nodejs.org/dist/v${node_js_version}/node-v${node_js_version}-linux-x64.tar.xz
cached_nodejs_version=$(cat "${layersdir}/node-js.toml" 2> /dev/null | yj -t | jq -r .metadata.nodejs_version 2>/dev/null || echo 'NOT FOUND')
if [[ "${node_js_url}" != *"${cached_nodejs_version}"* ]] ; then
echo "-----> Downloading and extracting NodeJS"
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
cat >> "${layersdir}/node-js.toml" << EOL
[metadata]
nodejs-version = "18.18.1"
EOL
else
echo "-----> Reusing NodeJS"
fi
# ======= MODIFIED =======
# 4. MAKE node-js AVAILABLE DURING LAUNCH and CACHE the LAYER
echo -e '[types]\ncache = true\nlaunch = true' > "${layersdir}/node-js.toml"
cat > "${layersdir}/node-js.toml" << EOL
[types]
cache = true
launch = true
[metadata]
nodejs_version = "${node_js_version}"
EOL
# ========== ADDED ===========
# 5. SET DEFAULT START COMMAND
cat > "${layersdir}/launch.toml" << EOL
cat >> "${layersdir}/launch.toml" << EOL
[[processes]]
type = "web"
command = "node app.js"
default = true
EOL
```

Now when you build your app:
Now when you build your app, the second call will reuse the layer:

<!-- test:exec -->
```text
pack build test-node-js-app --path ./node-js-sample-app --buildpack ./node-js-buildpack
pack build test-node-js-app --path ./node-js-sample-app --buildpack ./node-js-buildpack
```
<!--+- "{{execute}}"+-->

Expand All @@ -140,7 +144,7 @@ you will see the new caching logic at work during the `BUILDING` phase:
===> BUILDING
...
---> NodeJS Buildpack
---> Reusing node-js
-----> Reusing NodeJS
```

Next, let's see how buildpack users may be able to provide configuration to the buildpack.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,29 @@ mkdir -p "${node_js_layer}"

# ======= MODIFIED =======
# 3. DOWNLOAD node-js
node_js_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "node-js") | .metadata.version') || "18.18.1"
node_js_url=https://nodejs.org/dist/v18.18.1/node-v${node_js_version}-linux-x64.tar.xz
remote_nodejs_version=$(cat "${layersdir}/node-js.toml" 2> /dev/null | yj -t | jq -r .metadata.nodejs-version 2>/dev/null || echo 'NOT FOUND')
default_node_js_version="18.18.1"
node_js_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "node-js") | .metadata.version' || echo ${default_node_js_version})
node_js_url=https://nodejs.org/dist/v${node_js_version}/node-v${node_js_version}-linux-x64.tar.xz
remote_nodejs_version=$(cat "${layersdir}/node-js.toml" 2> /dev/null | yj -t | jq -r .metadata.nodejs_version 2>/dev/null || echo 'NOT FOUND')
if [[ "${node_js_url}" != *"${remote_nodejs_version}"* ]] ; then
echo "-----> Downloading and extracting NodeJS"
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
echo "-----> Downloading and extracting NodeJS" ${node_js_version}
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
cat >> "${layersdir}/node-js.toml" << EOL
[metadata]
nodejs-version = "${node_js_version}"
EOL
else
echo "-----> Reusing NodeJS"
fi

# 4. MAKE node-js AVAILABLE DURING LAUNCH and CACHE the LAYER
echo -e '[types]\ncache = true\nlaunch = true' > "${layersdir}/node-js.toml"
cat > "${layersdir}/node-js.toml" << EOL
[types]
cache = true
launch = true
[metadata]
nodejs_version = "${node_js_version}"
EOL

# ========== ADDED ===========
# 5. SET DEFAULT START COMMAND
cat > "${layersdir}/launch.toml" << EOL
cat >> "${layersdir}/launch.toml" << EOL
[[processes]]
type = "web"
command = "node app.js"
Expand All @@ -92,11 +94,11 @@ Finally, create a file `node-js-sample-app/.node-js-version` with the following
18.18.1
```

Now when you run:
In the following `pack` invocation we choose to `--clear-cache` so that we explicitly do not re-use cached layers. This helps us demonstrate that the NodeJS runtime layer does not get restored from a cache.

<!-- test:exec -->
```bash
pack build test-node-js-app --path ./node-js-sample-app --buildpack ./node-js-buildpack
pack build test-node-js-app --clear-cache --path ./node-js-sample-app --buildpack ./node-js-buildpack
```
<!--+- "{{execute}}"+-->

Expand All @@ -107,7 +109,7 @@ You will notice that version of NodeJS specified in the app's `.node-js-version`
===> BUILDING
...
---> NodeJS Buildpack
---> Downloading and extracting NodeJS 18.18.1
-----> Downloading and extracting NodeJS 18.18.1
```

Next, let's see how buildpacks can store information about the dependencies provided in the output app image for introspection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
wget -q -O - "$node_js_url" | tar -xJf - --strip-components 1 -C "${node_js_layer}"

# 4. MAKE node-js AVAILABLE DURING LAUNCH
echo -e '[types]\nlaunch = true' > "${layersdir}/node-js.toml"
cat > "${layersdir}/node-js.toml" << EOL
[types]
launch = true
EOL

# ========== MODIFIED ===========
# 5. SET DEFAULT START COMMAND
Expand Down

0 comments on commit d0a0200

Please sign in to comment.