Skip to content

Commit

Permalink
feat(ISV-5447): add multi-arch and sha info to release note images (#724
Browse files Browse the repository at this point in the history
)

Signed-off-by: Wai Cheang <[email protected]>
  • Loading branch information
wcheang authored Dec 17, 2024
1 parent b691c19 commit 9e15f03
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 23 deletions.
9 changes: 7 additions & 2 deletions tasks/populate-release-notes-images/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# populate-release-notes-images

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.
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 the
path to a file containing data used in component SBOM generation.

## Parameters

Expand All @@ -10,6 +12,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.3.0
* Export additional image data to a file 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.3.0"
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,12 @@ spec:
UNIQUE_TAG_REGEX="(rhel-)?v?[0-9]+\.[0-9]+(\.[0-9]+)?-[0-9]{8,}"
# Initialize the SBOM data result
relativeDir=$(dirname "$(params.dataPath)")
sbomDataPath="$(workspaces.data.path)/${relativeDir}/sbom_data.json"
echo -n "${relativeDir}/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 +69,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 +111,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 an SBOM data file
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" \
'.images = (.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 '.images[0].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "true"
test "$(jq -r '.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 '.images[1].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "false"
test "$(jq -r '.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 '.images[2].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "true"
test "$(jq -r '.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 '.images[3].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "false"
test "$(jq -r '.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 '.images[0].multiarch' \
"$(workspaces.data.path)/$(params.sbomDataPath)")" == "true"
test "$(jq -r '.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 All @@ -31,7 +31,7 @@ spec:
- name: data
steps:
- name: check-result
image: quay.io/konflux-ci/release-service-utils:e15023773e138c7d3449f288c8c16de4e3a8d249
image: quay.io/konflux-ci/release-service-utils:4a67d0c959e63cbb4bc0d37db1ce962091d6072a
script: |
#!/usr/bin/env bash
set -eux
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:4a67d0c959e63cbb4bc0d37db1ce962091d6072a
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 9e15f03

Please sign in to comment.