Skip to content

Commit 410df4a

Browse files
authored
Merge pull request #51 from LaurentGoderre/sbom-oci-import
Generate SBOM for the oci-builder
2 parents 72d39b3 + 662d724 commit 410df4a

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

.test/meta-commands/out.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,42 @@ jq -s '
138138
)
139139
' temp/index.json > temp/index.json.new
140140
mv temp/index.json.new temp/index.json
141+
# SBOM
142+
originalImageManifest="$(jq -r '.manifests[0].digest' temp/index.json)"
143+
SOURCE_DATE_EPOCH=1709081058 \
144+
docker buildx build --progress=plain \
145+
--load=false \
146+
--provenance=false \
147+
--build-arg BUILDKIT_DOCKERFILE_CHECK=skip=all \
148+
--sbom=generator="$BASHBREW_BUILDKIT_SBOM_GENERATOR" \
149+
--output 'type=oci,tar=false,dest=sbom' \
150+
--platform 'linux/amd64' \
151+
--build-context "fake=oci-layout://$PWD/temp@$originalImageManifest" \
152+
- <<<'FROM fake'
153+
sbomIndex="$(jq -r '.manifests[0].digest' sbom/index.json)"
154+
shell="$(jq -r --arg originalImageManifest "$originalImageManifest" '
155+
first(
156+
.manifests[]
157+
| select(.annotations["vnd.docker.reference.type"] == "attestation-manifest")
158+
) as $attDesc
159+
| @sh "sbomManifest=\($attDesc.digest)",
160+
@sh "sbomManifestDesc=\(
161+
$attDesc
162+
| .annotations["vnd.docker.reference.digest"] = $originalImageManifest
163+
| tojson
164+
)"
165+
' "sbom/blobs/${sbomIndex/://}")"
166+
eval "$shell"
167+
shell="$(jq -r '
168+
"copyBlobs=( \([ .config.digest, .layers[].digest | @sh ] | join(" ")) )"
169+
' "sbom/blobs/${sbomManifest/://}")"
170+
eval "$shell"
171+
copyBlobs+=( "$sbomManifest" )
172+
for blob in "${copyBlobs[@]}"; do
173+
cp "sbom/blobs/${blob/://}" "temp/blobs/${blob/://}"
174+
done
175+
jq -r --argjson sbomManifestDesc "$sbomManifestDesc" '.manifests += [ $sbomManifestDesc ]' temp/index.json > temp/index.json.new
176+
mv temp/index.json.new temp/index.json
141177
# </build>
142178
# <push>
143179
crane push --index temp 'oisupport/staging-amd64:191402ad0feacf03daf9d52a492207e73ef08b0bd17265043aea13aa27e2bb3f'

meta.jq

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,52 @@ def build_command:
320320

321321
# TODO consider / check what "crane validate" does and if it would be appropriate here
322322

323-
# TODO generate SBOM? ... somehow
324-
325-
empty
323+
if build_should_sbom then
324+
# we'll trick BuildKit into generating an SBOM for us, then inject it into our OCI layout
325+
"# SBOM",
326+
"originalImageManifest=\"$(jq -r '.manifests[0].digest' temp/index.json)\"",
327+
(
328+
[
329+
@sh "SOURCE_DATE_EPOCH=\(.source.entry.SOURCE_DATE_EPOCH)",
330+
"docker buildx build --progress=plain",
331+
"--load=false", "--provenance=false", # explicitly disable a few features we want to avoid
332+
"--build-arg BUILDKIT_DOCKERFILE_CHECK=skip=all", # disable linting (https://github.com/moby/buildkit/pull/4962)
333+
"--sbom=generator=\"$BASHBREW_BUILDKIT_SBOM_GENERATOR\"",
334+
"--output 'type=oci,tar=false,dest=sbom'",
335+
# TODO also add appropriate "--tag" lines (which would give us a mostly correct "subject" block in the generated SBOM, but we'd then need to replace instances of ${sbomImageManifest#*:} with ${originalImageManifest#*:} for their values to be correct)
336+
@sh "--platform \(.source.arches[.build.arch].platformString)",
337+
"--build-context \"fake=oci-layout://$PWD/temp@$originalImageManifest\"",
338+
"- <<<'FROM fake'", # note: "<<<" is a bashism (so this output must be invoked via bash)
339+
empty
340+
] | join(" \\\n\t")
341+
),
342+
"sbomIndex=\"$(jq -r '.manifests[0].digest' sbom/index.json)\"",
343+
@sh "shell=\"$(jq -r --arg originalImageManifest \"$originalImageManifest\" \("
344+
# https://docs.docker.com/build/attestations/attestation-storage/
345+
first(
346+
.manifests[]
347+
| select(.annotations[\"vnd.docker.reference.type\"] == \"attestation-manifest\")
348+
) as $attDesc
349+
| @sh \"sbomManifest=\\($attDesc.digest)\",
350+
@sh \"sbomManifestDesc=\\(
351+
$attDesc
352+
| .annotations[\"vnd.docker.reference.digest\"] = $originalImageManifest
353+
| tojson
354+
)\"
355+
" | unindent_and_decomment_jq(4)) \"sbom/blobs/${sbomIndex/://}\")\"",
356+
"eval \"$shell\"",
357+
@sh "shell=\"$(jq -r \("
358+
\"copyBlobs=( \\([ .config.digest, .layers[].digest | @sh ] | join(\" \")) )\"
359+
" | unindent_and_decomment_jq(4)) \"sbom/blobs/${sbomManifest/://}\")\"",
360+
"eval \"$shell\"",
361+
"copyBlobs+=( \"$sbomManifest\" )",
362+
"for blob in \"${copyBlobs[@]}\"; do",
363+
"\tcp \"sbom/blobs/${blob/://}\" \"temp/blobs/${blob/://}\"",
364+
"done",
365+
"jq -r --argjson sbomManifestDesc \"$sbomManifestDesc\" '.manifests += [ $sbomManifestDesc ]' temp/index.json > temp/index.json.new",
366+
"mv temp/index.json.new temp/index.json",
367+
empty
368+
else empty end
326369
] | join("\n")
327370
else
328371
error("unknown/unimplemented Builder: \($builder)")

0 commit comments

Comments
 (0)