Skip to content

Commit f3f0407

Browse files
authored
Merge pull request cds-hooks#465 from buildpacks/api-0.7
2 parents 96ee660 + d2d67b4 commit f3f0407

File tree

7 files changed

+373
-59
lines changed

7 files changed

+373
-59
lines changed

.gitpod.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ ports:
33
onOpen: open-preview
44

55
tasks:
6-
- init: make build
6+
- name: Setup
7+
before: chmod ugo+w /var/run/docker.sock
8+
init: make build
9+
command: chmod ugo+w /var/run/docker.sock
710

811
github:
912
prebuilds:

content/docs/buildpack-author-guide/create-buildpack/adding-bill-of-materials.md

Lines changed: 113 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ One of the benefits of buildpacks is they can also populate the app image with m
1212
* The buildpacks were used to create the app image
1313
* And more...!
1414

15-
You can find all of this information using `pack` via its `inspect-image` command.
15+
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`.
1616

1717
<!-- test:exec -->
1818
```bash
@@ -38,18 +38,77 @@ Processes:
3838

3939
Apart from the above standard metadata, buildpacks can also populate information about the dependencies they have provided in form of a `Bill-of-Materials`. Let's see how we can use this to populate information about the version of `ruby` that was installed in the output app image.
4040

41-
To add the `ruby` version to the output of `pack inspect-image`, we will have to provide a `Bill-of-Materials` (`BOM`) containing this information. You'll need to update the `launch.toml` created at the end of your `build` script:
41+
To add the `ruby` version to the output of `pack download sbom`, we will have to provide a [Software `Bill-of-Materials`](https://en.wikipedia.org/wiki/Software_bill_of_materials) (`SBOM`) containing this information. There are three "standard" ways to report SBOM data. You'll need to choose to use on of [CycloneDX](https://cyclonedx.org/), [SPDX](https://spdx.dev/) or [Syft](https://github.com/anchore/syft) update the `ruby.sbom.<ext>` (where `<ext>` is the extension appropriate for your SBOM standard, one of `cdx.json`, `spdx.json` or `syft.json`) at the end of your `build` script. Discussion of which SBOM format to choose is outside the scope of this tutorial, but we will note that the SBOM format you choose to use is likely to be the output format of any SBOM scanner (eg: [`syft cli`](https://github.com/anchore/syft)) you might choose to use. In this example we will use the CycloneDX json format.
42+
43+
First, annotate the `buildpack.toml` to specify that it emits CycloneDX:
44+
45+
<!-- test:file=ruby-buildpack/buildpack.toml -->
46+
```toml
47+
# Buildpack API version
48+
api = "0.7"
49+
50+
# Buildpack ID and metadata
51+
[buildpack]
52+
id = "examples/ruby"
53+
version = "0.0.1"
54+
sbom-formats = [ "application/vnd.cyclonedx+json" ]
55+
56+
# Stacks that the buildpack will work with
57+
[[stacks]]
58+
id = "io.buildpacks.samples.stacks.bionic"
59+
```
60+
61+
Then, in our buildpack implemetnation we will generate the necessary SBOM metadata:
4262

4363
```bash
4464
# ...
4565

4666
# Append a Bill-of-Materials containing metadata about the provided ruby version
47-
cat >> "$layersdir/launch.toml" << EOL
48-
[[bom]]
49-
name = "ruby"
50-
[bom.metadata]
51-
version = "$ruby_version"
67+
cat >> "$layersdir/ruby.sbom.cdx.json" << EOL
68+
{
69+
"bomFormat": "CycloneDX",
70+
"specVersion": "1.4",
71+
"version": 1,
72+
"components": [
73+
{
74+
"type": "library",
75+
"name": "ruby",
76+
"version": "$ruby_version"
77+
}
78+
]
79+
}
80+
EOL
81+
```
82+
83+
We can also add an SBOM entry for each dependency listed in `Gemfile.lock`. Here we use `jq` to add a new record to the `components` array in `bundler.sbom.cdx.json`:
84+
85+
```bash
86+
crubybom="${layersdir}/ruby.sbom.cdx.json"
87+
cat >> ${rubybom} << EOL
88+
{
89+
"bomFormat": "CycloneDX",
90+
"specVersion": "1.4",
91+
"version": 1,
92+
"components": [
93+
{
94+
"type": "library",
95+
"name": "ruby",
96+
"version": "$ruby_version"
97+
}
98+
]
99+
}
52100
EOL
101+
if [[ -f Gemfile.lock ]] ; then
102+
for gem in $(gem dep -q | grep ^Gem | sed 's/^Gem //')
103+
do
104+
version=${gem##*-}
105+
name=${gem%-${version}}
106+
DEP=$(jq --arg name "${name}" --arg version "${version}" \
107+
'.components[.components| length] |= . + {"type": "library", "name": $name, "version": $version}' \
108+
"${rubybom}")
109+
echo ${DEP} > "${rubybom}"
110+
done
111+
fi
53112
```
54113

55114
Your `ruby-buildpack/bin/build`<!--+"{{open}}"+--> script should look like the following:
@@ -128,14 +187,33 @@ command = "bundle exec ruby worker.rb"
128187
EOL
129188
130189
# ========== ADDED ===========
131-
# 9. ADD A BOM
132-
cat >> "$layersdir/launch.toml" << EOL
133-
[[bom]]
134-
name = "ruby"
135-
[bom.metadata]
136-
version = "$ruby_version"
190+
# 9. ADD A SBOM
191+
rubybom="${layersdir}/ruby.sbom.cdx.json"
192+
cat >> ${rubybom} << EOL
193+
{
194+
"bomFormat": "CycloneDX",
195+
"specVersion": "1.4",
196+
"version": 1,
197+
"components": [
198+
{
199+
"type": "library",
200+
"name": "ruby",
201+
"version": "$ruby_version"
202+
}
203+
]
204+
}
137205
EOL
138-
206+
if [[ -f Gemfile.lock ]] ; then
207+
for gem in $(gem dep -q | grep ^Gem | sed 's/^Gem //')
208+
do
209+
version=${gem##*-}
210+
name=${gem%-${version}}
211+
DEP=$(jq --arg name "${name}" --arg version "${version}" \
212+
'.components[.components| length] |= . + {"type": "library", "name": $name, "version": $version}' \
213+
"${rubybom}")
214+
echo ${DEP} > "${rubybom}"
215+
done
216+
fi
139217
```
140218
141219
Then rebuild your app using the updated buildpack:
@@ -146,28 +224,38 @@ pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack
146224
```
147225
<!--+- "{{execute}}"+-->
148226
149-
You should then be able to inspect your Ruby app for its Bill-of-Materials via:
227+
Viewing your bill-of-materials requires extracting (or `download`ing) the bill-of-materials from your local image. This command can take some time to return.
150228
151229
<!-- test:exec -->
152230
```bash
153-
pack inspect-image test-ruby-app --bom
231+
pack sbom download test-ruby-app
154232
```
155233
<!--+- "{{execute}}"+-->
156234
235+
The SBOM information is now downloaded to the local file system:
236+
237+
<!-- test:exec -->
238+
```bash
239+
cat layers/sbom/launch/examples_ruby/ruby/sbom.cdx.json | jq -M
240+
```
241+
157242
You should find that the included `ruby` version is `2.5.0` as expected.
158243
159-
<!-- test:assert=contains -->
244+
<!-- test:assert=contains;ignore-lines=... -->
160245
```text
246+
{
247+
"bomFormat": "CycloneDX",
248+
"specVersion": "1.4",
249+
"version": 1,
250+
"components": [
161251
{
252+
"type": "library",
162253
"name": "ruby",
163-
"metadata": {
164-
"version": "2.5.0"
165-
},
166-
"buildpacks": {
167-
"id": "examples/ruby",
168-
"version": "0.0.1"
169-
}
170-
}
254+
"version": "2.5.0"
255+
},
256+
...
257+
]
258+
}
171259
```
172260
173261
Congratulations! You’ve created your first configurable Cloud Native Buildpack that uses detection, image layers, and caching to create an introspectable and runnable OCI image.
@@ -177,7 +265,6 @@ Congratulations! You’ve created your first configurable Cloud Native Buildpack
177265
Now that you've finished your buildpack, how about extending it? Try:
178266
179267
- Caching the downloaded Ruby version
180-
- Updating the BOM with all the gems provided by bundler
181268
- [Packaging your buildpack for distribution][package-a-buildpack]
182269
183270
[package-a-buildpack]: /docs/buildpack-author-guide/package-a-buildpack/

content/docs/buildpack-author-guide/create-buildpack/building-blocks-cnb.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Example:
1717
<!-- test:exec -->
1818
```bash
1919
pack buildpack new examples/ruby \
20-
--api 0.6 \
20+
--api 0.7 \
2121
--path ruby-buildpack \
2222
--version 0.0.1 \
2323
--stacks io.buildpacks.samples.stacks.bionic
@@ -41,7 +41,7 @@ You will have `ruby-buildpack/buildpack.toml`<!--+"{{open}}"+--> in your buildpa
4141
<!-- test:file=ruby-buildpack/buildpack.toml -->
4242
```toml
4343
# Buildpack API version
44-
api = "0.6"
44+
api = "0.7"
4545

4646
# Buildpack ID and metadata
4747
[buildpack]

0 commit comments

Comments
 (0)