Skip to content

Commit

Permalink
feat(ISV-5447): add multi-arch and sha info to release note images
Browse files Browse the repository at this point in the history
Signed-off-by: Wai Cheang <wcheang@redhat.com>

feat(ISV-5447): refactor SBOM data generation

Signed-off-by: Martin Jediny <jedinym@proton.me>
  • Loading branch information
wcheang authored and jedinym committed Dec 10, 2024
1 parent eb7b4f9 commit f6013ea
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 20 deletions.
4 changes: 4 additions & 0 deletions tasks/populate-release-notes-images/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Tekton task to populate the releaseNotes.content.images key in the data.json file. It will update the data.json
in place so that downstream tasks relying on the releaseNotes data can use it.
Additionally, it outputs a result with data used in component SBOM generation.

## Parameters

Expand All @@ -10,6 +11,9 @@ in place so that downstream tasks relying on the releaseNotes data can use it.
| dataPath | Path to the JSON string of the merged data to update | No | - |
| snapshotPath | Path to the JSON string of the mapped Snapshot in the data workspace | No | - |

## Changes in 2.2.4
* Export additional image data for component SBOM generation

## Changes in 2.2.3
* Rename `components` in the CVE struct to `packages`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ kind: Task
metadata:
name: populate-release-notes-images
labels:
app.kubernetes.io/version: "2.2.3"
app.kubernetes.io/version: "2.2.4"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: release
Expand All @@ -18,6 +18,9 @@ spec:
- name: snapshotPath
description: Path to the JSON string of the mapped Snapshot spec in the data workspace
type: string
results:
- name: sbomDataPath
description: Path to data used in the component SBOM creation in the data workspace
workspaces:
- name: data
description: The workspace where the data JSON file resides
Expand All @@ -42,6 +45,11 @@ spec:
UNIQUE_TAG_REGEX="(rhel-)?v?[0-9]+\.[0-9]+(\.[0-9]+)?-[0-9]{8,}"
# Initialize the SBOM data result
sbomDataPath="$(workspaces.data.path)/$(dirname "$(params.dataPath)")/sbom_data.json"
echo -n "$(dirname "$(params.dataPath)")/sbom_data.json" > "$(results.sbomDataPath.path)"
cp "${DATA_FILE}" "${sbomDataPath}"
NUM_COMPONENTS=$(jq '.components | length' "${SNAPSHOT_FILE}")
for ((i = 0; i < $NUM_COMPONENTS; i++))
do
Expand All @@ -60,21 +68,22 @@ spec:
containerImage="${deliveryRepo}@sha256:${sha}"
# Construct CVE json
CVEsJson='{"cves":{"fixed":{}}}'
CVES=$(jq -c '[.releaseNotes.cves[]? | select(.component=="'$name'")]' ${DATA_FILE})
CVES=$(jq -c '[.releaseNotes.cves[]? | select(.component=="'"$name"'")]' "${DATA_FILE}")
NUM_CVES=$(jq 'length' <<< "$CVES")
for ((j = 0; j < $NUM_CVES; j++)); do
cve=$(jq -c --argjson j "$j" '.[$j]' <<< "$CVES")
cveJson=$(jq -n \
--arg id "$(jq -r '.key' <<< "$cve")" \
--argjson packages "$(jq -c '.packages // []' <<< "$cve")" \
'{($id): {"packages": $packages}}')
CVEsJson=$(jq --argjson cve "$cveJson" '.cves.fixed += $cve' <<< $CVEsJson)
CVEsJson=$(jq --argjson cve "$cveJson" '.cves.fixed += $cve' <<< "$CVEsJson")
done
# Add one entry per arch (amd64 for example)
get-image-architectures "${image}" | while IFS= read -r arch_json;
do
arch=$(jq -r .platform.architecture <<< "${arch_json}")
digest=$(jq -r .digest <<< "${arch_json}")
multiarch=$(jq -r .multiarch <<< "${arch_json}")
containerImage="${deliveryRepo}@${digest}"
# purl should be pkg:oci/bar@sha256%3Aabcde?arch=amd64&repository_url=registry.redhat.io/foo
purl="pkg:oci/${deliveryRepo##*/}@${digest/:/%3A}?arch=${arch}&repository_url=${deliveryRepo%/*}"
Expand All @@ -101,14 +110,33 @@ spec:
--arg purl "$purl" \
--arg repository "$deliveryRepo" \
--argjson tags "$tags" \
'{"architecture": $arch, "containerImage":$containerImage,
"purl": $purl, "repository": $repository, "tags": $tags,
"component": $component}')
if [ $(jq '.cves.fixed | length' <<< $CVEsJson) -gt 0 ]; then
jsonString=$(jq --argjson cves "$CVEsJson" '. += $cves' <<< $jsonString)
'{"architecture": $arch, "containerImage": $containerImage, "purl": $purl,
"repository": $repository, "tags": $tags, "component": $component}')
if [ "$(jq '.cves.fixed | length' <<< "$CVEsJson")" -gt 0 ]; then
jsonString=$(jq --argjson cves "$CVEsJson" '. += $cves' <<< "$jsonString")
fi
# Inject JSON into data.json
jq --argjson image "$jsonString" '.releaseNotes.content.images += [$image]' ${DATA_FILE} > \
/tmp/data.tmp && mv /tmp/data.tmp ${DATA_FILE}
jq --argjson image "$jsonString" '.releaseNotes.content.images += [$image]' "${DATA_FILE}" > \
/tmp/data.tmp && mv /tmp/data.tmp "${DATA_FILE}"
# Inject SBOM-related data into the result
sbomJsonString=$(jq -cn \
--arg component "$name" \
--arg arch "$arch" \
--arg containerImage "$containerImage" \
--arg purl "$purl" \
--arg repository "$deliveryRepo" \
--arg multiarch "$multiarch" \
--arg imageSha "$sha" \
--argjson tags "$tags" \
'{"architecture": $arch, "containerImage": $containerImage, "purl": $purl,
"multiarch": $multiarch, "imageSha": $imageSha, "repository": $repository,
"tags": $tags, "component": $component}')
jq --argjson image "$sbomJsonString" \
'.releaseNotes.content.images += [$image]' \
"${sbomDataPath}" > \
/tmp/sbomData.tmp && mv /tmp/sbomData.tmp "${sbomDataPath}"
done
done
4 changes: 2 additions & 2 deletions tasks/populate-release-notes-images/tests/mocks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ set -eux
# mocks to be injected into task step scripts

function get-image-architectures() {
echo '{"platform":{"architecture": "amd64", "os": "linux"}, "digest": "sha256:abcdefg"}'
echo '{"platform":{"architecture": "s390x", "os": "linux"}, "digest": "sha256:deadbeef"}'
echo '{"platform":{"architecture": "amd64", "os": "linux"}, "digest": "sha256:abcdefg", "multiarch": true}'
echo '{"platform":{"architecture": "s390x", "os": "linux"}, "digest": "sha256:deadbeef", "multiarch": false}'
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,15 @@ spec:
runAfter:
- setup
- name: check-result
params:
- name: sbomDataPath
value: $(tasks.run-task.results.sbomDataPath)
workspaces:
- name: data
workspace: tests-workspace
taskSpec:
params:
- name: sbomDataPath
workspaces:
- name: data
steps:
Expand All @@ -120,6 +125,12 @@ spec:
test $(jq -r '.repository' <<< $image1arch1) == "registry.redhat.io/product/repo"
test "$(jq -rc '.tags' <<< "$image1arch1")" == '["9.4-1723436855","9.4.0-1723436855","foo","bar"]'
test "$(jq -r '.releaseNotes.content.images[0].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "true"
test "$(jq -r '.releaseNotes.content.images[0].imageSha' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "123456"
echo Checking image1arch2...
image1arch2=$(jq '.releaseNotes.content.images[1]' "$(workspaces.data.path)/data.json")
test $(jq -r '.architecture' <<< $image1arch2) == "s390x"
Expand All @@ -129,6 +140,12 @@ spec:
test $(jq -r '.repository' <<< $image1arch2) == "registry.redhat.io/product/repo"
test "$(jq -rc '.tags' <<< "$image1arch2")" == '["9.4-1723436855","9.4.0-1723436855","foo","bar"]'
test "$(jq -r '.releaseNotes.content.images[1].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "false"
test "$(jq -r '.releaseNotes.content.images[1].imageSha' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "123456"
echo Checking image2arch1...
image2arch1=$(jq '.releaseNotes.content.images[2]' "$(workspaces.data.path)/data.json")
test $(jq -r '.architecture' <<< $image2arch1) == "amd64"
Expand All @@ -139,6 +156,12 @@ spec:
test $(jq -r '.repository' <<< $image2arch1) == "registry.stage.redhat.io/product2/repo2"
test $(jq -rc '.tags' <<< $image2arch1) == '["foo","bar"]'
test "$(jq -r '.releaseNotes.content.images[2].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "true"
test "$(jq -r '.releaseNotes.content.images[2].imageSha' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "abcde"
echo Checking image2arch2...
image2arch2=$(jq '.releaseNotes.content.images[3]' "$(workspaces.data.path)/data.json")
test $(jq -r '.architecture' <<< $image2arch2) == "s390x"
Expand All @@ -148,5 +171,11 @@ spec:
"pkg:oci/repo2@sha256%3Adeadbeef?arch=s390x&repository_url=registry.stage.redhat.io/product2"
test $(jq -r '.repository' <<< $image2arch2) == "registry.stage.redhat.io/product2/repo2"
test $(jq -rc '.tags' <<< $image2arch2) == '["foo","bar"]'
test "$(jq -r '.releaseNotes.content.images[3].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "false"
test "$(jq -r '.releaseNotes.content.images[3].imageSha' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "abcde"
runAfter:
- run-task
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,15 @@ spec:
runAfter:
- setup
- name: check-result
params:
- name: sbomDataPath
value: $(tasks.run-task.results.sbomDataPath)
workspaces:
- name: data
workspace: tests-workspace
taskSpec:
params:
- name: sbomDataPath
workspaces:
- name: data
steps:
Expand All @@ -116,5 +121,12 @@ spec:
test $(jq -r '.repository' <<< $imagearch2) == "registry.redhat.io/product/repo"
test $(jq -rc '.tags' <<< $imagearch2) == '["foo","bar"]'
test "$(jq -rc '.component' <<< "$imagearch2")" == "comp"
# Test SBOM injection
test "$(jq -r '.releaseNotes.content.images[0].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "true"
test "$(jq -r '.releaseNotes.content.images[0].imageSha' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "123456"
runAfter:
- run-task
7 changes: 5 additions & 2 deletions tasks/update-component-sbom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ Tekton task to update component-level SBOMs with purls containing release-time i
## Parameters

| Name | Description | Optional | Default value |
| ------------------ | ------------------------------------------------------------------------ | -------- | ------------- |
| dataJsonPath | Path to the JSON string of the merged data containing the release notes | No | - |
|--------------------|--------------------------------------------------------------------------|----------|---------------|
| sbomJsonPath | Path to the JSON string of the merged data containing the release notes | No | - |
| downloadedSbomPath | Path to the directory holding previously downloaded SBOMs to be updated. | No | - |

## Changes in 0.2.0
- Rename dataPath parameter to sbomJsonPath to better reflect usage

## Changes in 0.1.1
- (ISV-5321) Set a `name` of SPDX document to external reference of the component. The name is set to external image pullspec given by the public registry + repository + digest. Example: registry.redhat.io/ubi8/ubi-minimal@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
taskRef:
name: update-component-sbom
params:
- name: dataJsonPath
- name: sbomJsonPath
value: "data.json"
- name: downloadedSbomPath
value: downloaded-sboms
Expand Down
10 changes: 5 additions & 5 deletions tasks/update-component-sbom/update-component-sbom.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ kind: Task
metadata:
name: update-component-sbom
labels:
app.kubernetes.io/version: "0.1.1"
app.kubernetes.io/version: "0.2.0"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: release
spec:
description: >-
Update component-level SBOM with purls with release-time info.
params:
- name: dataJsonPath
description: Relative path to the JSON data file in the workspace.
- name: sbomJsonPath
description: Relative path to the SBOM data file in the workspace.
type: string
- name: downloadedSbomPath
description: |
Expand All @@ -24,7 +24,7 @@ spec:
description: The workspace where the SBOM files reside.
steps:
- name: update-component-sbom-purls
image: quay.io/konflux-ci/release-service-utils:e15023773e138c7d3449f288c8c16de4e3a8d249
image: quay.io/konflux-ci/release-service-utils:3e107dfec5342ef61ae89337458d26c6efe97938
script: |
#!/usr/bin/env bash
set -eux
Expand All @@ -33,6 +33,6 @@ spec:
#update the SBOM files in place
update_component_sbom \
--data-path "$(workspaces.data.path)/$(params.dataJsonPath)" \
--data-path "$(workspaces.data.path)/$(params.sbomJsonPath)" \
--input-path "$INPUT_PATH" \
--output-path "$INPUT_PATH"

0 comments on commit f6013ea

Please sign in to comment.