From 5b676d59a8ed74b9b65c3585decf2f842f169582 Mon Sep 17 00:00:00 2001 From: Misha Sugakov Date: Wed, 19 Feb 2025 18:21:05 +0100 Subject: [PATCH 1/4] Rename check-konflux-pipelines.sh because we'll check more than just the pipelines. --- .github/workflows/style.yaml | 4 ++-- .tekton/operator-bundle-pipeline.yaml | 2 +- .../{check-konflux-pipelines.sh => check-konflux-setup.sh} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename scripts/ci/jobs/{check-konflux-pipelines.sh => check-konflux-setup.sh} (100%) diff --git a/.github/workflows/style.yaml b/.github/workflows/style.yaml index d80ce8cf43bba..3015f676f95ec 100644 --- a/.github/workflows/style.yaml +++ b/.github/workflows/style.yaml @@ -75,8 +75,8 @@ jobs: - name: Check Policies run: scripts/ci/jobs/policy-checks.sh - - name: Check Konflux pipelines - run: scripts/ci/jobs/check-konflux-pipelines.sh + - name: Check Konflux setup + run: scripts/ci/jobs/check-konflux-setup.sh style-check: runs-on: ubuntu-latest diff --git a/.tekton/operator-bundle-pipeline.yaml b/.tekton/operator-bundle-pipeline.yaml index f74b18b18d5be..1a6dff4fb2625 100644 --- a/.tekton/operator-bundle-pipeline.yaml +++ b/.tekton/operator-bundle-pipeline.yaml @@ -648,7 +648,7 @@ spec: # Explicitly running after all other tasks to ensure that # - there are no failures that should prevent a release of the operator-bundle image (missing RPMs signatures, deprecated base images, ...) # - the source image is present as it is required by EC - # Use scripts/ci/jobs/check-konflux-pipelines.sh to validate and update the list. + # Use scripts/ci/jobs/check-konflux-setup.sh to validate and update the list. runAfter: - apply-tags - build-container diff --git a/scripts/ci/jobs/check-konflux-pipelines.sh b/scripts/ci/jobs/check-konflux-setup.sh similarity index 100% rename from scripts/ci/jobs/check-konflux-pipelines.sh rename to scripts/ci/jobs/check-konflux-setup.sh From 09240ce532e1a566d651d7756886fa9698832f9c Mon Sep 17 00:00:00 2001 From: Misha Sugakov Date: Fri, 31 Jan 2025 14:41:16 +0100 Subject: [PATCH 2/4] Exclude example rpmdb from SBOMs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note that Syft requires paths to start with `./` otherwise it fails like this: ``` [0000] ERROR ␛[31munable to get file resolver: invalid exclusion pattern(s): 'compliance/node/index/testdata/usr/share/rpm/rpmdb.sqlite' (must start with one of: './', '*/', or '**/')␛[0m ``` --- .syft.yaml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .syft.yaml diff --git a/.syft.yaml b/.syft.yaml new file mode 100644 index 0000000000000..dd5e7a7fd725c --- /dev/null +++ b/.syft.yaml @@ -0,0 +1,2 @@ +exclude: +- ./compliance/node/index/testdata/usr/share/rpm/rpmdb.sqlite From 31e7ba8e3c5a77d8ed02319ef2b624e03ad5b361 Mon Sep 17 00:00:00 2001 From: Misha Sugakov Date: Wed, 19 Feb 2025 17:51:21 +0100 Subject: [PATCH 3/4] Extend the check script to validate syft exclusions --- .syft.yaml | 5 +++ scripts/ci/jobs/check-konflux-setup.sh | 51 +++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/.syft.yaml b/.syft.yaml index dd5e7a7fd725c..593ec2fbe8adf 100644 --- a/.syft.yaml +++ b/.syft.yaml @@ -1,2 +1,7 @@ +# Konflux uses Syft to generate container SBOMs. +# Syft config docs https://github.com/anchore/syft/wiki/configuration + +# Here we exclude rpmdb files checked in this repo for testing purposes from being parsed and merged into SBOM. +# Use scripts/ci/jobs/check-konflux-setup.sh to validate or update this exclusion list. exclude: - ./compliance/node/index/testdata/usr/share/rpm/rpmdb.sqlite diff --git a/scripts/ci/jobs/check-konflux-setup.sh b/scripts/ci/jobs/check-konflux-setup.sh index 75da2da510718..6589abe4c6bb2 100755 --- a/scripts/ci/jobs/check-konflux-setup.sh +++ b/scripts/ci/jobs/check-konflux-setup.sh @@ -62,12 +62,61 @@ ${expected_components} fi } +check_example_rpmdb_files_are_ignored() { + # At the time of this writing, Konflux uses syft to generate SBOMs for built containers. + # If we happen to have test rpmdb databases in the repo, syft will union their contents with RPMs that it finds + # installed in the container resulting in a misleading SBOM. + # This check is to make sure the exclusion list in Syft config enumerates all such rpmdbs. + # Ref https://github.com/anchore/syft/wiki/configuration + + local -r syft_config=".syft.yaml" + local -r exclude_attribute=".exclude" + + local actual_excludes + actual_excludes="$(yq eval "${exclude_attribute}" "${syft_config}")" + + local expected_excludes + expected_excludes="$(git ls-files -- '**/rpmdb.sqlite' | sort | uniq | sed 's/^/- .\//')" + + echo + echo "➤ ${syft_config} // checking ${exclude_attribute} list: all rpmdb files in the repo shall be mentioned." + if ! compare "${expected_excludes}" "${actual_excludes}"; then + echo >&2 "How to resolve: +1. Open ${syft_config} and replace ${exclude_attribute} contents with the following. +${expected_excludes}" + record_failure "${FUNCNAME}" + fi +} + +compare() { + local -r expected="$1" + local -r actual="$2" + + if ! diff --brief <(echo "${expected}") <(echo "${actual}") > /dev/null; then + echo >&2 "✗ ERROR: the expected contents (left) don't match the actual ones (right):" + diff >&2 --side-by-side <(echo "${expected}") <(echo "${actual}") || true + return 1 + else + echo "✓ No diff detected." + fi +} + +record_failure() { + local -r func="$1" + echo "${func}" >> "${FAIL_FLAG}" +} + echo "Ensure consistency of our Konflux pipelines." ensure_create_snapshot_runs_last || { echo "ensure_create_snapshot_runs_last" >> "${FAIL_FLAG}"; } check_all_components_part_of_custom_snapshot || { echo "check_all_components_part_of_custom_snapshot" >> "${FAIL_FLAG}"; } +check_example_rpmdb_files_are_ignored if [[ -s "$FAIL_FLAG" ]]; then - echo >&2 "ERROR: Some Konflux pipeline consistency checks failed:" + echo >&2 + echo >&2 "✗ Some Konflux pipeline consistency checks failed:" cat >&2 "$FAIL_FLAG" exit 1 +else + echo + echo "✓ All checks passed." fi From b5cfc2c18f5fd997db6087e18502e4ac17371259 Mon Sep 17 00:00:00 2001 From: Misha Sugakov Date: Wed, 19 Feb 2025 18:03:56 +0100 Subject: [PATCH 4/4] Refactor earlier checks for consistency --- scripts/ci/jobs/check-konflux-setup.sh | 72 ++++++++++++-------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/scripts/ci/jobs/check-konflux-setup.sh b/scripts/ci/jobs/check-konflux-setup.sh index 6589abe4c6bb2..3623fe111821c 100755 --- a/scripts/ci/jobs/check-konflux-setup.sh +++ b/scripts/ci/jobs/check-konflux-setup.sh @@ -8,57 +8,49 @@ set -euo pipefail FAIL_FLAG="$(mktemp)" trap 'rm -f $FAIL_FLAG' EXIT -ensure_create_snapshot_runs_last() { - local pipeline_path=".tekton/operator-bundle-pipeline.yaml" - local task_name="create-acs-style-snapshot" - expected_runafter="$(yq eval '.spec.tasks[] | select(.name != '\"${task_name}\"') | .name' "${pipeline_path}" | sort)" - actual_runafter="$(yq eval '.spec.tasks[] | select(.name == '\"${task_name}\"') | .runAfter[]' "${pipeline_path}")" +check_create_snapshot_runs_last() { + local -r pipeline_path=".tekton/operator-bundle-pipeline.yaml" + local -r task_name="create-acs-style-snapshot" - echo "➤ ${pipeline_path} // checking ${task_name}: task's runAfter contents shall match the expected ones (left - expected, right - actual)." - if ! diff --side-by-side <(echo "${expected_runafter}") <(echo "${actual_runafter}"); then - echo >&2 -e " -✗ ERROR: + local expected_runafter + expected_runafter="$(yq eval '.spec.tasks[] | select(.name != '\"${task_name}\"') | .name' "${pipeline_path}" | sort)" -The actual runAfter contents do not match the expectations. -To resolve: + local actual_runafter + actual_runafter="$(yq eval '.spec.tasks[] | select(.name == '\"${task_name}\"') | .runAfter[]' "${pipeline_path}")" + echo + echo "➤ ${pipeline_path} // checking ${task_name}: task's runAfter contents shall match the expected ones." + if ! compare "${expected_runafter}" "${actual_runafter}"; then + echo >&2 -e "How to resolve: 1. Open ${pipeline_path} and locate the ${task_name} task -2. Update the runAfter attribute of this task to this list of all previous tasks in the pipeline (sorted alphabetically): - -${expected_runafter} - " - return 1 - else - echo "✓ No diff detected." +2. Update the runAfter attribute of this task to the following list (all previous tasks in the pipeline, sorted alphabetically): +${expected_runafter}" + record_failure "${FUNCNAME}" fi } -check_all_components_part_of_custom_snapshot() { - local pipeline_path=".tekton/operator-bundle-pipeline.yaml" - local task_name="create-acs-style-snapshot" +check_all_components_are_part_of_custom_snapshot() { + local -r pipeline_path=".tekton/operator-bundle-pipeline.yaml" + local -r task_name="create-acs-style-snapshot" # Actual components are based on the COMPONENTS parameter and stored as sorted multi-line string. + local actual_components actual_components="$(yq eval '.spec.tasks[] | select(.name == '\"${task_name}\"') | .params[] | select(.name == "COMPONENTS") | .value' "${pipeline_path}" | yq eval '.[].name' - | tr " " "\n" | sort)" + # Expected components are based on the wait-for-*-image task plus the operator-bundle and stored as a sorted multi-line string. + local expected_components_from_images + local expected_components expected_components_from_images="$(yq eval '.spec.tasks[] | select(.name == "wait-for-*-image") | .name | sub("(wait-for-|-image)", "")' ${pipeline_path})" expected_components=$(echo "${expected_components_from_images} operator-bundle" | tr " " "\n" | sort) - echo "➤ ${pipeline_path} // checking ${task_name}: COMPONENTS contents shall include all ACS images (left - expected, right - actual)." - if ! diff --side-by-side <(echo "${expected_components}") <(echo "${actual_components}"); then - echo >&2 -e " -✗ ERROR: - -The actual COMPONENTS contents do not match the expectations. -To resolve: - + echo + echo "➤ ${pipeline_path} // checking ${task_name}: COMPONENTS contents shall include all ACS images." + if ! compare "${expected_components}" "${actual_components}"; then + echo >&2 -e "How to resolve: 1. Open ${pipeline_path} and locate the ${task_name} task 2. Update the COMPONENTS parameter of this task to include entries for the missing components or delete references to removed components. COMPONENTS should include entries for (sorted alphabetically): - -${expected_components} - " - return 1 - else - echo "✓ No diff detected." +${expected_components}" + record_failure "${FUNCNAME}" fi } @@ -79,7 +71,7 @@ check_example_rpmdb_files_are_ignored() { expected_excludes="$(git ls-files -- '**/rpmdb.sqlite' | sort | uniq | sed 's/^/- .\//')" echo - echo "➤ ${syft_config} // checking ${exclude_attribute} list: all rpmdb files in the repo shall be mentioned." + echo "➤ ${syft_config} // checking ${exclude_attribute}: all rpmdb files in the repo shall be mentioned." if ! compare "${expected_excludes}" "${actual_excludes}"; then echo >&2 "How to resolve: 1. Open ${syft_config} and replace ${exclude_attribute} contents with the following. @@ -106,14 +98,14 @@ record_failure() { echo "${func}" >> "${FAIL_FLAG}" } -echo "Ensure consistency of our Konflux pipelines." -ensure_create_snapshot_runs_last || { echo "ensure_create_snapshot_runs_last" >> "${FAIL_FLAG}"; } -check_all_components_part_of_custom_snapshot || { echo "check_all_components_part_of_custom_snapshot" >> "${FAIL_FLAG}"; } +echo "Checking our Konflux pipelines and builds setup." +check_create_snapshot_runs_last +check_all_components_are_part_of_custom_snapshot check_example_rpmdb_files_are_ignored if [[ -s "$FAIL_FLAG" ]]; then echo >&2 - echo >&2 "✗ Some Konflux pipeline consistency checks failed:" + echo >&2 "✗ Some Konflux checks failed:" cat >&2 "$FAIL_FLAG" exit 1 else