Skip to content

Commit

Permalink
source-build: read base image from SBOM
Browse files Browse the repository at this point in the history
STONEBLD-2607

When the BASE_IMAGES param is empty, fall back to reading the base image
from the SBOM of the BINARY_IMAGE.

This removes the source-build task's dependency on the
BASE_IMAGES_DIGESTS result, finally allowing us to stop returning this
result from build tasks.

Signed-off-by: Adam Cmiel <[email protected]>
  • Loading branch information
chmeliik committed Jul 11, 2024
1 parent 6e5906c commit 277ccab
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
2 changes: 1 addition & 1 deletion task/source-build/0.1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Source image build.
|name|description|default value|required|
|---|---|---|---|
|BINARY_IMAGE|Binary image name from which to generate the source image name.||true|
|BASE_IMAGES|Base images used to build the binary image. Each image per line in the same order of FROM instructions specified in a multistage Dockerfile. Default to an empty string, which means to skip handling a base image.|""|false|
|BASE_IMAGES|By default, the task inspects the SBOM of the binary image to find the base image. With this parameter, you can override that behavior and pass the base image directly. The value should be a newline-separated list of images, in the same order as the FROM instructions specified in a multistage Dockerfile.|""|false|

## Results
|name|description|
Expand Down
67 changes: 56 additions & 11 deletions task/source-build/0.1/source-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ spec:
type: string
- name: BASE_IMAGES
description: >-
Base images used to build the binary image. Each image per line in the same order of FROM
instructions specified in a multistage Dockerfile. Default to an empty string, which means
to skip handling a base image.
By default, the task inspects the SBOM of the binary image to find the base image.
With this parameter, you can override that behavior and pass the base image directly.
The value should be a newline-separated list of images, in the same order as the FROM
instructions specified in a multistage Dockerfile.
type: string
default: ""
results:
Expand All @@ -34,7 +35,58 @@ spec:
volumes:
- name: source-build-work-place
emptyDir: {}
stepTemplate:
env:
- name: BINARY_IMAGE
value: "$(params.BINARY_IMAGE)"
- name: BASE_IMAGES_FILE
value: /var/source-build/base-images.txt
volumeMounts:
- name: source-build-work-place
mountPath: /var/source-build
steps:
- name: get-base-images
image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14
env:
- name: BASE_IMAGES
value: "$(params.BASE_IMAGES)"
script: |
#!/usr/bin/env bash
set -euo pipefail
if [[ -n "$BASE_IMAGES" ]]; then
echo "BASE_IMAGES param received:"
printf "%s" "$BASE_IMAGES" | tee "$BASE_IMAGES_FILE"
exit
fi
echo "BASE_IMAGES param is empty, inspecting the SBOM instead"
raw_inspect=$(skopeo inspect --raw "docker://$BINARY_IMAGE")
if manifest_digest=$(jq -e -r '.manifests[0].digest' <<< "$raw_inspect"); then
# We're gonna assume the base images are the same or similar enough in all the SBOMs
# How would we even handle a build where each manifest in the list is built from different base images?
echo "BINARY_IMAGE ($BINARY_IMAGE) is a manifest list, picking an arbitrary image from the list"
image_without_digest=${BINARY_IMAGE%@*}
image_without_tag=${image_without_digest%:*}
image=${image_without_tag}@${manifest_digest}
else
image=$BINARY_IMAGE
fi
echo "Downloading SBOM for $image"
sbom=$(cosign download sbom "$image")
echo -n "Extracting base images from SBOM"
echo " (looking for .formulation[].components[] with 'konflux:container:is_base_image' properties)"
jq -r '
.formulation[]?
| .components[]?
| select(any(.properties[]?; .name == "konflux:container:is_base_image"))
| (.purl | capture("^pkg:oci/.*?@(?<digest>.*?:[a-f0-9]*)")) as $matched
| .name + "@" + $matched.digest
' <<< "$sbom" | tee "$BASE_IMAGES_FILE"
- name: build
image: quay.io/konflux-ci/source-container-build:9ad131acf5154d2f280b7b46a1abc543952d325c@sha256:94271c32e4578208ac90308695d2b625d4e932d65f0cdd116b200c39228f5ece
# per https://kubernetes.io/docs/concepts/containers/images/#imagepullpolicy-defaulting
Expand All @@ -51,16 +103,9 @@ spec:
capabilities:
add:
- SETFCAP
volumeMounts:
- name: source-build-work-place
mountPath: /var/source-build
env:
- name: BINARY_IMAGE
value: "$(params.BINARY_IMAGE)"
- name: SOURCE_DIR
value: "$(workspaces.workspace.path)/source"
- name: BASE_IMAGES
value: "$(params.BASE_IMAGES)"
- name: RESULT_FILE
value: "$(results.BUILD_RESULT.path)"
- name: CACHI2_ARTIFACTS_DIR
Expand Down Expand Up @@ -91,7 +136,7 @@ spec:
--output-binary-image "$BINARY_IMAGE" \
--workspace /var/source-build \
--source-dir "$SOURCE_DIR" \
--base-images "$BASE_IMAGES" \
--base-images "$(cat "$BASE_IMAGES_FILE")" \
--write-result-to "$RESULT_FILE" \
--cachi2-artifacts-dir "$CACHI2_ARTIFACTS_DIR" \
--registry-allowlist="$registry_allowlist"
Expand Down

0 comments on commit 277ccab

Please sign in to comment.