diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 512481c525896..fbf56430c81df 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "image":"quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1", + "image":"quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2", "containerEnv":{ "CI":"true" }, diff --git a/.github/workflows/batch-load-test-metrics.yml b/.github/workflows/batch-load-test-metrics.yml index de06ff50f3905..1dbec06c9de11 100644 --- a/.github/workflows/batch-load-test-metrics.yml +++ b/.github/workflows/batch-load-test-metrics.yml @@ -12,7 +12,7 @@ jobs: if: ${{ github.repository_owner == 'stackrox' }} runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 750e389193dac..20dd30bcad1e2 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -65,7 +65,7 @@ jobs: matrix="$(jq '.push_operator_multiarch_manifests.archs = [.build_and_push_operator.arch | join(",")]' <<< "$matrix")" matrix="$(jq '.scan_images_with_roxctl.name += ["RHACS_BRANDING", "STACKROX_BRANDING"]' <<< "$matrix")" - matrix="$(jq '.scan_images_with_roxctl.image += ["central-db", "collector", "main", "roxctl", "scanner", "scanner-db", "scanner-db-slim", "scanner-slim", "stackrox-operator"]' <<< "$matrix")" + matrix="$(jq '.scan_images_with_roxctl.image += ["central-db", "collector", "fact", "main", "roxctl", "scanner", "scanner-db", "scanner-db-slim", "scanner-slim", "stackrox-operator"]' <<< "$matrix")" # TODO(ROX-27191): remove the exclusion once there's a community operator. matrix="$(jq '.scan_images_with_roxctl.exclude += [{ "name": "STACKROX_BRANDING", "image": "stackrox-operator" }]' <<< "$matrix")" @@ -114,7 +114,7 @@ jobs: UI_PKG_INSTALL_EXTRA_ARGS: --ignore-scripts runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -149,7 +149,7 @@ jobs: pre-build-cli: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -190,7 +190,7 @@ jobs: needs: define-job-matrix runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -260,7 +260,7 @@ jobs: pre-build-docs: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -320,7 +320,7 @@ jobs: GO_BINARIES_BUILD_ARTIFACT: "" ROX_PRODUCT_BRANDING: "" container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -504,7 +504,7 @@ jobs: env: ROX_PRODUCT_BRANDING: "" container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -599,7 +599,7 @@ jobs: needs: - define-job-matrix container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -761,7 +761,7 @@ jobs: env: ROX_PRODUCT_BRANDING: ${{ matrix.name }} container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -805,7 +805,7 @@ jobs: ARTIFACT_DIR: junit-reports/ runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 needs: - pre-build-cli - pre-build-go-binaries diff --git a/.github/workflows/check-crd-compatibility.yaml b/.github/workflows/check-crd-compatibility.yaml index 2e32fdb61d995..dd33ab13965be 100644 --- a/.github/workflows/check-crd-compatibility.yaml +++ b/.github/workflows/check-crd-compatibility.yaml @@ -20,7 +20,7 @@ jobs: check-crd-compatibility: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 outputs: released_version: ${{ steps.get_previous_released_version.outputs.released_version }} steps: diff --git a/.github/workflows/ci-failures-report.yml b/.github/workflows/ci-failures-report.yml index 369a09976720b..6432642796a9f 100644 --- a/.github/workflows/ci-failures-report.yml +++ b/.github/workflows/ci-failures-report.yml @@ -15,7 +15,7 @@ jobs: if: ${{ github.repository_owner == 'stackrox' }} runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 diff --git a/.github/workflows/fixxxer.yaml b/.github/workflows/fixxxer.yaml index 94ec15650b54d..ca0ecafb6e273 100644 --- a/.github/workflows/fixxxer.yaml +++ b/.github/workflows/fixxxer.yaml @@ -7,6 +7,9 @@ on: permissions: contents: write +env: + ROX_PRODUCT_BRANDING: RHACS_BRANDING + jobs: pr_commented: name: Run PR Fixxxer @@ -14,7 +17,7 @@ jobs: if: ${{ github.event.issue.pull_request && github.event.comment.body == '/fixxx' }} runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Fetch PR metadata diff --git a/.github/workflows/release-ci.yaml b/.github/workflows/release-ci.yaml index 1ec4ae0e1fbe8..f28143aa12eaf 100644 --- a/.github/workflows/release-ci.yaml +++ b/.github/workflows/release-ci.yaml @@ -70,8 +70,21 @@ jobs: scripts/ci/lib.sh \ check_collector_version + check-fact-version: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + ref: ${{ github.ref_name }} + - name: Check fact version + run: | + scripts/ci/lib.sh \ + check_fact_version + publish-helm-charts: - needs: [build, check-scanner-version, check-collector-version, check-is-release] + needs: [build, check-scanner-version, check-collector-version, check-fact-version, check-is-release] if: needs.check-is-release.outputs.is_release == 'true' runs-on: ubuntu-latest steps: @@ -100,7 +113,7 @@ jobs: # Publish `roxagent` and `roxctl`. publish-cli: - needs: [build, check-scanner-version, check-collector-version, check-is-release] + needs: [build, check-scanner-version, check-collector-version, check-fact-version, check-is-release] if: needs.check-is-release.outputs.is_release == 'true' runs-on: ubuntu-latest steps: @@ -126,7 +139,7 @@ jobs: publish_cli "${STACKROX_TAG}" publish-openapispec: - needs: [build, check-scanner-version, check-collector-version, check-is-release] + needs: [build, check-scanner-version, check-collector-version, check-fact-version, check-is-release] if: needs.check-is-release.outputs.is_release == 'true' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/scan-image-vulnerabilities.yaml b/.github/workflows/scan-image-vulnerabilities.yaml index 1f022e587d7fb..7fd100e9b11c1 100644 --- a/.github/workflows/scan-image-vulnerabilities.yaml +++ b/.github/workflows/scan-image-vulnerabilities.yaml @@ -59,6 +59,7 @@ jobs: [ "central-db", "collector", + "fact", "main", "roxctl", "scanner", @@ -114,6 +115,7 @@ jobs: [ "release-central-db", "release-collector", + "release-fact", "release-main", "release-roxctl", "release-scanner", diff --git a/.github/workflows/scanner-build.yaml b/.github/workflows/scanner-build.yaml index 1493f701f16ae..0bd77af73b883 100644 --- a/.github/workflows/scanner-build.yaml +++ b/.github/workflows/scanner-build.yaml @@ -86,7 +86,7 @@ jobs: # race-condition-debug - built with -race matrix: ${{ fromJson(needs.define-scanner-job-matrix.outputs.matrix).pre_build_scanner_go_binary }} container: - image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -146,7 +146,7 @@ jobs: needs: pre-build-scanner-go-binary runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.2 if: contains(github.event.pull_request.labels.*.name, 'scan-go-binaries') env: ARTIFACT_DIR: junit-reports/ @@ -200,7 +200,7 @@ jobs: # race-condition-debug - built with -race matrix: ${{ fromJson(needs.define-scanner-job-matrix.outputs.matrix).build_and_push_scanner }} container: - image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -278,7 +278,7 @@ jobs: # race-condition-debug matrix: ${{ fromJson(needs.define-scanner-job-matrix.outputs.matrix).push_scanner_manifests }} container: - image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.2 env: QUAY_RHACS_ENG_RW_USERNAME: ${{ secrets.QUAY_RHACS_ENG_RW_USERNAME }} QUAY_RHACS_ENG_RW_PASSWORD: ${{ secrets.QUAY_RHACS_ENG_RW_PASSWORD }} diff --git a/.github/workflows/scanner-db-integration-tests.yaml b/.github/workflows/scanner-db-integration-tests.yaml index a17a3c2766522..26e0f1d4969f4 100644 --- a/.github/workflows/scanner-db-integration-tests.yaml +++ b/.github/workflows/scanner-db-integration-tests.yaml @@ -17,7 +17,7 @@ jobs: db-integration-tests: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 diff --git a/.github/workflows/scanner-versioned-definitions-update.yaml b/.github/workflows/scanner-versioned-definitions-update.yaml index 54622a9d776cf..7b3284818c596 100644 --- a/.github/workflows/scanner-versioned-definitions-update.yaml +++ b/.github/workflows/scanner-versioned-definitions-update.yaml @@ -190,7 +190,7 @@ jobs: - prepare-environment runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.2 volumes: # The updater makes heavy use of /tmp files. - /tmp:/tmp @@ -282,7 +282,7 @@ jobs: - prepare-environment runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.2 volumes: # The updater makes heavy use of /tmp files. - /tmp:/tmp diff --git a/.github/workflows/style.yaml b/.github/workflows/style.yaml index c6f183a8739af..df239fd819858 100644 --- a/.github/workflows/style.yaml +++ b/.github/workflows/style.yaml @@ -24,7 +24,7 @@ jobs: ARTIFACT_DIR: junit-reports/ runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 @@ -50,7 +50,7 @@ jobs: ARTIFACT_DIR: junit-reports/ runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 @@ -91,7 +91,7 @@ jobs: style-check: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -162,14 +162,14 @@ jobs: - name: Check Cache golangci-lint run: make golangci-lint-cache-status - check-collector-and-scanner-images-exist: - # This job ensures that COLLECTOR_VERSION or SCANNER_VERSION files cannot be updated to a version for which the - # image was not successfully built on Konflux (suffix "-fast"). It also verifies that GHA-built image is there (no - # suffix) so that the failure also happens in this job. + check-dependent-images-exist: + # This job ensures that COLLECTOR_VERSION, FACT_VERSION or SCANNER_VERSION files cannot be updated to a version + # for which the image was not successfully built on Konflux (suffix "-fast"). It also verifies that GHA-built image + # is there (no suffix) so that the failure also happens in this job. runs-on: ubuntu-latest strategy: matrix: - image: ["collector", "scanner", "scanner-slim", "scanner-db", "scanner-db-slim"] + image: ["collector", "fact", "scanner", "scanner-slim", "scanner-db", "scanner-db-slim"] steps: - name: Checkout repo uses: actions/checkout@v6 @@ -178,11 +178,13 @@ jobs: with: gcp-account: ${{ secrets.GCP_SERVICE_ACCOUNT_STACKROX_CI }} - - name: Get image tag from COLLECTOR|SCANNER_VERSION file + - name: Get image tag from COLLECTOR|FACT|SCANNER_VERSION file id: image-tag run: | if [[ "${{ matrix.image }}" == "collector" ]]; then makefile_target="collector-tag" + elif [[ "${{ matrix.image }}" == "fact" ]]; then + makefile_target="fact-tag" else makefile_target="scanner-tag" fi @@ -236,7 +238,7 @@ jobs: openshift-ci-lint: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 @@ -271,7 +273,7 @@ jobs: - misc-checks - style-check - golangci-lint - - check-collector-and-scanner-images-exist + - check-dependent-images-exist - github-actions-lint - github-actions-shellcheck - openshift-ci-lint diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index b529981e09341..48020f614abdf 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -26,7 +26,7 @@ jobs: outputs: new-jiras: ${{ steps.junit2jira.outputs.new-jiras }} container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -97,7 +97,7 @@ jobs: outputs: new-jiras: ${{ steps.junit2jira.outputs.new-jiras }} container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -157,7 +157,7 @@ jobs: go-bench: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -207,7 +207,7 @@ jobs: outputs: new-jiras: ${{ steps.junit2jira.outputs.new-jiras }} container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 @@ -243,7 +243,7 @@ jobs: outputs: new-jiras: ${{ steps.junit2jira.outputs.new-jiras }} container: - image: quay.io/stackrox-io/apollo-ci:stackrox-ui-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-ui-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 @@ -286,7 +286,7 @@ jobs: outputs: new-jiras: ${{ steps.junit2jira.outputs.new-jiras }} container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 volumes: - /usr:/mnt/usr - /opt:/mnt/opt @@ -330,7 +330,7 @@ jobs: outputs: new-jiras: ${{ steps.junit2jira.outputs.new-jiras }} container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 @@ -364,7 +364,7 @@ jobs: openshift-ci-unit-tests: runs-on: ubuntu-latest container: - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 steps: - name: Checkout uses: actions/checkout@v6 diff --git a/.openshift-ci/Dockerfile.build_root b/.openshift-ci/Dockerfile.build_root index 158314ac8b810..dc8ba4bc9110a 100644 --- a/.openshift-ci/Dockerfile.build_root +++ b/.openshift-ci/Dockerfile.build_root @@ -27,4 +27,4 @@ # For an example, see https://github.com/stackrox/stackrox/pull/2762 and its counterpart # https://github.com/openshift/release/pull/31561 -FROM quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 +FROM quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 diff --git a/.openshift-ci/dev-requirements.txt b/.openshift-ci/dev-requirements.txt index 4b112aa426cd4..3cea5ed44ed04 100644 --- a/.openshift-ci/dev-requirements.txt +++ b/.openshift-ci/dev-requirements.txt @@ -1,4 +1,4 @@ -# These versions should match those used in the current CI test image (stackrox-test-0.5.1). +# These versions should match those used in the current CI test image (stackrox-test-0.5.2). # See .github/workflows/{lint,style}.yaml for that. # And the stackrox/rox-ci-image repo for the original source and pinned versions. pycodestyle==2.14.0 diff --git a/.tekton/basic-component-pipeline.yaml b/.tekton/basic-component-pipeline.yaml index d44396956e29e..6edccd53d4341 100644 --- a/.tekton/basic-component-pipeline.yaml +++ b/.tekton/basic-component-pipeline.yaml @@ -35,7 +35,7 @@ spec: - name: name value: show-sbom - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:beb0616db051952b4b861dd8c3e00fa1c0eccbd926feddf71194d3bb3ace9ce7 + value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:e2c1b4eac642f32e91f3bc5d3cb48c5c70888aaf45c3650d9ea34573de7a7fd5 - name: kind value: task resolver: bundles @@ -49,7 +49,7 @@ spec: - name: name value: post-bigquery-metrics - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -77,10 +77,6 @@ spec: description: Path to the Dockerfile inside the context specified by parameter path-context name: dockerfile type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - default: "false" description: Skip checks against built image name: skip-checks @@ -159,15 +155,6 @@ spec: - name: init params: - - name: image-url - # We can't provide a StackRox-style tag because it is not known at this time (requires cloning source, etc.) - # As a workaround, we still provide a unique tag that's based on a revision in order for this task to comply with - # its expected input. We later actually add this tag on a built image with the apply-index-image-tag task. - value: $(params.output-image-repo):konflux-$(params.revision) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - name: enable-cache-proxy value: $(params.enable-cache-proxy) taskRef: @@ -175,7 +162,7 @@ spec: - name: name value: init - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:b349d24cb896573695802d6913d311640b44675ec082b3ad167721946a6a0a71 + value: quay.io/konflux-ci/tekton-catalog/task-init:0.3@sha256:aa6f8632cc23d605c5942505ff1d00280db16a6fda5c4c56c4ed9ae936b5fbc6 - name: kind value: task resolver: bundles @@ -199,14 +186,10 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:56f65a16d3d0485c64ad85af2c1f3e9b0bb4d02d63f2fd0ebb9498d219ca723d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:306b69e6db435ad4a7cf258b6219d9b998eb37da44f5e9ac882ac86a08109154 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] workspaces: - name: basic-auth workspace: git-auth @@ -222,7 +205,7 @@ spec: - name: name value: determine-image-expiration - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -238,7 +221,7 @@ spec: - name: name value: determine-image-tag - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -258,7 +241,7 @@ spec: - name: name value: prefetch-dependencies-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:8eac535f436874ca27c70434ff356ba941d7b649c0e861bca6f4e9fc5e215478 + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:c07551efbd7fc414ae1245ddd93579b00317fee0734980f539fd8aea3cfcb945 - name: kind value: task resolver: bundles @@ -311,14 +294,10 @@ spec: - name: name value: buildah-remote-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah-remote-oci-ta:0.7@sha256:fe66734cde6713f530b19e222680acc5e0d6a533866429659ea8561b746d9ce7 + value: quay.io/konflux-ci/tekton-catalog/task-buildah-remote-oci-ta:0.8@sha256:4c6e3e4c3fe8a289161dfbc38a162d28a0289eb4d51f835e847f8c3677a211f3 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - name: build-image-index params: @@ -338,39 +317,12 @@ spec: - name: name value: build-image-index - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:985d1efe861b02524a7679ecd855624b3d4e3a2e835b6f8a97ec7d135898ec0b + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:30989fa1f475bb8f6bda811b26bd4ddf7187288ed5815ce634ba399341852c75 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] runAfter: [build-images] - - name: apply-index-image-tag - params: - - name: IMAGE_URL - value: $(tasks.build-image-index.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-image-index.results.IMAGE_DIGEST) - - name: ADDITIONAL_TAGS - value: - - konflux-$(params.revision) - taskRef: - params: - - name: name - value: apply-tags - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.2@sha256:c89cd10b2a3f4c43789c5f06ef2b86f528b28f156c20af5e751fa8c0facd457d - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - - name: build-source-image params: - name: BINARY_IMAGE @@ -391,9 +343,6 @@ spec: value: task resolver: bundles when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - input: $(params.build-source-image) operator: in values: ["true"] @@ -409,7 +358,7 @@ spec: - name: name value: deprecated-image-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:e3a55ccdf1091b4a35507f9ee2d1918d8e89a5f96babcb5486b491226da03d6f - name: kind value: task resolver: bundles @@ -434,7 +383,7 @@ spec: - name: name value: clair-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:7c2a32de9021f16f6e8df08a55f539f12e00ea4d96f6fb37f9ea04167032c61f + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:b01d8e2c58eb407ac23fa07b8e44c4631f0cf7257e87507c829fa2486aff9804 - name: kind value: task resolver: bundles @@ -457,7 +406,7 @@ spec: - name: name value: ecosystem-cert-preflight-checks - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:04f75593558f79a27da2336400bc63d460bf0c5669e3c13f40ee2fb650b1ad1e + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:40bc4bcc1c52c114139daee60ec2ddeb59921ecef8a68f241d5593c79b2a21d6 - name: kind value: task resolver: bundles @@ -481,7 +430,7 @@ spec: - name: name value: sast-shell-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:d44336d7bcbd1f7cedee639357a493bd1f661e2859e49e11a34644bdf6819c4e + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:f475b4b6b0c1687fa1aafa5ba38813e04f080b185af2975e12b457742d9dd857 - name: kind value: task resolver: bundles @@ -505,7 +454,7 @@ spec: - name: name value: sast-unicode-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.3@sha256:e5a8d3e8e7be7246a1460385b95c084ea6e8fe7520d40fe4389deb90f1bf5176 + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:b38140b2f0b2163def80e28a792b2702245d38a5610a504f2e56c198f3b8f70b - name: kind value: task resolver: bundles @@ -529,7 +478,7 @@ spec: - name: name value: sast-snyk-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0eca130f289a1a1069a1b92943479f79aa7324e4e68d6396fd777ccd97058f50 + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0c2ab8ce6d419400b63dd67d061052ac51de7b1ebe93f8ae86ed07ac638d756d - name: kind value: task resolver: bundles @@ -554,7 +503,7 @@ spec: - name: name value: clamav-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:f3d2d179cddcc07d0228d9f52959a233037a3afa2619d0a8b2effbb467db80c3 + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:5b5b31eae9063a00b91acc049b536e548d87c730068e439eefe33ab5238ee118 - name: kind value: task resolver: bundles @@ -574,7 +523,7 @@ spec: - name: name value: rpms-signature-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:0b10508c82ccb0f5a06a66ce7af56e9bfd40651ddefdf0f499988e897771ee28 + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:23f133f47d13e6fd35ad6a65138f5b48bd2e6c4e66a2512991ff9f7d90cd7e0e - name: kind value: task resolver: bundles @@ -600,7 +549,7 @@ spec: - name: name value: push-dockerfile-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:08bba4a659ecd48f871bef00b80af58954e5a09fcbb28a1783ddd640c4f6535e + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:2623be4a9bad87ade614b4b24a8f98a4e100042a845e8f162b8237168697294c - name: kind value: task resolver: bundles diff --git a/.tekton/central-db-build.yaml b/.tekton/central-db-build.yaml index 9076f0e1063c6..13473b22d77d9 100644 --- a/.tekton/central-db-build.yaml +++ b/.tekton/central-db-build.yaml @@ -23,8 +23,8 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs - appstudio.openshift.io/component: central-db + appstudio.openshift.io/application: acs-4-10 + appstudio.openshift.io/component: central-db-4-10 pipelines.appstudio.openshift.io/type: build name: central-db-on-push namespace: rh-acs-tenant @@ -60,7 +60,7 @@ spec: - name: extra-labels value: # X.Y in the cpe label must be adjusted for every version stream. - - "cpe=cpe:/a:redhat:advanced_cluster_security:X.Y::el8" + - "cpe=cpe:/a:redhat:advanced_cluster_security:4.10::el8" pipelineRef: name: basic-component-pipeline @@ -77,7 +77,7 @@ spec: memory: 3Gi taskRunTemplate: - serviceAccountName: build-pipeline-central-db + serviceAccountName: build-pipeline-central-db-4-10 # IMPORTANT: when changing timeouts here, read and follow timeout instructions in operator-bundle-build.yaml. timeouts: diff --git a/.tekton/create-custom-snapshot.yaml b/.tekton/create-custom-snapshot.yaml index 4e865b0fd322b..c62aa08ac19ef 100644 --- a/.tekton/create-custom-snapshot.yaml +++ b/.tekton/create-custom-snapshot.yaml @@ -78,7 +78,7 @@ spec: - name: name value: post-bigquery-metrics - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -142,7 +142,7 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:56f65a16d3d0485c64ad85af2c1f3e9b0bb4d02d63f2fd0ebb9498d219ca723d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:306b69e6db435ad4a7cf258b6219d9b998eb37da44f5e9ac882ac86a08109154 - name: kind value: task resolver: bundles @@ -161,7 +161,7 @@ spec: - name: name value: determine-image-tag - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -175,7 +175,7 @@ spec: - name: name value: wait-for-image - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -203,6 +203,11 @@ spec: "internalRepo": "quay.io/rhacs-eng/release-collector", "component": "collector" }, + { + "externalRepo": "registry.redhat.io/advanced-cluster-security/rhacs-fact-rhel8", + "internalRepo": "quay.io/rhacs-eng/release-fact", + "component": "fact" + }, { "externalRepo": "registry.redhat.io/advanced-cluster-security/rhacs-main-rhel8", "internalRepo": "quay.io/rhacs-eng/release-main", @@ -259,7 +264,7 @@ spec: - name: name value: create-snapshot-from-bundle - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles diff --git a/.tekton/images-mirror-set.yaml b/.tekton/images-mirror-set.yaml index 3cc93ea45b2df..6bfdbc33b9ac9 100644 --- a/.tekton/images-mirror-set.yaml +++ b/.tekton/images-mirror-set.yaml @@ -17,6 +17,9 @@ spec: mirrors: - quay.io/rhacs-eng/release-collector - quay.io/rhacs-eng/release-collector-slim + - source: registry.redhat.io/advanced-cluster-security/rhacs-fact-rhel8 + mirrors: + - quay.io/rhacs-eng/release-fact - source: registry.redhat.io/advanced-cluster-security/rhacs-main-rhel8 mirrors: - quay.io/rhacs-eng/release-main diff --git a/.tekton/main-build.yaml b/.tekton/main-build.yaml index a59403e0cbc35..3feb7459e1b1f 100644 --- a/.tekton/main-build.yaml +++ b/.tekton/main-build.yaml @@ -23,8 +23,8 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs - appstudio.openshift.io/component: main + appstudio.openshift.io/application: acs-4-10 + appstudio.openshift.io/component: main-4-10 pipelines.appstudio.openshift.io/type: build name: main-on-push namespace: rh-acs-tenant @@ -64,7 +64,7 @@ spec: - name: extra-labels value: # X.Y in the cpe label must be adjusted for every version stream. - - "cpe=cpe:/a:redhat:advanced_cluster_security:X.Y::el8" + - "cpe=cpe:/a:redhat:advanced_cluster_security:4.10::el8" pipelineRef: name: main-pipeline @@ -102,7 +102,7 @@ spec: memory: 3Gi taskRunTemplate: - serviceAccountName: build-pipeline-main + serviceAccountName: build-pipeline-main-4-10 # IMPORTANT: when changing timeouts here, read and follow timeout instructions in operator-bundle-build.yaml. timeouts: diff --git a/.tekton/main-pipeline.yaml b/.tekton/main-pipeline.yaml index 223d6e9194a92..f3e4818f71dc6 100644 --- a/.tekton/main-pipeline.yaml +++ b/.tekton/main-pipeline.yaml @@ -35,7 +35,7 @@ spec: - name: name value: show-sbom - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:beb0616db051952b4b861dd8c3e00fa1c0eccbd926feddf71194d3bb3ace9ce7 + value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:e2c1b4eac642f32e91f3bc5d3cb48c5c70888aaf45c3650d9ea34573de7a7fd5 - name: kind value: task resolver: bundles @@ -49,7 +49,7 @@ spec: - name: name value: post-bigquery-metrics - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -77,10 +77,6 @@ spec: description: Path to the Dockerfile inside the context specified by parameter path-context name: dockerfile type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - default: "false" description: Skip checks against built image name: skip-checks @@ -160,15 +156,6 @@ spec: - name: init params: - - name: image-url - # We can't provide a StackRox-style tag because it is not known at this time (requires cloning source, etc.) - # As a workaround, we still provide a unique tag that's based on a revision in order for this task to comply with - # its expected input. We later actually add this tag on a built image with the apply-index-image-tag task. - value: $(params.output-image-repo):konflux-$(params.revision) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - name: enable-cache-proxy value: $(params.enable-cache-proxy) taskRef: @@ -176,7 +163,7 @@ spec: - name: name value: init - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:b349d24cb896573695802d6913d311640b44675ec082b3ad167721946a6a0a71 + value: quay.io/konflux-ci/tekton-catalog/task-init:0.3@sha256:aa6f8632cc23d605c5942505ff1d00280db16a6fda5c4c56c4ed9ae936b5fbc6 - name: kind value: task resolver: bundles @@ -200,14 +187,10 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:56f65a16d3d0485c64ad85af2c1f3e9b0bb4d02d63f2fd0ebb9498d219ca723d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:306b69e6db435ad4a7cf258b6219d9b998eb37da44f5e9ac882ac86a08109154 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] workspaces: - name: basic-auth workspace: git-auth @@ -223,7 +206,7 @@ spec: - name: name value: determine-image-expiration - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -239,7 +222,7 @@ spec: - name: name value: determine-image-tag - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -259,7 +242,7 @@ spec: - name: name value: fetch-external-networks - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -284,7 +267,7 @@ spec: - name: name value: prefetch-dependencies-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:8eac535f436874ca27c70434ff356ba941d7b649c0e861bca6f4e9fc5e215478 + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:c07551efbd7fc414ae1245ddd93579b00317fee0734980f539fd8aea3cfcb945 - name: kind value: task resolver: bundles @@ -337,14 +320,10 @@ spec: - name: name value: buildah-remote-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah-remote-oci-ta:0.7@sha256:fe66734cde6713f530b19e222680acc5e0d6a533866429659ea8561b746d9ce7 + value: quay.io/konflux-ci/tekton-catalog/task-buildah-remote-oci-ta:0.8@sha256:4c6e3e4c3fe8a289161dfbc38a162d28a0289eb4d51f835e847f8c3677a211f3 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] timeout: 2h0m0s - name: build-image-index @@ -365,39 +344,12 @@ spec: - name: name value: build-image-index - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:985d1efe861b02524a7679ecd855624b3d4e3a2e835b6f8a97ec7d135898ec0b + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:30989fa1f475bb8f6bda811b26bd4ddf7187288ed5815ce634ba399341852c75 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] runAfter: [build-images] - - name: apply-index-image-tag - params: - - name: IMAGE_URL - value: $(tasks.build-image-index.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-image-index.results.IMAGE_DIGEST) - - name: ADDITIONAL_TAGS - value: - - konflux-$(params.revision) - taskRef: - params: - - name: name - value: apply-tags - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.2@sha256:c89cd10b2a3f4c43789c5f06ef2b86f528b28f156c20af5e751fa8c0facd457d - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - - name: build-source-image params: - name: BINARY_IMAGE @@ -418,9 +370,6 @@ spec: value: task resolver: bundles when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - input: $(params.build-source-image) operator: in values: ["true"] @@ -436,7 +385,7 @@ spec: - name: name value: deprecated-image-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:e3a55ccdf1091b4a35507f9ee2d1918d8e89a5f96babcb5486b491226da03d6f - name: kind value: task resolver: bundles @@ -461,7 +410,7 @@ spec: - name: name value: clair-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:7c2a32de9021f16f6e8df08a55f539f12e00ea4d96f6fb37f9ea04167032c61f + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:b01d8e2c58eb407ac23fa07b8e44c4631f0cf7257e87507c829fa2486aff9804 - name: kind value: task resolver: bundles @@ -484,7 +433,7 @@ spec: - name: name value: ecosystem-cert-preflight-checks - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:04f75593558f79a27da2336400bc63d460bf0c5669e3c13f40ee2fb650b1ad1e + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:40bc4bcc1c52c114139daee60ec2ddeb59921ecef8a68f241d5593c79b2a21d6 - name: kind value: task resolver: bundles @@ -508,7 +457,7 @@ spec: - name: name value: sast-shell-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:d44336d7bcbd1f7cedee639357a493bd1f661e2859e49e11a34644bdf6819c4e + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:f475b4b6b0c1687fa1aafa5ba38813e04f080b185af2975e12b457742d9dd857 - name: kind value: task resolver: bundles @@ -532,7 +481,7 @@ spec: - name: name value: sast-unicode-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.3@sha256:e5a8d3e8e7be7246a1460385b95c084ea6e8fe7520d40fe4389deb90f1bf5176 + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:b38140b2f0b2163def80e28a792b2702245d38a5610a504f2e56c198f3b8f70b - name: kind value: task resolver: bundles @@ -556,7 +505,7 @@ spec: - name: name value: sast-snyk-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0eca130f289a1a1069a1b92943479f79aa7324e4e68d6396fd777ccd97058f50 + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0c2ab8ce6d419400b63dd67d061052ac51de7b1ebe93f8ae86ed07ac638d756d - name: kind value: task resolver: bundles @@ -581,7 +530,7 @@ spec: - name: name value: clamav-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:f3d2d179cddcc07d0228d9f52959a233037a3afa2619d0a8b2effbb467db80c3 + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:5b5b31eae9063a00b91acc049b536e548d87c730068e439eefe33ab5238ee118 - name: kind value: task resolver: bundles @@ -601,7 +550,7 @@ spec: - name: name value: rpms-signature-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:0b10508c82ccb0f5a06a66ce7af56e9bfd40651ddefdf0f499988e897771ee28 + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:23f133f47d13e6fd35ad6a65138f5b48bd2e6c4e66a2512991ff9f7d90cd7e0e - name: kind value: task resolver: bundles @@ -627,7 +576,7 @@ spec: - name: name value: push-dockerfile-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:08bba4a659ecd48f871bef00b80af58954e5a09fcbb28a1783ddd640c4f6535e + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:2623be4a9bad87ade614b4b24a8f98a4e100042a845e8f162b8237168697294c - name: kind value: task resolver: bundles diff --git a/.tekton/operator-build.yaml b/.tekton/operator-build.yaml index c7f3b2df2c97e..c694638bb3593 100644 --- a/.tekton/operator-build.yaml +++ b/.tekton/operator-build.yaml @@ -23,8 +23,8 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs - appstudio.openshift.io/component: operator + appstudio.openshift.io/application: acs-4-10 + appstudio.openshift.io/component: operator-4-10 pipelines.appstudio.openshift.io/type: build name: operator-on-push namespace: rh-acs-tenant @@ -59,7 +59,7 @@ spec: - name: extra-labels value: # X.Y in the cpe label must be adjusted for every version stream. - - "cpe=cpe:/a:redhat:advanced_cluster_security:X.Y::el8" + - "cpe=cpe:/a:redhat:advanced_cluster_security:4.10::el8" pipelineRef: name: basic-component-pipeline @@ -85,7 +85,7 @@ spec: memory: 3Gi taskRunTemplate: - serviceAccountName: build-pipeline-operator + serviceAccountName: build-pipeline-operator-4-10 # IMPORTANT: when changing timeouts here, read and follow timeout instructions in operator-bundle-build.yaml. timeouts: diff --git a/.tekton/operator-bundle-build.yaml b/.tekton/operator-bundle-build.yaml index 08f39fc7e2c11..05ec6d04a9fac 100644 --- a/.tekton/operator-bundle-build.yaml +++ b/.tekton/operator-bundle-build.yaml @@ -23,8 +23,8 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs - appstudio.openshift.io/component: operator-bundle + appstudio.openshift.io/application: acs-4-10 + appstudio.openshift.io/component: operator-bundle-4-10 pipelines.appstudio.openshift.io/type: build name: operator-bundle-on-push namespace: rh-acs-tenant @@ -49,7 +49,7 @@ spec: - name: prefetch-input value: | [ - { "type": "pip", "path": "operator/bundle_helpers" } + { "type": "rpm", "path": "." } ] - name: build-source-image value: 'true' @@ -60,7 +60,7 @@ spec: - name: extra-labels value: # X.Y in the cpe label must be adjusted for every version stream. - - "cpe=cpe:/a:redhat:advanced_cluster_security:X.Y::el8" + - "cpe=cpe:/a:redhat:advanced_cluster_security:4.10::el8" pipelineRef: name: operator-bundle-pipeline @@ -77,7 +77,7 @@ spec: memory: 3Gi taskRunTemplate: - serviceAccountName: build-pipeline-operator-bundle + serviceAccountName: build-pipeline-operator-bundle-4-10 # When building the operator-bundle, we must resolve image digests for all other ACS product images in order to inject # these digests in the bundle's ClusterServiceVersion file. For this, the bundle pipeline waits for each image to be diff --git a/.tekton/operator-bundle-pipeline.yaml b/.tekton/operator-bundle-pipeline.yaml index 228a65276b860..0065d765bd3c5 100644 --- a/.tekton/operator-bundle-pipeline.yaml +++ b/.tekton/operator-bundle-pipeline.yaml @@ -35,7 +35,7 @@ spec: - name: name value: show-sbom - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:beb0616db051952b4b861dd8c3e00fa1c0eccbd926feddf71194d3bb3ace9ce7 + value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:e2c1b4eac642f32e91f3bc5d3cb48c5c70888aaf45c3650d9ea34573de7a7fd5 - name: kind value: task resolver: bundles @@ -49,7 +49,7 @@ spec: - name: name value: post-bigquery-metrics - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -77,10 +77,6 @@ spec: description: Path to the Dockerfile inside the context specified by parameter path-context name: dockerfile type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - default: "false" description: Skip checks against built image name: skip-checks @@ -201,6 +197,15 @@ spec: type: string default: "registry.redhat.io/advanced-cluster-security/rhacs-collector-rhel8" + - name: fact-image-build-repo + description: Repository where the (unreleased) fact image is pushed by its build pipeline. + type: string + default: "quay.io/rhacs-eng/release-fact" + - name: fact-image-catalog-repo + description: Repository within the Red Hat Container Catalog where the fact image is pushed to during the release. + type: string + default: "registry.redhat.io/advanced-cluster-security/rhacs-fact-rhel8" + - name: roxctl-image-build-repo description: Repository where the (unreleased) roxctl image is pushed by its build pipeline. type: string @@ -247,15 +252,6 @@ spec: - name: init params: - - name: image-url - # We can't provide a StackRox-style tag because it is not known at this time (requires cloning source, etc.) - # As a workaround, we still provide a unique tag that's based on a revision to this task to comply with its - # expected input. We later actually add this tag on a built image with apply-tags task. - value: $(params.output-image-repo):konflux-$(params.revision) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - name: enable-cache-proxy value: $(params.enable-cache-proxy) taskRef: @@ -263,7 +259,7 @@ spec: - name: name value: init - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:b349d24cb896573695802d6913d311640b44675ec082b3ad167721946a6a0a71 + value: quay.io/konflux-ci/tekton-catalog/task-init:0.3@sha256:aa6f8632cc23d605c5942505ff1d00280db16a6fda5c4c56c4ed9ae936b5fbc6 - name: kind value: task resolver: bundles @@ -287,14 +283,10 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:56f65a16d3d0485c64ad85af2c1f3e9b0bb4d02d63f2fd0ebb9498d219ca723d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:306b69e6db435ad4a7cf258b6219d9b998eb37da44f5e9ac882ac86a08109154 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] workspaces: - name: basic-auth workspace: git-auth @@ -310,7 +302,7 @@ spec: - name: name value: determine-image-expiration - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -326,7 +318,7 @@ spec: - name: name value: determine-image-tag - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -341,12 +333,14 @@ spec: value: $(params.output-image-repo):konflux-$(params.revision).prefetch - name: ociArtifactExpiresAfter value: $(params.oci-artifact-expires-after) + - name: ACTIVATION_KEY + value: subscription-manager-activation-key-prod taskRef: params: - name: name value: prefetch-dependencies-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:8eac535f436874ca27c70434ff356ba941d7b649c0e861bca6f4e9fc5e215478 + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:c07551efbd7fc414ae1245ddd93579b00317fee0734980f539fd8aea3cfcb945 - name: kind value: task resolver: bundles @@ -363,7 +357,7 @@ spec: - name: name value: wait-for-image - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -434,6 +428,14 @@ spec: # This timeout must be the same as the pipeline timeout in `collector-retag.yaml` timeout: 40m + - name: wait-for-fact-image + params: + - name: IMAGE + value: "$(params.fact-image-build-repo):$(tasks.determine-image-tag.results.IMAGE_TAG)" + taskRef: *wait-for-image-ref + # This timeout must be the same as the pipeline timeout in `retag-fact.yaml` + timeout: 40m + - name: wait-for-roxctl-image params: - name: IMAGE @@ -479,6 +481,7 @@ spec: - RELATED_IMAGE_SCANNER_V4=$(params.scanner-v4-image-catalog-repo)@$(tasks.wait-for-scanner-v4-image.results.IMAGE_DIGEST) - RELATED_IMAGE_SCANNER_V4_DB=$(params.scanner-v4-db-image-catalog-repo)@$(tasks.wait-for-scanner-v4-db-image.results.IMAGE_DIGEST) - RELATED_IMAGE_COLLECTOR=$(params.collector-image-catalog-repo)@$(tasks.wait-for-collector-image.results.IMAGE_DIGEST) + - RELATED_IMAGE_FACT=$(params.fact-image-catalog-repo)@$(tasks.wait-for-fact-image.results.IMAGE_DIGEST) - RELATED_IMAGE_ROXCTL=$(params.roxctl-image-catalog-repo)@$(tasks.wait-for-roxctl-image.results.IMAGE_DIGEST) - RELATED_IMAGE_CENTRAL_DB=$(params.central-db-image-catalog-repo)@$(tasks.wait-for-central-db-image.results.IMAGE_DIGEST) - name: SOURCE_ARTIFACT @@ -500,30 +503,7 @@ spec: - name: name value: buildah-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah-oci-ta:0.7@sha256:eeb86e8739801237bbefa84e1ab7873c887ca598ef859dd6d06548948b11b95f - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - - - name: apply-tags - params: - - name: ADDITIONAL_TAGS - value: - - konflux-$(params.revision) - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - taskRef: - params: - - name: name - value: apply-tags - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.2@sha256:c89cd10b2a3f4c43789c5f06ef2b86f528b28f156c20af5e751fa8c0facd457d + value: quay.io/konflux-ci/tekton-catalog/task-buildah-oci-ta:0.8@sha256:6eb38e7dede283e48aec619572f52f2589513f668d0345d084cf99133bbaa39c - name: kind value: task resolver: bundles @@ -548,9 +528,6 @@ spec: value: task resolver: bundles when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - input: $(params.build-source-image) operator: in values: ["true"] @@ -566,7 +543,7 @@ spec: - name: name value: deprecated-image-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:e3a55ccdf1091b4a35507f9ee2d1918d8e89a5f96babcb5486b491226da03d6f - name: kind value: task resolver: bundles @@ -586,7 +563,7 @@ spec: - name: name value: clair-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:7c2a32de9021f16f6e8df08a55f539f12e00ea4d96f6fb37f9ea04167032c61f + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:b01d8e2c58eb407ac23fa07b8e44c4631f0cf7257e87507c829fa2486aff9804 - name: kind value: task resolver: bundles @@ -608,7 +585,7 @@ spec: - name: name value: fips-operator-bundle-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-fips-operator-bundle-check-oci-ta:0.1@sha256:d3b0730dac6a72db1de4a90f3f2703fb261365b2202cb79a9cf7cc56cec0671f + value: quay.io/konflux-ci/tekton-catalog/task-fips-operator-bundle-check-oci-ta:0.1@sha256:6d2e40bcc0f4a4430e99e522e7764a8c3b07b76f33839b231dd6e3f0ffa44b63 - name: kind value: task resolver: bundles @@ -632,7 +609,7 @@ spec: - name: name value: sast-shell-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:d44336d7bcbd1f7cedee639357a493bd1f661e2859e49e11a34644bdf6819c4e + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:f475b4b6b0c1687fa1aafa5ba38813e04f080b185af2975e12b457742d9dd857 - name: kind value: task resolver: bundles @@ -656,7 +633,7 @@ spec: - name: name value: sast-unicode-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.3@sha256:e5a8d3e8e7be7246a1460385b95c084ea6e8fe7520d40fe4389deb90f1bf5176 + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:b38140b2f0b2163def80e28a792b2702245d38a5610a504f2e56c198f3b8f70b - name: kind value: task resolver: bundles @@ -680,7 +657,7 @@ spec: - name: name value: sast-snyk-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0eca130f289a1a1069a1b92943479f79aa7324e4e68d6396fd777ccd97058f50 + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0c2ab8ce6d419400b63dd67d061052ac51de7b1ebe93f8ae86ed07ac638d756d - name: kind value: task resolver: bundles @@ -700,7 +677,7 @@ spec: - name: name value: clamav-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:f3d2d179cddcc07d0228d9f52959a233037a3afa2619d0a8b2effbb467db80c3 + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:5b5b31eae9063a00b91acc049b536e548d87c730068e439eefe33ab5238ee118 - name: kind value: task resolver: bundles @@ -720,7 +697,7 @@ spec: - name: name value: rpms-signature-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:0b10508c82ccb0f5a06a66ce7af56e9bfd40651ddefdf0f499988e897771ee28 + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:23f133f47d13e6fd35ad6a65138f5b48bd2e6c4e66a2512991ff9f7d90cd7e0e - name: kind value: task resolver: bundles @@ -746,7 +723,7 @@ spec: - name: name value: push-dockerfile-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:08bba4a659ecd48f871bef00b80af58954e5a09fcbb28a1783ddd640c4f6535e + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:2623be4a9bad87ade614b4b24a8f98a4e100042a845e8f162b8237168697294c - name: kind value: task resolver: bundles diff --git a/.tekton/retag-collector.yaml b/.tekton/retag-collector.yaml index 402dfb62469e1..a31f327d88729 100644 --- a/.tekton/retag-collector.yaml +++ b/.tekton/retag-collector.yaml @@ -23,7 +23,7 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs + appstudio.openshift.io/application: acs-4-10 name: retag-collector namespace: rh-acs-tenant @@ -45,7 +45,7 @@ spec: name: retag-pipeline taskRunTemplate: - serviceAccountName: build-pipeline-collector + serviceAccountName: build-pipeline-collector-4-10 timeouts: tasks: 30m diff --git a/.tekton/retag-fact.yaml b/.tekton/retag-fact.yaml new file mode 100644 index 0000000000000..84015040fa457 --- /dev/null +++ b/.tekton/retag-fact.yaml @@ -0,0 +1,59 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun + +metadata: + annotations: + build.appstudio.openshift.io/repo: https://github.com/stackrox/stackrox?rev={{revision}} + build.appstudio.redhat.com/commit_sha: '{{revision}}' + build.appstudio.redhat.com/pull_request_number: '{{pull_request_number}}' + build.appstudio.redhat.com/target_branch: '{{target_branch}}' + pipelinesascode.tekton.dev/max-keep-runs: "500" + # TODO(ROX-21073): re-enable for all PR branches + pipelinesascode.tekton.dev/on-cel-expression: | + ( + event == "push" && target_branch.matches("^(master|release-.*|refs/tags/.*)$") + ) || ( + event == "pull_request" && ( + target_branch.startsWith("release-") || + source_branch.matches("(konflux|renovate|appstudio|rhtap)") || + (has(body.pull_request) && has(body.pull_request.labels) && body.pull_request.labels.exists(l, l.name == "konflux-build")) + ) && body.action != "ready_for_review" + ) + # The empty `on-label` annotation is a workaround to make sure the pipeline gets triggered when the label gets first + # added to the PR. See the Slack tread linked from ROX-30580. + pipelinesascode.tekton.dev/on-label: "[]" + labels: + appstudio.openshift.io/application: acs-4-10 + name: retag-fact + namespace: rh-acs-tenant + +spec: + + params: + - name: git-url + value: '{{source_url}}' + - name: revision + value: '{{revision}}' + - name: input-image-repo + value: quay.io/rhacs-eng/release-fact + - name: input-image-tag-makefile-target + value: fact-tag + - name: output-image-repo + value: quay.io/rhacs-eng/release-fact + + pipelineRef: + name: retag-pipeline + + taskRunTemplate: + serviceAccountName: build-pipeline-fact-4-10 + + timeouts: + tasks: 30m + # Reserve time for final tasks to run. + finally: 10m + pipeline: 40m + + workspaces: + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' diff --git a/.tekton/retag-pipeline.yaml b/.tekton/retag-pipeline.yaml index 71cd2995cde74..74219ba61aaf6 100644 --- a/.tekton/retag-pipeline.yaml +++ b/.tekton/retag-pipeline.yaml @@ -35,7 +35,7 @@ spec: - name: name value: post-bigquery-metrics - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -117,7 +117,7 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:56f65a16d3d0485c64ad85af2c1f3e9b0bb4d02d63f2fd0ebb9498d219ca723d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:306b69e6db435ad4a7cf258b6219d9b998eb37da44f5e9ac882ac86a08109154 - name: kind value: task resolver: bundles @@ -136,7 +136,7 @@ spec: - name: name value: determine-image-tag - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -154,7 +154,7 @@ spec: - name: name value: determine-dependency-image-tag - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -170,7 +170,7 @@ spec: - name: name value: wait-for-image - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -195,7 +195,7 @@ spec: - name: name value: retag-image - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles diff --git a/.tekton/retag-scanner-db-slim.yaml b/.tekton/retag-scanner-db-slim.yaml index 581a18e658190..a96d04be41845 100644 --- a/.tekton/retag-scanner-db-slim.yaml +++ b/.tekton/retag-scanner-db-slim.yaml @@ -23,7 +23,7 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs + appstudio.openshift.io/application: acs-4-10 name: retag-scanner-db-slim namespace: rh-acs-tenant @@ -45,7 +45,7 @@ spec: name: retag-pipeline taskRunTemplate: - serviceAccountName: build-pipeline-scanner-db-slim + serviceAccountName: build-pipeline-scanner-db-slim-4-10 timeouts: tasks: 30m diff --git a/.tekton/retag-scanner-db.yaml b/.tekton/retag-scanner-db.yaml index 500aa96403280..56cafa3f1c38a 100644 --- a/.tekton/retag-scanner-db.yaml +++ b/.tekton/retag-scanner-db.yaml @@ -23,7 +23,7 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs + appstudio.openshift.io/application: acs-4-10 name: retag-scanner-db namespace: rh-acs-tenant @@ -45,7 +45,7 @@ spec: name: retag-pipeline taskRunTemplate: - serviceAccountName: build-pipeline-scanner-db + serviceAccountName: build-pipeline-scanner-db-4-10 timeouts: tasks: 30m diff --git a/.tekton/retag-scanner-slim.yaml b/.tekton/retag-scanner-slim.yaml index 9a0347886450c..e15b321bbbf74 100644 --- a/.tekton/retag-scanner-slim.yaml +++ b/.tekton/retag-scanner-slim.yaml @@ -23,7 +23,7 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs + appstudio.openshift.io/application: acs-4-10 name: retag-scanner-slim namespace: rh-acs-tenant @@ -45,7 +45,7 @@ spec: name: retag-pipeline taskRunTemplate: - serviceAccountName: build-pipeline-scanner-slim + serviceAccountName: build-pipeline-scanner-slim-4-10 timeouts: tasks: 30m diff --git a/.tekton/retag-scanner.yaml b/.tekton/retag-scanner.yaml index 1ef222b253e72..934bdf6a937e7 100644 --- a/.tekton/retag-scanner.yaml +++ b/.tekton/retag-scanner.yaml @@ -23,7 +23,7 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs + appstudio.openshift.io/application: acs-4-10 name: retag-scanner namespace: rh-acs-tenant @@ -45,7 +45,7 @@ spec: name: retag-pipeline taskRunTemplate: - serviceAccountName: build-pipeline-scanner + serviceAccountName: build-pipeline-scanner-4-10 timeouts: tasks: 30m diff --git a/.tekton/roxctl-build.yaml b/.tekton/roxctl-build.yaml index a5386f4c3a007..b9dfcd58fb482 100644 --- a/.tekton/roxctl-build.yaml +++ b/.tekton/roxctl-build.yaml @@ -23,8 +23,8 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs - appstudio.openshift.io/component: roxctl + appstudio.openshift.io/application: acs-4-10 + appstudio.openshift.io/component: roxctl-4-10 pipelines.appstudio.openshift.io/type: build name: roxctl-on-push namespace: rh-acs-tenant @@ -59,7 +59,7 @@ spec: - name: extra-labels value: # X.Y in the cpe label must be adjusted for every version stream. - - "cpe=cpe:/a:redhat:advanced_cluster_security:X.Y::el8" + - "cpe=cpe:/a:redhat:advanced_cluster_security:4.10::el8" pipelineRef: name: basic-component-pipeline @@ -85,7 +85,7 @@ spec: memory: 3Gi taskRunTemplate: - serviceAccountName: build-pipeline-roxctl + serviceAccountName: build-pipeline-roxctl-4-10 # IMPORTANT: when changing timeouts here, read and follow timeout instructions in operator-bundle-build.yaml. timeouts: diff --git a/.tekton/scanner-v4-build.yaml b/.tekton/scanner-v4-build.yaml index c6c890a261eb1..a72a18685a7be 100644 --- a/.tekton/scanner-v4-build.yaml +++ b/.tekton/scanner-v4-build.yaml @@ -23,8 +23,8 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs - appstudio.openshift.io/component: scanner-v4 + appstudio.openshift.io/application: acs-4-10 + appstudio.openshift.io/component: scanner-v4-4-10 pipelines.appstudio.openshift.io/type: build name: scanner-v4-on-push namespace: rh-acs-tenant @@ -59,7 +59,7 @@ spec: - name: extra-labels value: # X.Y in the cpe label must be adjusted for every version stream. - - "cpe=cpe:/a:redhat:advanced_cluster_security:X.Y::el8" + - "cpe=cpe:/a:redhat:advanced_cluster_security:4.10::el8" pipelineRef: name: scanner-v4-pipeline @@ -85,7 +85,7 @@ spec: memory: 3Gi taskRunTemplate: - serviceAccountName: build-pipeline-scanner-v4 + serviceAccountName: build-pipeline-scanner-v4-4-10 # IMPORTANT: when changing timeouts here, read and follow timeout instructions in operator-bundle-build.yaml. timeouts: diff --git a/.tekton/scanner-v4-db-build.yaml b/.tekton/scanner-v4-db-build.yaml index 5b74dc9b763eb..0043f6640f739 100644 --- a/.tekton/scanner-v4-db-build.yaml +++ b/.tekton/scanner-v4-db-build.yaml @@ -23,8 +23,8 @@ metadata: # added to the PR. See the Slack tread linked from ROX-30580. pipelinesascode.tekton.dev/on-label: "[]" labels: - appstudio.openshift.io/application: acs - appstudio.openshift.io/component: scanner-v4-db + appstudio.openshift.io/application: acs-4-10 + appstudio.openshift.io/component: scanner-v4-db-4-10 pipelines.appstudio.openshift.io/type: build name: scanner-v4-db-on-push namespace: rh-acs-tenant @@ -60,7 +60,7 @@ spec: - name: extra-labels value: # X.Y in the cpe label must be adjusted for every version stream. - - "cpe=cpe:/a:redhat:advanced_cluster_security:X.Y::el8" + - "cpe=cpe:/a:redhat:advanced_cluster_security:4.10::el8" pipelineRef: name: basic-component-pipeline @@ -77,7 +77,7 @@ spec: memory: 3Gi taskRunTemplate: - serviceAccountName: build-pipeline-scanner-v4-db + serviceAccountName: build-pipeline-scanner-v4-db-4-10 # IMPORTANT: when changing timeouts here, read and follow timeout instructions in operator-bundle-build.yaml. timeouts: diff --git a/.tekton/scanner-v4-pipeline.yaml b/.tekton/scanner-v4-pipeline.yaml index de426d4da0bc1..7fafed6af2583 100644 --- a/.tekton/scanner-v4-pipeline.yaml +++ b/.tekton/scanner-v4-pipeline.yaml @@ -35,7 +35,7 @@ spec: - name: name value: show-sbom - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:beb0616db051952b4b861dd8c3e00fa1c0eccbd926feddf71194d3bb3ace9ce7 + value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:e2c1b4eac642f32e91f3bc5d3cb48c5c70888aaf45c3650d9ea34573de7a7fd5 - name: kind value: task resolver: bundles @@ -49,7 +49,7 @@ spec: - name: name value: post-bigquery-metrics - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -77,10 +77,6 @@ spec: description: Path to the Dockerfile inside the context specified by parameter path-context name: dockerfile type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - default: "false" description: Skip checks against built image name: skip-checks @@ -159,15 +155,6 @@ spec: - name: init params: - - name: image-url - # We can't provide a StackRox-style tag because it is not known at this time (requires cloning source, etc.) - # As a workaround, we still provide a unique tag that's based on a revision in order for this task to comply with - # its expected input. We later actually add this tag on a built image with the apply-index-image-tag task. - value: $(params.output-image-repo):konflux-$(params.revision) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - name: enable-cache-proxy value: $(params.enable-cache-proxy) taskRef: @@ -175,7 +162,7 @@ spec: - name: name value: init - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:b349d24cb896573695802d6913d311640b44675ec082b3ad167721946a6a0a71 + value: quay.io/konflux-ci/tekton-catalog/task-init:0.3@sha256:aa6f8632cc23d605c5942505ff1d00280db16a6fda5c4c56c4ed9ae936b5fbc6 - name: kind value: task resolver: bundles @@ -199,14 +186,10 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:56f65a16d3d0485c64ad85af2c1f3e9b0bb4d02d63f2fd0ebb9498d219ca723d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:306b69e6db435ad4a7cf258b6219d9b998eb37da44f5e9ac882ac86a08109154 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] workspaces: - name: basic-auth workspace: git-auth @@ -222,7 +205,7 @@ spec: - name: name value: determine-image-expiration - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -238,7 +221,7 @@ spec: - name: name value: determine-image-tag - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -258,7 +241,7 @@ spec: - name: name value: fetch-scanner-v4-vuln-mappings - name: bundle - value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:c3b069313d4de5d67dc662e31cbcdde02e134be5fe7dcdb5bceeb670f89fcf52 + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:4f382e13876ba779243afce2235585b0553129059c7299aa329e3ba632fe03bc - name: kind value: task resolver: bundles @@ -278,7 +261,7 @@ spec: - name: name value: prefetch-dependencies-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:8eac535f436874ca27c70434ff356ba941d7b649c0e861bca6f4e9fc5e215478 + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:c07551efbd7fc414ae1245ddd93579b00317fee0734980f539fd8aea3cfcb945 - name: kind value: task resolver: bundles @@ -331,14 +314,10 @@ spec: - name: name value: buildah-remote-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah-remote-oci-ta:0.7@sha256:fe66734cde6713f530b19e222680acc5e0d6a533866429659ea8561b746d9ce7 + value: quay.io/konflux-ci/tekton-catalog/task-buildah-remote-oci-ta:0.8@sha256:4c6e3e4c3fe8a289161dfbc38a162d28a0289eb4d51f835e847f8c3677a211f3 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - name: build-image-index params: @@ -358,39 +337,12 @@ spec: - name: name value: build-image-index - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:985d1efe861b02524a7679ecd855624b3d4e3a2e835b6f8a97ec7d135898ec0b + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:30989fa1f475bb8f6bda811b26bd4ddf7187288ed5815ce634ba399341852c75 - name: kind value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] runAfter: [build-images] - - name: apply-index-image-tag - params: - - name: IMAGE_URL - value: $(tasks.build-image-index.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-image-index.results.IMAGE_DIGEST) - - name: ADDITIONAL_TAGS - value: - - konflux-$(params.revision) - taskRef: - params: - - name: name - value: apply-tags - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.2@sha256:c89cd10b2a3f4c43789c5f06ef2b86f528b28f156c20af5e751fa8c0facd457d - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - - name: build-source-image params: - name: BINARY_IMAGE @@ -411,9 +363,6 @@ spec: value: task resolver: bundles when: - - input: $(tasks.init.results.build) - operator: in - values: ["true"] - input: $(params.build-source-image) operator: in values: ["true"] @@ -429,7 +378,7 @@ spec: - name: name value: deprecated-image-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:e3a55ccdf1091b4a35507f9ee2d1918d8e89a5f96babcb5486b491226da03d6f - name: kind value: task resolver: bundles @@ -454,7 +403,7 @@ spec: - name: name value: clair-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:7c2a32de9021f16f6e8df08a55f539f12e00ea4d96f6fb37f9ea04167032c61f + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:b01d8e2c58eb407ac23fa07b8e44c4631f0cf7257e87507c829fa2486aff9804 - name: kind value: task resolver: bundles @@ -477,7 +426,7 @@ spec: - name: name value: ecosystem-cert-preflight-checks - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:04f75593558f79a27da2336400bc63d460bf0c5669e3c13f40ee2fb650b1ad1e + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:40bc4bcc1c52c114139daee60ec2ddeb59921ecef8a68f241d5593c79b2a21d6 - name: kind value: task resolver: bundles @@ -501,7 +450,7 @@ spec: - name: name value: sast-shell-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:d44336d7bcbd1f7cedee639357a493bd1f661e2859e49e11a34644bdf6819c4e + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:f475b4b6b0c1687fa1aafa5ba38813e04f080b185af2975e12b457742d9dd857 - name: kind value: task resolver: bundles @@ -525,7 +474,7 @@ spec: - name: name value: sast-unicode-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.3@sha256:e5a8d3e8e7be7246a1460385b95c084ea6e8fe7520d40fe4389deb90f1bf5176 + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:b38140b2f0b2163def80e28a792b2702245d38a5610a504f2e56c198f3b8f70b - name: kind value: task resolver: bundles @@ -549,7 +498,7 @@ spec: - name: name value: sast-snyk-check-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0eca130f289a1a1069a1b92943479f79aa7324e4e68d6396fd777ccd97058f50 + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:0c2ab8ce6d419400b63dd67d061052ac51de7b1ebe93f8ae86ed07ac638d756d - name: kind value: task resolver: bundles @@ -574,7 +523,7 @@ spec: - name: name value: clamav-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:f3d2d179cddcc07d0228d9f52959a233037a3afa2619d0a8b2effbb467db80c3 + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:5b5b31eae9063a00b91acc049b536e548d87c730068e439eefe33ab5238ee118 - name: kind value: task resolver: bundles @@ -594,7 +543,7 @@ spec: - name: name value: rpms-signature-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:0b10508c82ccb0f5a06a66ce7af56e9bfd40651ddefdf0f499988e897771ee28 + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:23f133f47d13e6fd35ad6a65138f5b48bd2e6c4e66a2512991ff9f7d90cd7e0e - name: kind value: task resolver: bundles @@ -620,7 +569,7 @@ spec: - name: name value: push-dockerfile-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:08bba4a659ecd48f871bef00b80af58954e5a09fcbb28a1783ddd640c4f6535e + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:2623be4a9bad87ade614b4b24a8f98a4e100042a845e8f162b8237168697294c - name: kind value: task resolver: bundles diff --git a/BUILD_IMAGE_VERSION b/BUILD_IMAGE_VERSION index 44776a28929be..455f95443ea3c 100644 --- a/BUILD_IMAGE_VERSION +++ b/BUILD_IMAGE_VERSION @@ -1 +1 @@ -stackrox-build-0.5.1 +stackrox-build-0.5.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f267c6769d6e..70767e63fabe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ Put an entry in this file if your change is user-visible and you consider it _pa Changes should still be described appropriately in JIRA/doc input pages, for inclusion in downstream release notes. -## [NEXT RELEASE] +## [4.10.0] ### Added Features @@ -33,6 +33,10 @@ Changes should still be described appropriately in JIRA/doc input pages, for inc ### Deprecated Features - ROX-32851: The `roxctl netpol generate`, `roxctl netpol connectivity map`, and `roxctl netpol connectivity diff` commands are deprecated because they rely on the unmaintained NP-Guard library and will be removed in a future release. +- ROX-32867: The Compliance V1 feature has been deprecated, and it is planned to be removed in a future release. This includes: + - The Compliance Dashboard + - The Compliance V1 API endpoints + - The Compliance Configuration Management Board ### Technical Changes - ROX-30769: Update Node.js requirement for ui folder to 22.13.0 diff --git a/COLLECTOR_VERSION b/COLLECTOR_VERSION index b94c548573151..5edc0a683b900 100644 --- a/COLLECTOR_VERSION +++ b/COLLECTOR_VERSION @@ -1 +1 @@ -3.23.x-117-g24f41bdc67 +3.24.2 diff --git a/FACT_VERSION b/FACT_VERSION index 2ac86b8890de7..0c62199f16ac1 100644 --- a/FACT_VERSION +++ b/FACT_VERSION @@ -1 +1 @@ -0.2.x +0.2.1 diff --git a/Makefile b/Makefile index 799959e64cc3c..63c4ad12659c8 100644 --- a/Makefile +++ b/Makefile @@ -491,7 +491,8 @@ main-build-nodeps: migrator \ sensor/admission-control \ sensor/kubernetes \ - sensor/upgrader + sensor/upgrader \ + compliance/virtualmachines/roxagent ifndef CI CGO_ENABLED=0 $(GOBUILD) roxctl endif diff --git a/README.md b/README.md index 6d647e0be8dde..fbae0276d6729 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ - [Deploying StackRox](#deploying-stackrox) - [Quick Installation using Helm](#quick-installation-using-helm) - [Manual Installation using Helm](#manual-installation-using-helm) + - [Installation using the Operator](#installation-using-the-operator) - [Installation via Scripts](#installation-via-scripts) - [Kubernetes Distributions (EKS, AKS, GKE)](#kubernetes-distributions-eks-aks-gke) - [OpenShift](#openshift) @@ -213,6 +214,11 @@ To further customize your Helm installation consult these documents: +### Installation using the Operator + +As of release 4.10 it's possible to [install StackRox using the operator](operator/install). +We encourage you to try this out and give us your feedback. + ### Installation via Scripts The `deploy` script will: diff --git a/SCANNER_VERSION b/SCANNER_VERSION index 0aede1756389d..8f5a39a048591 100644 --- a/SCANNER_VERSION +++ b/SCANNER_VERSION @@ -1 +1 @@ -2.38.x-24-gcd5fb7a6d1 +2.39.2 diff --git a/central/baseimage/matcher/matcher.go b/central/baseimage/matcher/matcher.go index a46315dd2e308..8f5bc09e3a104 100644 --- a/central/baseimage/matcher/matcher.go +++ b/central/baseimage/matcher/matcher.go @@ -8,5 +8,5 @@ import ( //go:generate mockgen-wrapper type Matcher interface { - MatchWithBaseImages(ctx context.Context, layers []string) ([]*storage.BaseImageInfo, error) + MatchWithBaseImages(ctx context.Context, layers []string) ([]*storage.BaseImage, error) } diff --git a/central/baseimage/matcher/matcher_impl.go b/central/baseimage/matcher/matcher_impl.go index 96a3f7a2032d9..9b43bc5482dea 100644 --- a/central/baseimage/matcher/matcher_impl.go +++ b/central/baseimage/matcher/matcher_impl.go @@ -28,7 +28,7 @@ func New( } } -func (m matcherImpl) MatchWithBaseImages(ctx context.Context, layers []string) ([]*storage.BaseImageInfo, error) { +func (m matcherImpl) MatchWithBaseImages(ctx context.Context, layers []string) ([]*storage.BaseImage, error) { start := time.Now() defer func() { @@ -45,15 +45,20 @@ func (m matcherImpl) MatchWithBaseImages(ctx context.Context, layers []string) ( if err != nil { return nil, fmt.Errorf("listing candidates for layer %s: %w", firstLayer, err) } - var baseImages []*storage.BaseImageInfo + var baseImages []*storage.BaseImage + maxLayers := 0 + for _, c := range candidates { candidateLayers := c.GetLayers() slices.SortFunc(candidateLayers, func(a, b *storage.BaseImageLayer) int { return int(a.GetIndex() - b.GetIndex()) }) + + // base images should always have less layers than a target image if len(layers) <= len(candidateLayers) { continue } + match := true for i, l := range candidateLayers { if layers[i] != l.GetLayerDigest() { @@ -63,13 +68,18 @@ func (m matcherImpl) MatchWithBaseImages(ctx context.Context, layers []string) ( } if match { - baseImages = append(baseImages, &storage.BaseImageInfo{ - BaseImageId: c.GetId(), - BaseImageFullName: fmt.Sprintf("%s:%s", c.GetRepository(), c.GetTag()), - BaseImageDigest: c.GetManifestDigest(), - Created: c.GetCreated(), - }) + n := len(candidateLayers) + + if n > maxLayers { + // Found a better (longer) match: reset the slice and update max + maxLayers = n + baseImages = []*storage.BaseImage{c} + } else if n == maxLayers { + // Found another match of the same (maximum) length + baseImages = append(baseImages, c) + } } } + return baseImages, nil } diff --git a/central/baseimage/matcher/matcher_impl_test.go b/central/baseimage/matcher/matcher_impl_test.go index f208c2bcfeef2..3cce996fdb865 100644 --- a/central/baseimage/matcher/matcher_impl_test.go +++ b/central/baseimage/matcher/matcher_impl_test.go @@ -27,7 +27,7 @@ func TestMatchWithBaseImages(t *testing.T) { desc string imgLayers []string mockSetup func() - expected []*storage.BaseImageInfo + expected []*storage.BaseImage }{ { desc: "Match found: Base image layers are returned out of order", @@ -49,12 +49,13 @@ func TestMatchWithBaseImages(t *testing.T) { }, }, nil) }, - expected: []*storage.BaseImageInfo{ + expected: []*storage.BaseImage{ { - BaseImageId: "base-1", - BaseImageFullName: "rhel:8", - BaseImageDigest: "sha-base", - Created: testCreatedTime, + Id: "base-1", + Repository: "rhel", + Tag: "8", + ManifestDigest: "sha-base", + Created: testCreatedTime, }, }, }, @@ -99,8 +100,8 @@ func TestMatchWithBaseImages(t *testing.T) { }, }, nil) }, - expected: []*storage.BaseImageInfo{ - {BaseImageId: "match"}, + expected: []*storage.BaseImage{ + {Id: "match"}, }, }, { @@ -120,6 +121,67 @@ func TestMatchWithBaseImages(t *testing.T) { }, nil) }, expected: nil, + }, { + desc: "Max layers only: Returns 3-layer match and ignores 2-layer match", + imgLayers: []string{"L1", "L2", "L3", "L4"}, + mockSetup: func() { + mockDS.EXPECT(). + ListCandidateBaseImages(gomock.Any(), "L1"). + Return([]*storage.BaseImage{ + { + Id: "short-match", // 2 layers + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "L1", Index: 0}, + {LayerDigest: "L2", Index: 1}, + }, + }, + { + Id: "long-match", // 3 layers - the winner + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "L1", Index: 0}, + {LayerDigest: "L2", Index: 1}, + {LayerDigest: "L3", Index: 2}, + }, + }, + }, nil) + }, + expected: []*storage.BaseImage{ + {Id: "long-match"}, + }, + }, + { + desc: "Max layers only: Returns multiple matches if they have same max length", + imgLayers: []string{"L1", "L2", "L3"}, + mockSetup: func() { + mockDS.EXPECT(). + ListCandidateBaseImages(gomock.Any(), "L1"). + Return([]*storage.BaseImage{ + { + Id: "match-A", + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "L1", Index: 0}, + {LayerDigest: "L2", Index: 1}, + }, + }, + { + Id: "match-B", + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "L1", Index: 0}, + {LayerDigest: "L2", Index: 1}, + }, + }, + { + Id: "too-short", + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "L1", Index: 0}, + }, + }, + }, nil) + }, + expected: []*storage.BaseImage{ + {Id: "match-A"}, + {Id: "match-B"}, + }, }, } @@ -134,9 +196,10 @@ func TestMatchWithBaseImages(t *testing.T) { } else { require.Equal(t, len(tc.expected), len(actual)) for i := range tc.expected { - assert.Equal(t, tc.expected[i].GetBaseImageId(), actual[i].GetBaseImageId()) - if tc.expected[i].GetBaseImageFullName() != "" { - assert.Equal(t, tc.expected[i].GetBaseImageFullName(), actual[i].GetBaseImageFullName()) + assert.Equal(t, tc.expected[i].GetId(), actual[i].GetId()) + if tc.expected[i].GetRepository() != "" { + assert.Equal(t, tc.expected[i].GetRepository(), actual[i].GetRepository()) + assert.Equal(t, tc.expected[i].GetTag(), actual[i].GetTag()) } if tc.expected[i].GetCreated() != nil { assert.Equal(t, tc.expected[i].GetCreated(), actual[i].GetCreated()) diff --git a/central/baseimage/matcher/mocks/matcher.go b/central/baseimage/matcher/mocks/matcher.go index fb015f20f03e7..567d6287b7d72 100644 --- a/central/baseimage/matcher/mocks/matcher.go +++ b/central/baseimage/matcher/mocks/matcher.go @@ -42,10 +42,10 @@ func (m *MockMatcher) EXPECT() *MockMatcherMockRecorder { } // MatchWithBaseImages mocks base method. -func (m *MockMatcher) MatchWithBaseImages(ctx context.Context, layers []string) ([]*storage.BaseImageInfo, error) { +func (m *MockMatcher) MatchWithBaseImages(ctx context.Context, layers []string) ([]*storage.BaseImage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MatchWithBaseImages", ctx, layers) - ret0, _ := ret[0].([]*storage.BaseImageInfo) + ret0, _ := ret[0].([]*storage.BaseImage) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/central/cve/converter/utils/convert_utils_v2.go b/central/cve/converter/utils/convert_utils_v2.go index fe6546ec72a99..4fe09a77b43d1 100644 --- a/central/cve/converter/utils/convert_utils_v2.go +++ b/central/cve/converter/utils/convert_utils_v2.go @@ -33,6 +33,7 @@ func ImageCVEV2ToEmbeddedVulnerability(vuln *storage.ImageCVEV2) *storage.Embedd VulnerabilityType: storage.EmbeddedVulnerability_IMAGE_VULNERABILITY, VulnerabilityTypes: []storage.EmbeddedVulnerability_VulnerabilityType{storage.EmbeddedVulnerability_IMAGE_VULNERABILITY}, State: vuln.GetState(), + Datasource: vuln.GetDatasource(), } if vuln.GetIsFixable() { @@ -105,6 +106,7 @@ func EmbeddedVulnerabilityToImageCVEV2(imageID string, componentID string, index IsFixable: from.GetFixedBy() != "", ImpactScore: impactScore, Advisory: from.GetAdvisory(), + Datasource: from.GetDatasource(), } if !features.FlattenImageData.Enabled() { ret.ImageId = imageID diff --git a/central/cve/converter/utils/convert_utils_v2_test.go b/central/cve/converter/utils/convert_utils_v2_test.go index 0bf10ac6b1f02..d37f78f1eb1ce 100644 --- a/central/cve/converter/utils/convert_utils_v2_test.go +++ b/central/cve/converter/utils/convert_utils_v2_test.go @@ -91,6 +91,7 @@ var ( EpssProbability: 22, EpssPercentile: 98, }, + Datasource: "test-ds", }, { Cve: "cve2", @@ -225,6 +226,7 @@ func getTestCVEs(t *testing.T) []*storage.ImageCVEV2 { IsFixable: false, HasFixedBy: nil, ComponentId: getTestComponentID(0), + Datasource: "test-ds", }, { Id: getTestCVEID(testVulns[1], getTestComponentID(1), 1), diff --git a/central/cve/image/info/datastore/datastore_impl.go b/central/cve/image/info/datastore/datastore_impl.go index 58c5c2fff5ec7..57a689bbd006f 100644 --- a/central/cve/image/info/datastore/datastore_impl.go +++ b/central/cve/image/info/datastore/datastore_impl.go @@ -8,10 +8,14 @@ import ( "github.com/stackrox/rox/generated/storage" "github.com/stackrox/rox/pkg/protocompat" "github.com/stackrox/rox/pkg/sliceutils" + "github.com/stackrox/rox/pkg/sync" ) type datastoreImpl struct { storage store.Store + // upsertLock serializes Upsert and UpsertMany to make the + // read-modify-write of timestamp merging atomic. + upsertLock sync.Mutex } func (ds *datastoreImpl) SearchRawImageCVEInfos(ctx context.Context, q *v1.Query) ([]*storage.ImageCVEInfo, error) { @@ -41,6 +45,9 @@ func (ds *datastoreImpl) GetBatch(ctx context.Context, ids []string) ([]*storage } func (ds *datastoreImpl) Upsert(ctx context.Context, info *storage.ImageCVEInfo) error { + ds.upsertLock.Lock() + defer ds.upsertLock.Unlock() + existing, found, err := ds.Get(ctx, info.GetId()) if err != nil { return err @@ -53,6 +60,9 @@ func (ds *datastoreImpl) Upsert(ctx context.Context, info *storage.ImageCVEInfo) } func (ds *datastoreImpl) UpsertMany(ctx context.Context, infos []*storage.ImageCVEInfo) error { + ds.upsertLock.Lock() + defer ds.upsertLock.Unlock() + // Create a list of ids to look up ids := sliceutils.Map[*storage.ImageCVEInfo, string](infos, func(info *storage.ImageCVEInfo) string { return info.GetId() @@ -66,7 +76,12 @@ func (ds *datastoreImpl) UpsertMany(ctx context.Context, infos []*storage.ImageC // Populate both maps separately - can't use index-based loop because // existing may not be in the same order as infos for _, info := range infos { - newInfoMap[info.GetId()] = info + if prev, ok := newInfoMap[info.GetId()]; ok { + // if there are are multiple infos with same id, earlier timestamps take precedence + newInfoMap[info.GetId()] = updateTimestamps(prev, info) + } else { + newInfoMap[info.GetId()] = info + } } for _, info := range existing { oldInfoMap[info.GetId()] = info diff --git a/central/cve/image/info/datastore/datastore_impl_test.go b/central/cve/image/info/datastore/datastore_impl_test.go index 26f163a0af891..877862cbfcfb8 100644 --- a/central/cve/image/info/datastore/datastore_impl_test.go +++ b/central/cve/image/info/datastore/datastore_impl_test.go @@ -44,6 +44,7 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpdateTimestamps_NilOld() { now := time.Now() newInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FirstSystemOccurrence: timestamppb.New(now), FixAvailableTimestamp: timestamppb.New(now), } @@ -62,10 +63,12 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpdateTimestamps_PreservesEarlierFirstS oldInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FirstSystemOccurrence: timestamppb.New(earlier), } newInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FirstSystemOccurrence: timestamppb.New(later), } @@ -82,10 +85,12 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpdateTimestamps_PreservesEarlierFixAva oldInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FixAvailableTimestamp: timestamppb.New(earlier), } newInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FixAvailableTimestamp: timestamppb.New(later), } @@ -101,10 +106,12 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpdateTimestamps_UsesNewWhenOldIsZero() oldInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FirstSystemOccurrence: nil, // Zero timestamp } newInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FirstSystemOccurrence: timestamppb.New(now), } @@ -120,10 +127,12 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpdateTimestamps_UsesOldWhenNewIsZero() oldInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FirstSystemOccurrence: timestamppb.New(earlier), } newInfo := &storage.ImageCVEInfo{ Id: "test-id", + Cve: "test-cve", FirstSystemOccurrence: nil, // Zero timestamp } @@ -141,6 +150,7 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpsert_PreservesTimestamps() { // First, insert an info with an earlier timestamp firstInfo := &storage.ImageCVEInfo{ Id: "test-cve#test-pkg#test-ds", + Cve: "test-cve", FirstSystemOccurrence: timestamppb.New(earlier), FixAvailableTimestamp: timestamppb.New(earlier), } @@ -150,6 +160,7 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpsert_PreservesTimestamps() { // Now upsert with a later timestamp secondInfo := &storage.ImageCVEInfo{ Id: "test-cve#test-pkg#test-ds", + Cve: "test-cve", FirstSystemOccurrence: timestamppb.New(later), FixAvailableTimestamp: timestamppb.New(later), } @@ -167,20 +178,30 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpsert_PreservesTimestamps() { // TestUpsertMany_PreservesTimestamps tests that UpsertMany preserves earlier timestamps. func (s *ImageCVEInfoDataStoreSuite) TestUpsertMany_PreservesTimestamps() { earlier := time.Now().Add(-24 * time.Hour) + earlier2 := time.Now().Add(-12 * time.Hour) later := time.Now() - // First, insert infos with earlier timestamps + // First, insert infos with earlier timestamps. + // If there are multiple infos with same id, earlier timestamps should be preserved. firstInfos := []*storage.ImageCVEInfo{ { Id: "test-cve-1#test-pkg#test-ds", + Cve: "test-cve-1", FirstSystemOccurrence: timestamppb.New(earlier), FixAvailableTimestamp: timestamppb.New(earlier), }, { Id: "test-cve-2#test-pkg#test-ds", + Cve: "test-cve-2", FirstSystemOccurrence: timestamppb.New(earlier), FixAvailableTimestamp: timestamppb.New(earlier), }, + { + Id: "test-cve-1#test-pkg#test-ds", + Cve: "test-cve-1", + FirstSystemOccurrence: nil, + FixAvailableTimestamp: timestamppb.New(earlier2), + }, } err := s.datastore.UpsertMany(s.ctx, firstInfos) s.NoError(err) @@ -189,11 +210,13 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpsertMany_PreservesTimestamps() { secondInfos := []*storage.ImageCVEInfo{ { Id: "test-cve-1#test-pkg#test-ds", + Cve: "test-cve-1", FirstSystemOccurrence: timestamppb.New(later), FixAvailableTimestamp: timestamppb.New(later), }, { Id: "test-cve-2#test-pkg#test-ds", + Cve: "test-cve-2", FirstSystemOccurrence: timestamppb.New(later), FixAvailableTimestamp: timestamppb.New(later), }, @@ -218,6 +241,7 @@ func (s *ImageCVEInfoDataStoreSuite) TestUpsert_NewInfo() { info := &storage.ImageCVEInfo{ Id: "new-cve#new-pkg#new-ds", + Cve: "new-cve", FirstSystemOccurrence: timestamppb.New(now), FixAvailableTimestamp: timestamppb.New(now), } diff --git a/central/cve/image/info/datastore/store/postgres/gen.go b/central/cve/image/info/datastore/store/postgres/gen.go index 22f5743e25a80..ee0dbb0186f58 100644 --- a/central/cve/image/info/datastore/store/postgres/gen.go +++ b/central/cve/image/info/datastore/store/postgres/gen.go @@ -1,3 +1,3 @@ package postgres -//go:generate pg-table-bindings-wrapper --type=storage.ImageCVEInfo --cached-store +//go:generate pg-table-bindings-wrapper --type=storage.ImageCVEInfo --cached-store --no-copy-from diff --git a/central/cve/image/info/datastore/store/postgres/store.go b/central/cve/image/info/datastore/store/postgres/store.go index 1eb0c84aa1029..c9d62a93a4de7 100644 --- a/central/cve/image/info/datastore/store/postgres/store.go +++ b/central/cve/image/info/datastore/store/postgres/store.go @@ -68,7 +68,7 @@ func New(db postgres.DB) Store { schema, pkGetter, insertIntoImageCveInfos, - copyFromImageCveInfos, + nil, metricsSetAcquireDBConnDuration, metricsSetPostgresOperationDurationTime, metricsSetCacheOperationDurationTime, @@ -108,65 +108,14 @@ func insertIntoImageCveInfos(batch *pgx.Batch, obj *storage.ImageCVEInfo) error obj.GetId(), protocompat.NilOrTime(obj.GetFixAvailableTimestamp()), protocompat.NilOrTime(obj.GetFirstSystemOccurrence()), + obj.GetCve(), serialized, } - finalStr := "INSERT INTO image_cve_infos (Id, FixAvailableTimestamp, FirstSystemOccurrence, serialized) VALUES($1, $2, $3, $4) ON CONFLICT(Id) DO UPDATE SET Id = EXCLUDED.Id, FixAvailableTimestamp = EXCLUDED.FixAvailableTimestamp, FirstSystemOccurrence = EXCLUDED.FirstSystemOccurrence, serialized = EXCLUDED.serialized" + finalStr := "INSERT INTO image_cve_infos (Id, FixAvailableTimestamp, FirstSystemOccurrence, Cve, serialized) VALUES($1, $2, $3, $4, $5) ON CONFLICT(Id) DO UPDATE SET Id = EXCLUDED.Id, FixAvailableTimestamp = EXCLUDED.FixAvailableTimestamp, FirstSystemOccurrence = EXCLUDED.FirstSystemOccurrence, Cve = EXCLUDED.Cve, serialized = EXCLUDED.serialized" batch.Queue(finalStr, values...) return nil } -var copyColsImageCveInfos = []string{ - "id", - "fixavailabletimestamp", - "firstsystemoccurrence", - "serialized", -} - -func copyFromImageCveInfos(ctx context.Context, s pgSearch.Deleter, tx *postgres.Tx, objs ...*storage.ImageCVEInfo) error { - if len(objs) == 0 { - return nil - } - - { - // CopyFrom does not upsert, so delete existing rows first to achieve upsert behavior. - // Parent deletion cascades to children, so only the top-level parent needs deletion. - deletes := make([]string, 0, len(objs)) - for _, obj := range objs { - deletes = append(deletes, obj.GetId()) - } - if err := s.DeleteMany(ctx, deletes); err != nil { - return err - } - } - - idx := 0 - inputRows := pgx.CopyFromFunc(func() ([]any, error) { - if idx >= len(objs) { - return nil, nil - } - obj := objs[idx] - idx++ - - serialized, marshalErr := obj.MarshalVT() - if marshalErr != nil { - return nil, marshalErr - } - - return []interface{}{ - obj.GetId(), - protocompat.NilOrTime(obj.GetFixAvailableTimestamp()), - protocompat.NilOrTime(obj.GetFirstSystemOccurrence()), - serialized, - }, nil - }) - - if _, err := tx.CopyFrom(ctx, pgx.Identifier{"image_cve_infos"}, copyColsImageCveInfos, inputRows); err != nil { - return err - } - - return nil -} - // endregion Helper functions diff --git a/central/cve/image/info/enricher/enricher.go b/central/cve/image/info/enricher/enricher.go new file mode 100644 index 0000000000000..d4d9220220585 --- /dev/null +++ b/central/cve/image/info/enricher/enricher.go @@ -0,0 +1,139 @@ +package enricher + +import ( + "context" + + imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" + "github.com/stackrox/rox/generated/storage" + "github.com/stackrox/rox/pkg/cve" + "github.com/stackrox/rox/pkg/features" + imageEnricher "github.com/stackrox/rox/pkg/images/enricher" + "github.com/stackrox/rox/pkg/protocompat" + "github.com/stackrox/rox/pkg/sac" +) + +type enricherImpl struct { + imageCVEInfoDS imageCVEInfoDS.DataStore +} + +// New creates a new CVEInfoEnricher. +func New(imageCVEInfoDS imageCVEInfoDS.DataStore) imageEnricher.CVEInfoEnricher { + return &enricherImpl{ + imageCVEInfoDS: imageCVEInfoDS, + } +} + +// EnrichImageWithCVEInfo enriches a V1 image's CVEs with timing metadata. +func (e *enricherImpl) EnrichImageWithCVEInfo(ctx context.Context, image *storage.Image) error { + if !features.CVEFixTimestampCriteria.Enabled() { + return nil + } + + scan := image.GetScan() + if scan == nil { + return nil + } + + // Populate the ImageCVEInfo table with CVE timing metadata + if err := e.upsertImageCVEInfos(ctx, scan); err != nil { + return err + } + + // Enrich the CVEs with accurate timestamps from lookup table + return e.enrichCVEsFromImageCVEInfo(ctx, scan) +} + +// EnrichImageV2WithCVEInfo enriches a V2 image's CVEs with timing metadata. +func (e *enricherImpl) EnrichImageV2WithCVEInfo(ctx context.Context, image *storage.ImageV2) error { + if !features.CVEFixTimestampCriteria.Enabled() { + return nil + } + + scan := image.GetScan() + if scan == nil { + return nil + } + + // Populate the ImageCVEInfo table with CVE timing metadata + if err := e.upsertImageCVEInfos(ctx, scan); err != nil { + return err + } + + // Enrich the CVEs with accurate timestamps from lookup table + return e.enrichCVEsFromImageCVEInfo(ctx, scan) +} + +// upsertImageCVEInfos populates the ImageCVEInfo lookup table with CVE timing metadata. +func (e *enricherImpl) upsertImageCVEInfos(ctx context.Context, scan *storage.ImageScan) error { + infos := make([]*storage.ImageCVEInfo, 0) + now := protocompat.TimestampNow() + + for _, component := range scan.GetComponents() { + for _, vuln := range component.GetVulns() { + // Determine fix available timestamp: use scanner-provided value if available, + // otherwise fabricate from scan time if the CVE is fixable (has a fix version). + // This handles non-Red Hat data sources that don't provide fix timestamps. + fixAvailableTimestamp := vuln.GetFixAvailableTimestamp() + if fixAvailableTimestamp == nil && vuln.GetFixedBy() != "" { + fixAvailableTimestamp = now + } + + info := &storage.ImageCVEInfo{ + Id: cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource()), + Cve: vuln.GetCve(), + FixAvailableTimestamp: fixAvailableTimestamp, + FirstSystemOccurrence: now, // Smart upsert in ImageCVEInfo datastore preserves existing + } + infos = append(infos, info) + } + } + + if len(infos) == 0 { + return nil + } + + return e.imageCVEInfoDS.UpsertMany(sac.WithAllAccess(ctx), infos) +} + +// enrichCVEsFromImageCVEInfo enriches the image's CVEs with accurate timestamps from the lookup table. +func (e *enricherImpl) enrichCVEsFromImageCVEInfo(ctx context.Context, scan *storage.ImageScan) error { + // Collect all IDs + ids := make([]string, 0) + for _, component := range scan.GetComponents() { + for _, vuln := range component.GetVulns() { + ids = append(ids, cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource())) + } + } + + if len(ids) == 0 { + return nil + } + + // Batch fetch + infos, err := e.imageCVEInfoDS.GetBatch(sac.WithAllAccess(ctx), ids) + if err != nil { + return err + } + + // Build lookup map + infoMap := make(map[string]*storage.ImageCVEInfo) + for _, info := range infos { + infoMap[info.GetId()] = info + } + + // Enrich CVEs + for _, component := range scan.GetComponents() { + for _, vuln := range component.GetVulns() { + id := cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource()) + if info, ok := infoMap[id]; ok { + if vuln.GetFixAvailableTimestamp() == nil && vuln.GetFixedBy() != "" { + // Set the fix timestamp if it was not provided by the scanner + vuln.FixAvailableTimestamp = info.GetFixAvailableTimestamp() + } + vuln.FirstSystemOccurrence = info.GetFirstSystemOccurrence() + } + } + } + + return nil +} diff --git a/central/cve/image/info/enricher/singleton.go b/central/cve/image/info/enricher/singleton.go new file mode 100644 index 0000000000000..ba5b452e54968 --- /dev/null +++ b/central/cve/image/info/enricher/singleton.go @@ -0,0 +1,23 @@ +package enricher + +import ( + imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" + imageEnricher "github.com/stackrox/rox/pkg/images/enricher" + "github.com/stackrox/rox/pkg/sync" +) + +var ( + once sync.Once + + instance imageEnricher.CVEInfoEnricher +) + +func initialize() { + instance = New(imageCVEInfoDS.Singleton()) +} + +// Singleton returns a singleton instance of CVEInfoEnricher. +func Singleton() imageEnricher.CVEInfoEnricher { + once.Do(initialize) + return instance +} diff --git a/central/enrichment/singleton.go b/central/enrichment/singleton.go index cb28eb5b95aca..ba236d20af19c 100644 --- a/central/enrichment/singleton.go +++ b/central/enrichment/singleton.go @@ -7,6 +7,7 @@ import ( baseImageMatcher "github.com/stackrox/rox/central/baseimage/matcher" clusterDataStore "github.com/stackrox/rox/central/cluster/datastore" "github.com/stackrox/rox/central/cve/fetcher" + cveInfoEnricher "github.com/stackrox/rox/central/cve/image/info/enricher" nodeCVEDataStore "github.com/stackrox/rox/central/cve/node/datastore" delegatedRegistryConfigDS "github.com/stackrox/rox/central/delegatedregistryconfig/datastore" "github.com/stackrox/rox/central/delegatedregistryconfig/delegator" @@ -59,11 +60,11 @@ func initialize() { ) if !features.FlattenImageData.Enabled() { - imgEnricher = imageEnricher.New(suppressor.Singleton(), imageintegration.Set(), + imgEnricher = imageEnricher.New(suppressor.Singleton(), cveInfoEnricher.Singleton(), imageintegration.Set(), metrics.CentralSubsystem, cache.ImageMetadataCacheSingleton(), baseImageMatcher.Singleton().MatchWithBaseImages, datastore.Singleton().GetImage, reporter.Singleton(), signatureIntegrationDataStore.Singleton().GetAllSignatureIntegrations, scanDelegator) } else { - imgEnricherV2 = imageEnricher.NewV2(suppressor.Singleton(), imageintegration.Set(), + imgEnricherV2 = imageEnricher.NewV2(suppressor.Singleton(), cveInfoEnricher.Singleton(), imageintegration.Set(), metrics.CentralSubsystem, cache.ImageMetadataCacheSingleton(), baseImageMatcher.Singleton().MatchWithBaseImages, imageV2DataStore.Singleton().GetImage, reporter.Singleton(), signatureIntegrationDataStore.Singleton().GetAllSignatureIntegrations, scanDelegator) } diff --git a/central/graphdb/testutils/datastore.go b/central/graphdb/testutils/datastore.go index 64a757be049b7..fda32e355feb0 100644 --- a/central/graphdb/testutils/datastore.go +++ b/central/graphdb/testutils/datastore.go @@ -7,7 +7,6 @@ import ( clusterDataStore "github.com/stackrox/rox/central/cluster/datastore" clusterCVEDataStore "github.com/stackrox/rox/central/cve/cluster/datastore" cveConverterV2 "github.com/stackrox/rox/central/cve/converter/v2" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" deploymentDataStore "github.com/stackrox/rox/central/deployment/datastore" imageDataStore "github.com/stackrox/rox/central/image/datastore" imagePostgresV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" @@ -308,13 +307,11 @@ func NewTestGraphDataStore(t *testing.T) (TestGraphDataStore, error) { s.pgtestbase = pgtest.ForT(t) s.nodeStore = nodeDataStore.GetTestPostgresDataStore(t, s.GetPostgresPool()) - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(t, s.GetPostgresPool()) s.imageStore = imageDataStore.NewWithPostgres( imagePostgresV2.New(s.GetPostgresPool(), false, concurrency.NewKeyFence()), riskDS.GetTestPostgresDataStore(t, s.GetPostgresPool()), ranking.NewRanker(), ranking.NewRanker(), - imageCVEInfo, ) s.deploymentStore, err = deploymentDataStore.GetTestPostgresDataStore(t, s.GetPostgresPool()) if err != nil { diff --git a/central/graphql/resolvers/image_components_v2_postgres_test.go b/central/graphql/resolvers/image_components_v2_postgres_test.go index d31eab72f83f2..2fde535cf68a9 100644 --- a/central/graphql/resolvers/image_components_v2_postgres_test.go +++ b/central/graphql/resolvers/image_components_v2_postgres_test.go @@ -128,7 +128,7 @@ func (s *GraphQLImageComponentV2TestSuite) TestImageComponents() { } inBaseImageLayerMap := map[string]bool{ s.componentIDMap[comp11]: false, - s.componentIDMap[comp12]: true, + s.componentIDMap[comp12]: false, // comp1 on image2 has no LayerIndex, so we can't determine origin s.componentIDMap[comp21]: false, s.componentIDMap[comp31]: false, s.componentIDMap[comp32]: true, diff --git a/central/graphql/resolvers/test_setup_utils.go b/central/graphql/resolvers/test_setup_utils.go index 33c9b980f1acc..56b485481dd8c 100644 --- a/central/graphql/resolvers/test_setup_utils.go +++ b/central/graphql/resolvers/test_setup_utils.go @@ -12,7 +12,6 @@ import ( clusterCVEEdgePostgres "github.com/stackrox/rox/central/clustercveedge/datastore/store/postgres" clusterCVEDataStore "github.com/stackrox/rox/central/cve/cluster/datastore" clusterCVEPostgres "github.com/stackrox/rox/central/cve/cluster/datastore/store/postgres" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" imageCVEV2DS "github.com/stackrox/rox/central/cve/image/v2/datastore" imageCVEV2Postgres "github.com/stackrox/rox/central/cve/image/v2/datastore/store/postgres" nodeCVEDataStore "github.com/stackrox/rox/central/cve/node/datastore" @@ -142,7 +141,7 @@ func SetupTestResolver(t testing.TB, datastores ...interface{}) (*Resolver, *gra } // CreateTestImageV2Datastore creates image datastore for testing -func CreateTestImageV2Datastore(t testing.TB, testDB *pgtest.TestPostgres, ctrl *gomock.Controller) imageDS.DataStore { +func CreateTestImageV2Datastore(_ testing.TB, testDB *pgtest.TestPostgres, ctrl *gomock.Controller) imageDS.DataStore { risks := mockRisks.NewMockDataStore(ctrl) risks.EXPECT().RemoveRisk(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() return imageDS.NewWithPostgres( @@ -150,12 +149,11 @@ func CreateTestImageV2Datastore(t testing.TB, testDB *pgtest.TestPostgres, ctrl risks, ranking.NewRanker(), ranking.NewRanker(), - imageCVEInfoDS.GetTestPostgresDataStore(t, testDB.DB), ) } // CreateTestImageV2V2Datastore creates image datastore for testing -func CreateTestImageV2V2Datastore(t testing.TB, testDB *pgtest.TestPostgres, ctrl *gomock.Controller) imageV2DS.DataStore { +func CreateTestImageV2V2Datastore(_ testing.TB, testDB *pgtest.TestPostgres, ctrl *gomock.Controller) imageV2DS.DataStore { risks := mockRisks.NewMockDataStore(ctrl) risks.EXPECT().RemoveRisk(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() return imageV2DS.NewWithPostgres( @@ -163,7 +161,6 @@ func CreateTestImageV2V2Datastore(t testing.TB, testDB *pgtest.TestPostgres, ctr risks, ranking.NewRanker(), ranking.NewRanker(), - imageCVEInfoDS.GetTestPostgresDataStore(t, testDB.DB), ) } diff --git a/central/graphql/resolvers/test_utils.go b/central/graphql/resolvers/test_utils.go index d8ffb0e60db62..08ecb07643efa 100644 --- a/central/graphql/resolvers/test_utils.go +++ b/central/graphql/resolvers/test_utils.go @@ -238,12 +238,14 @@ func testImages() []*storage.Image { BaseImageFullName: "busybox:latest", BaseImageDigest: "sha256:alpine312", Created: t3, + MaxLayerIndex: 10, }, { BaseImageId: "base-sha3", BaseImageFullName: "alpine:3.12", BaseImageDigest: "sha256:busybox1", Created: t3, + MaxLayerIndex: 10, }, }, }, diff --git a/central/image/datastore/datastore.go b/central/image/datastore/datastore.go index f16ac3d335117..5d4fee9f0987e 100644 --- a/central/image/datastore/datastore.go +++ b/central/image/datastore/datastore.go @@ -3,7 +3,6 @@ package datastore import ( "context" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/image/datastore/store" "github.com/stackrox/rox/central/ranking" riskDS "github.com/stackrox/rox/central/risk/datastore" @@ -41,8 +40,8 @@ type DataStore interface { // NewWithPostgres returns a new instance of DataStore using the input store, and searcher. // noUpdateTimestamps controls whether timestamps are automatically updated when upserting images. // This should be set to `false` except for some tests. -func NewWithPostgres(storage store.Store, risks riskDS.DataStore, imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker, imageCVEInfo imageCVEInfoDS.DataStore) DataStore { - ds := newDatastoreImpl(storage, risks, imageRanker, imageComponentRanker, imageCVEInfo) +func NewWithPostgres(storage store.Store, risks riskDS.DataStore, imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker) DataStore { + ds := newDatastoreImpl(storage, risks, imageRanker, imageComponentRanker) go ds.initializeRankers() return ds } diff --git a/central/image/datastore/datastore_bench_postgres_test.go b/central/image/datastore/datastore_bench_postgres_test.go index e6019176f342f..123dfb8c5337c 100644 --- a/central/image/datastore/datastore_bench_postgres_test.go +++ b/central/image/datastore/datastore_bench_postgres_test.go @@ -9,7 +9,6 @@ import ( "fmt" "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/image/datastore/keyfence" pgStoreV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" "github.com/stackrox/rox/central/ranking" @@ -30,8 +29,7 @@ func BenchmarkImageGetMany(b *testing.B) { db := testDB.DB mockRisk := mockRisks.NewMockDataStore(gomock.NewController(b)) - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(b, db) - datastore := NewWithPostgres(pgStoreV2.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker(), imageCVEInfo) + datastore := NewWithPostgres(pgStoreV2.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker()) ids := make([]string, 0, 100) images := make([]*storage.Image, 0, 100) @@ -70,8 +68,7 @@ func BenchmarkImageUpsert(b *testing.B) { db := testDB.DB mockRisk := mockRisks.NewMockDataStore(gomock.NewController(b)) - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(b, db) - datastore := NewWithPostgres(pgStoreV2.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker(), imageCVEInfo) + datastore := NewWithPostgres(pgStoreV2.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker()) images := make([]*storage.Image, 0, 100) for i := 0; i < 100; i++ { diff --git a/central/image/datastore/datastore_impl.go b/central/image/datastore/datastore_impl.go index d861084214664..7bf178ff7f2c7 100644 --- a/central/image/datastore/datastore_impl.go +++ b/central/image/datastore/datastore_impl.go @@ -6,7 +6,6 @@ import ( "time" "github.com/pkg/errors" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/globaldb" "github.com/stackrox/rox/central/image/datastore/store" "github.com/stackrox/rox/central/image/views" @@ -16,13 +15,10 @@ import ( v1 "github.com/stackrox/rox/generated/api/v1" "github.com/stackrox/rox/generated/storage" "github.com/stackrox/rox/pkg/concurrency" - "github.com/stackrox/rox/pkg/cve" "github.com/stackrox/rox/pkg/errorhelpers" - "github.com/stackrox/rox/pkg/features" "github.com/stackrox/rox/pkg/images/enricher" imageTypes "github.com/stackrox/rox/pkg/images/types" "github.com/stackrox/rox/pkg/logging" - "github.com/stackrox/rox/pkg/protocompat" "github.com/stackrox/rox/pkg/sac" "github.com/stackrox/rox/pkg/sac/resources" "github.com/stackrox/rox/pkg/scancomponent" @@ -44,13 +40,10 @@ type datastoreImpl struct { imageRanker *ranking.Ranker imageComponentRanker *ranking.Ranker - - imageCVEInfoDS imageCVEInfoDS.DataStore } func newDatastoreImpl(storage store.Store, risks riskDS.DataStore, - imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker, - imageCVEInfo imageCVEInfoDS.DataStore) *datastoreImpl { + imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker) *datastoreImpl { ds := &datastoreImpl{ storage: storage, @@ -59,8 +52,6 @@ func newDatastoreImpl(storage store.Store, risks riskDS.DataStore, imageRanker: imageRanker, imageComponentRanker: imageComponentRanker, - imageCVEInfoDS: imageCVEInfo, - keyedMutex: concurrency.NewKeyedMutex(globaldb.DefaultDataStorePoolSize), } return ds @@ -274,20 +265,6 @@ func (ds *datastoreImpl) UpsertImage(ctx context.Context, image *storage.Image) ds.keyedMutex.Lock(image.GetId()) defer ds.keyedMutex.Unlock(image.GetId()) - if features.CVEFixTimestampCriteria.Enabled() { - // Populate the ImageCVEInfo table with CVE timing metadata - if err := ds.upsertImageCVEInfos(ctx, image); err != nil { - log.Warnf("Failed to upsert ImageCVEInfo: %v", err) - // Non-fatal, continue with image upsert - } - - // Enrich the CVEs with accurate timestamps from lookup table - if err := ds.enrichCVEsFromImageCVEInfo(ctx, image); err != nil { - log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) - // Non-fatal, continue with image upsert - } - } - ds.updateComponentRisk(image) enricher.FillScanStats(image) @@ -393,83 +370,6 @@ func (ds *datastoreImpl) updateComponentRisk(image *storage.Image) { } } -// upsertImageCVEInfos populates the ImageCVEInfo lookup table with CVE timing metadata. -func (ds *datastoreImpl) upsertImageCVEInfos(ctx context.Context, image *storage.Image) error { - if !features.CVEFixTimestampCriteria.Enabled() { - return nil - } - - infos := make([]*storage.ImageCVEInfo, 0) - now := protocompat.TimestampNow() - - for _, component := range image.GetScan().GetComponents() { - for _, vuln := range component.GetVulns() { - // Determine fix available timestamp: use scanner-provided value if available, - // otherwise fabricate from scan time if the CVE is fixable (has a fix version). - // This handles non-Red Hat data sources that don't provide fix timestamps. - fixAvailableTimestamp := vuln.GetFixAvailableTimestamp() - if fixAvailableTimestamp == nil && vuln.GetFixedBy() != "" { - fixAvailableTimestamp = now - } - - info := &storage.ImageCVEInfo{ - Id: cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource()), - FixAvailableTimestamp: fixAvailableTimestamp, - FirstSystemOccurrence: now, // Smart upsert in ImageCVEInfo datastore preserves existing - } - infos = append(infos, info) - } - } - - return ds.imageCVEInfoDS.UpsertMany(ctx, infos) -} - -// enrichCVEsFromImageCVEInfo enriches the image's CVEs with accurate timestamps from the lookup table. -func (ds *datastoreImpl) enrichCVEsFromImageCVEInfo(ctx context.Context, image *storage.Image) error { - if !features.CVEFixTimestampCriteria.Enabled() { - return nil - } - - // Collect all IDs - ids := make([]string, 0) - for _, component := range image.GetScan().GetComponents() { - for _, vuln := range component.GetVulns() { - ids = append(ids, cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource())) - } - } - - if len(ids) == 0 { - return nil - } - - // Batch fetch - infos, err := ds.imageCVEInfoDS.GetBatch(ctx, ids) - if err != nil { - return err - } - - // Build lookup map - infoMap := make(map[string]*storage.ImageCVEInfo) - for _, info := range infos { - infoMap[info.GetId()] = info - } - - // Enrich CVEs and blank out datasource after using it - for _, component := range image.GetScan().GetComponents() { - for _, vuln := range component.GetVulns() { - id := cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource()) - if info, ok := infoMap[id]; ok { - vuln.FixAvailableTimestamp = info.GetFixAvailableTimestamp() - vuln.FirstSystemOccurrence = info.GetFirstSystemOccurrence() - } - // Blank out datasource after using it - this is internal scanner data not meant for end users - vuln.Datasource = "" - } - } - - return nil -} - // ImageSearchResultConverter converts image search results to proto search results type ImageSearchResultConverter struct{} diff --git a/central/image/datastore/datastore_impl_flat_postgres_test.go b/central/image/datastore/datastore_impl_flat_postgres_test.go index 7d14fc7fd2135..adb8d6d52eaf4 100644 --- a/central/image/datastore/datastore_impl_flat_postgres_test.go +++ b/central/image/datastore/datastore_impl_flat_postgres_test.go @@ -8,7 +8,6 @@ import ( "sort" "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" imageCVEDS "github.com/stackrox/rox/central/cve/image/v2/datastore" imageCVEPostgres "github.com/stackrox/rox/central/cve/image/v2/datastore/store/postgres" "github.com/stackrox/rox/central/image/datastore/keyfence" @@ -45,14 +44,13 @@ func TestImageFlatDataStoreWithPostgres(t *testing.T) { type ImageFlatPostgresDataStoreTestSuite struct { suite.Suite - ctx context.Context - testDB *pgtest.TestPostgres - db postgres.DB - datastore DataStore - mockRisk *mockRisks.MockDataStore - componentDataStore imageComponentDS.DataStore - cveDataStore imageCVEDS.DataStore - imageCVEInfoDatastore imageCVEInfoDS.DataStore + ctx context.Context + testDB *pgtest.TestPostgres + db postgres.DB + datastore DataStore + mockRisk *mockRisks.MockDataStore + componentDataStore imageComponentDS.DataStore + cveDataStore imageCVEDS.DataStore } func (s *ImageFlatPostgresDataStoreTestSuite) SetupSuite() { @@ -63,9 +61,8 @@ func (s *ImageFlatPostgresDataStoreTestSuite) SetupSuite() { func (s *ImageFlatPostgresDataStoreTestSuite) SetupTest() { s.mockRisk = mockRisks.NewMockDataStore(gomock.NewController(s.T())) - s.imageCVEInfoDatastore = imageCVEInfoDS.GetTestPostgresDataStore(s.T(), s.db) dbStore := pgStoreV2.New(s.db, false, keyfence.ImageKeyFenceSingleton()) - s.datastore = NewWithPostgres(dbStore, s.mockRisk, ranking.ImageRanker(), ranking.ComponentRanker(), s.imageCVEInfoDatastore) + s.datastore = NewWithPostgres(dbStore, s.mockRisk, ranking.ImageRanker(), ranking.ComponentRanker()) componentStorage := imageComponentPostgres.New(s.db) s.componentDataStore = imageComponentDS.New(componentStorage, s.mockRisk, ranking.NewRanker()) @@ -639,201 +636,3 @@ func cloneAndUpdateRiskPriority(image *storage.Image) *storage.Image { cloned.LastUpdated = image.GetLastUpdated() return cloned } - -// TestImageCVEInfoIntegration tests the ImageCVEInfo lookup table integration -func (s *ImageFlatPostgresDataStoreTestSuite) TestImageCVEInfoIntegration_PopulatesTable() { - // Enable the feature flag - s.T().Setenv("ROX_CVE_FIX_TIMESTAMP", "true") - - ctx := sac.WithGlobalAccessScopeChecker(context.Background(), sac.AllowFixedScopes( - sac.AccessModeScopeKeys(storage.Access_READ_ACCESS, storage.Access_READ_WRITE_ACCESS), - sac.ResourceScopeKeys(resources.Image), - )) - - // Create an image with CVEs that have fix timestamps - fixTime := protocompat.TimestampNow() - image := &storage.Image{ - Id: "test-image-cve-info", - Name: &storage.ImageName{ - FullName: "test/image:tag", - }, - Scan: &storage.ImageScan{ - OperatingSystem: "debian", - ScanTime: protocompat.TimestampNow(), - Components: []*storage.EmbeddedImageScanComponent{ - { - Name: "openssl", - Version: "1.1.1", - Vulns: []*storage.EmbeddedVulnerability{ - { - Cve: "CVE-2021-1234", - VulnerabilityType: storage.EmbeddedVulnerability_IMAGE_VULNERABILITY, - Datasource: "debian-bookworm-updater::debian:12", - FixAvailableTimestamp: fixTime, - }, - }, - }, - }, - }, - } - - // Upsert the image - s.NoError(s.datastore.UpsertImage(ctx, image)) - - // Verify ImageCVEInfo was populated - expectedID := pkgCVE.ImageCVEInfoID("CVE-2021-1234", "openssl", "debian-bookworm-updater::debian:12") - info, found, err := s.imageCVEInfoDatastore.Get(ctx, expectedID) - s.NoError(err) - s.True(found, "ImageCVEInfo should be populated after image upsert") - s.NotNil(info.GetFirstSystemOccurrence(), "FirstSystemOccurrence should be set") - s.Equal(fixTime.GetSeconds(), info.GetFixAvailableTimestamp().GetSeconds(), "FixAvailableTimestamp should match") -} - -func (s *ImageFlatPostgresDataStoreTestSuite) TestImageCVEInfoIntegration_EnrichesFromLookupTable() { - // Enable the feature flag - s.T().Setenv("ROX_CVE_FIX_TIMESTAMP", "true") - - ctx := sac.WithGlobalAccessScopeChecker(context.Background(), sac.AllowFixedScopes( - sac.AccessModeScopeKeys(storage.Access_READ_ACCESS, storage.Access_READ_WRITE_ACCESS), - sac.ResourceScopeKeys(resources.Image), - )) - - // Pre-populate ImageCVEInfo with known timestamps - earlierTime := protocompat.TimestampNow() - earlierTime.Seconds -= 86400 // 1 day ago - - preExistingInfo := &storage.ImageCVEInfo{ - Id: pkgCVE.ImageCVEInfoID("CVE-2021-5678", "curl", "debian-updater::debian:11"), - FixAvailableTimestamp: earlierTime, - FirstSystemOccurrence: earlierTime, - } - s.NoError(s.imageCVEInfoDatastore.Upsert(ctx, preExistingInfo)) - - // Create an image with a CVE that matches the pre-existing info - image := &storage.Image{ - Id: "test-image-enrich", - Name: &storage.ImageName{ - FullName: "test/enrich:tag", - }, - Scan: &storage.ImageScan{ - OperatingSystem: "debian", - ScanTime: protocompat.TimestampNow(), - Components: []*storage.EmbeddedImageScanComponent{ - { - Name: "curl", - Version: "7.68.0", - Vulns: []*storage.EmbeddedVulnerability{ - { - Cve: "CVE-2021-5678", - VulnerabilityType: storage.EmbeddedVulnerability_IMAGE_VULNERABILITY, - Datasource: "debian-updater::debian:11", - // No fix timestamp set - should be enriched from lookup - }, - }, - }, - }, - }, - } - - // Upsert the image - s.NoError(s.datastore.UpsertImage(ctx, image)) - - // Retrieve the image and verify CVE was enriched - storedImage, found, err := s.datastore.GetImage(ctx, image.GetId()) - s.NoError(err) - s.True(found) - - // Check that the CVE was enriched with timestamps from the lookup table - vuln := storedImage.GetScan().GetComponents()[0].GetVulns()[0] - s.NotNil(vuln.GetFirstSystemOccurrence(), "FirstSystemOccurrence should be enriched") - s.Equal(earlierTime.GetSeconds(), vuln.GetFirstSystemOccurrence().GetSeconds(), "FirstSystemOccurrence should match pre-existing value") -} - -func (s *ImageFlatPostgresDataStoreTestSuite) TestImageCVEInfoIntegration_PreservesEarlierTimestamps() { - // Enable the feature flag - s.T().Setenv("ROX_CVE_FIX_TIMESTAMP", "true") - - ctx := sac.WithGlobalAccessScopeChecker(context.Background(), sac.AllowFixedScopes( - sac.AccessModeScopeKeys(storage.Access_READ_ACCESS, storage.Access_READ_WRITE_ACCESS), - sac.ResourceScopeKeys(resources.Image), - )) - - // First image upsert - establishes initial timestamps - firstFixTime := protocompat.TimestampNow() - firstFixTime.Seconds -= 86400 // 1 day ago - - image1 := &storage.Image{ - Id: "test-image-preserve-1", - Name: &storage.ImageName{ - FullName: "test/preserve:v1", - }, - Scan: &storage.ImageScan{ - OperatingSystem: "alpine", - ScanTime: protocompat.TimestampNow(), - Components: []*storage.EmbeddedImageScanComponent{ - { - Name: "busybox", - Version: "1.33.0", - Vulns: []*storage.EmbeddedVulnerability{ - { - Cve: "CVE-2021-9999", - VulnerabilityType: storage.EmbeddedVulnerability_IMAGE_VULNERABILITY, - Datasource: "alpine-updater::alpine:3.14", - FixAvailableTimestamp: firstFixTime, - }, - }, - }, - }, - }, - } - s.NoError(s.datastore.UpsertImage(ctx, image1)) - - // Get the first system occurrence time - infoID := pkgCVE.ImageCVEInfoID("CVE-2021-9999", "busybox", "alpine-updater::alpine:3.14") - info1, found, err := s.imageCVEInfoDatastore.Get(ctx, infoID) - s.NoError(err) - s.True(found) - firstOccurrence := info1.GetFirstSystemOccurrence() - - // Second image upsert with a later fix timestamp - should preserve earlier timestamps - laterFixTime := protocompat.TimestampNow() - - image2 := &storage.Image{ - Id: "test-image-preserve-2", - Name: &storage.ImageName{ - FullName: "test/preserve:v2", - }, - Scan: &storage.ImageScan{ - OperatingSystem: "alpine", - ScanTime: protocompat.TimestampNow(), - Components: []*storage.EmbeddedImageScanComponent{ - { - Name: "busybox", - Version: "1.33.1", - Vulns: []*storage.EmbeddedVulnerability{ - { - Cve: "CVE-2021-9999", - VulnerabilityType: storage.EmbeddedVulnerability_IMAGE_VULNERABILITY, - Datasource: "alpine-updater::alpine:3.14", - FixAvailableTimestamp: laterFixTime, // Later timestamp - }, - }, - }, - }, - }, - } - s.NoError(s.datastore.UpsertImage(ctx, image2)) - - // Verify earlier timestamps are preserved - info2, found, err := s.imageCVEInfoDatastore.Get(ctx, infoID) - s.NoError(err) - s.True(found) - - // FirstSystemOccurrence should remain the same (earlier value preserved) - s.Equal(firstOccurrence.GetSeconds(), info2.GetFirstSystemOccurrence().GetSeconds(), - "FirstSystemOccurrence should preserve the earlier timestamp") - - // FixAvailableTimestamp should also preserve the earlier value - s.Equal(firstFixTime.GetSeconds(), info2.GetFixAvailableTimestamp().GetSeconds(), - "FixAvailableTimestamp should preserve the earlier timestamp") -} diff --git a/central/image/datastore/datastore_test_constructors.go b/central/image/datastore/datastore_test_constructors.go index 2b4b9d816ab7c..092ee90487bd6 100644 --- a/central/image/datastore/datastore_test_constructors.go +++ b/central/image/datastore/datastore_test_constructors.go @@ -3,7 +3,6 @@ package datastore import ( "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/image/datastore/keyfence" pgStoreV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" "github.com/stackrox/rox/central/ranking" @@ -17,6 +16,5 @@ func GetTestPostgresDataStore(t testing.TB, pool postgres.DB) DataStore { riskStore := riskDS.GetTestPostgresDataStore(t, pool) imageRanker := ranking.ImageRanker() imageComponentRanker := ranking.ComponentRanker() - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(t, pool) - return NewWithPostgres(dbstore, riskStore, imageRanker, imageComponentRanker, imageCVEInfo) + return NewWithPostgres(dbstore, riskStore, imageRanker, imageComponentRanker) } diff --git a/central/image/datastore/singleton.go b/central/image/datastore/singleton.go index f8e48e2342370..1c4c9553c4828 100644 --- a/central/image/datastore/singleton.go +++ b/central/image/datastore/singleton.go @@ -1,7 +1,6 @@ package datastore import ( - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/globaldb" "github.com/stackrox/rox/central/image/datastore/keyfence" pgStoreV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" @@ -18,7 +17,7 @@ var ( func initialize() { storage := pgStoreV2.New(globaldb.GetPostgres(), false, keyfence.ImageKeyFenceSingleton()) - ad = NewWithPostgres(storage, riskDS.Singleton(), ranking.ImageRanker(), ranking.ComponentRanker(), imageCVEInfoDS.Singleton()) + ad = NewWithPostgres(storage, riskDS.Singleton(), ranking.ImageRanker(), ranking.ComponentRanker()) } // Singleton provides the interface for non-service external interaction. diff --git a/central/image/datastore/store/common/v2/parts_test.go b/central/image/datastore/store/common/v2/parts_test.go index a67fbc13d45b5..71aefdbfef53b 100644 --- a/central/image/datastore/store/common/v2/parts_test.go +++ b/central/image/datastore/store/common/v2/parts_test.go @@ -162,11 +162,13 @@ func TestSplitAndMergeImage(t *testing.T) { BaseImageId: "some-id", BaseImageFullName: "registry.example.com/ns/base:tag", BaseImageDigest: "sha256:...", + MaxLayerIndex: 3, }, { BaseImageId: "another-id", BaseImageFullName: "registry.example.com/ns/other:tag", BaseImageDigest: "sha256:...", + MaxLayerIndex: 3, }, }, Metadata: &storage.ImageMetadata{ @@ -302,11 +304,13 @@ func TestSplitAndMergeImage(t *testing.T) { BaseImageId: "some-id", BaseImageFullName: "registry.example.com/ns/base:tag", BaseImageDigest: "sha256:...", + MaxLayerIndex: 3, }, { BaseImageId: "another-id", BaseImageFullName: "registry.example.com/ns/other:tag", BaseImageDigest: "sha256:...", + MaxLayerIndex: 3, }, }, Scan: &storage.ImageScan{ diff --git a/central/image/datastore/store/common/v2/split_v2.go b/central/image/datastore/store/common/v2/split_v2.go index 3d103025269ee..1489bf96cc346 100644 --- a/central/image/datastore/store/common/v2/split_v2.go +++ b/central/image/datastore/store/common/v2/split_v2.go @@ -98,8 +98,10 @@ func GenerateImageComponentV2(os string, image *storage.Image, index int, from * } ret.LayerType = storage.LayerType_APPLICATION - if len(image.GetBaseImageInfo()) > 0 { - ret.LayerType = storage.LayerType_BASE_IMAGE + if len(image.GetBaseImageInfo()) > 0 && from.GetHasLayerIndex() != nil { + if from.GetLayerIndex() <= image.GetBaseImageInfo()[0].GetMaxLayerIndex() { + ret.LayerType = storage.LayerType_BASE_IMAGE + } } return ret, nil } diff --git a/central/image/datastore/store/v2/postgres/store.go b/central/image/datastore/store/v2/postgres/store.go index cee5ba800b1bf..cb3db6ca3fd81 100644 --- a/central/image/datastore/store/v2/postgres/store.go +++ b/central/image/datastore/store/v2/postgres/store.go @@ -16,7 +16,9 @@ import ( "github.com/stackrox/rox/central/metrics" v1 "github.com/stackrox/rox/generated/api/v1" "github.com/stackrox/rox/generated/storage" + "github.com/stackrox/rox/pkg/baseimage" "github.com/stackrox/rox/pkg/concurrency" + "github.com/stackrox/rox/pkg/features" "github.com/stackrox/rox/pkg/logging" ops "github.com/stackrox/rox/pkg/metrics" "github.com/stackrox/rox/pkg/postgres" @@ -269,6 +271,7 @@ func (s *storeImpl) copyFromImageComponentsV2(ctx context.Context, tx *postgres. "operatingsystem", "imageid", "location", + "layertype", "serialized", } @@ -289,6 +292,7 @@ func (s *storeImpl) copyFromImageComponentsV2(ctx context.Context, tx *postgres. obj.GetOperatingSystem(), obj.GetImageId(), obj.GetLocation(), + obj.GetLayerType(), serialized, }) @@ -473,6 +477,13 @@ func (s *storeImpl) upsert(ctx context.Context, obj *storage.Image) error { scanUpdated = scanUpdated || componentsEmpty + if features.BaseImageDetection.Enabled() { + // Re-verify base images when base image detection is enabled: + // 1. Legacy images may lack base image info if the feature was enabled after they were scanned. + // 2. User-provided base images may change over time. + scanUpdated = scanUpdated || baseimage.BaseImagesUpdated(oldImage.GetBaseImageInfo(), obj.GetBaseImageInfo()) + } + splitParts, err := common.SplitV2(obj, scanUpdated) if err != nil { return err diff --git a/central/image/service/service_impl.go b/central/image/service/service_impl.go index 6dc7997147909..e06a4622a53f2 100644 --- a/central/image/service/service_impl.go +++ b/central/image/service/service_impl.go @@ -164,6 +164,7 @@ func (s *serviceImpl) GetImage(ctx context.Context, request *v1.GetImageRequest) // This modifies the image object utils.StripCVEDescriptionsNoClone(image) } + utils.StripDatasourceNoClone(image.GetScan()) return image, nil } @@ -216,6 +217,7 @@ func (s *serviceImpl) ExportImages(req *v1.ExportImageRequest, srv v1.ImageServi defer cancel() } return s.mappingDatastore.WalkByQuery(ctx, parsedQuery, func(image *storage.Image) error { + utils.StripDatasourceNoClone(image.GetScan()) if err := srv.Send(&v1.ExportImageResponse{Image: image}); err != nil { return err } @@ -622,6 +624,7 @@ func (s *serviceImpl) ScanImage(ctx context.Context, request *v1.ScanImageReques if !request.GetIncludeSnoozed() { utils.FilterSuppressedCVEsNoCloneV2(imgV2) } + utils.StripDatasourceNoClone(imgV2.GetScan()) return utils.ConvertToV1(imgV2), nil } @@ -648,7 +651,7 @@ func (s *serviceImpl) ScanImage(ctx context.Context, request *v1.ScanImageReques if !request.GetIncludeSnoozed() { utils.FilterSuppressedCVEsNoClone(img) } - + utils.StripDatasourceNoClone(img.GetScan()) return img, nil } diff --git a/central/imagev2/datastore/datastore.go b/central/imagev2/datastore/datastore.go index 1a78cb2debad5..822590f67a77d 100644 --- a/central/imagev2/datastore/datastore.go +++ b/central/imagev2/datastore/datastore.go @@ -3,7 +3,6 @@ package datastore import ( "context" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/imagev2/datastore/store" "github.com/stackrox/rox/central/imagev2/views" "github.com/stackrox/rox/central/ranking" @@ -39,8 +38,8 @@ type DataStore interface { } // NewWithPostgres returns a new instance of DataStore using the input store, and searcher. -func NewWithPostgres(storage store.Store, risks riskDS.DataStore, imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker, imageCVEInfo imageCVEInfoDS.DataStore) DataStore { - ds := newDatastoreImpl(storage, risks, imageRanker, imageComponentRanker, imageCVEInfo) +func NewWithPostgres(storage store.Store, risks riskDS.DataStore, imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker) DataStore { + ds := newDatastoreImpl(storage, risks, imageRanker, imageComponentRanker) go ds.initializeRankers() return ds } diff --git a/central/imagev2/datastore/datastore_bench_postgres_test.go b/central/imagev2/datastore/datastore_bench_postgres_test.go index 97fcc86dcb9e7..db7d1248ca418 100644 --- a/central/imagev2/datastore/datastore_bench_postgres_test.go +++ b/central/imagev2/datastore/datastore_bench_postgres_test.go @@ -7,7 +7,6 @@ import ( "fmt" "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/image/datastore/keyfence" pgStore "github.com/stackrox/rox/central/imagev2/datastore/store/postgres" "github.com/stackrox/rox/central/ranking" @@ -33,8 +32,7 @@ func BenchmarkImageGetMany(b *testing.B) { db := testDB.DB mockRisk := mockRisks.NewMockDataStore(gomock.NewController(b)) - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(b, db) - datastore := NewWithPostgres(pgStore.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker(), imageCVEInfo) + datastore := NewWithPostgres(pgStore.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker()) ids := make([]string, 0, 100) images := make([]*storage.ImageV2, 0, 100) @@ -76,8 +74,7 @@ func BenchmarkImageUpsert(b *testing.B) { db := testDB.DB mockRisk := mockRisks.NewMockDataStore(gomock.NewController(b)) - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(b, db) - datastore := NewWithPostgres(pgStore.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker(), imageCVEInfo) + datastore := NewWithPostgres(pgStore.New(db, false, keyfence.ImageKeyFenceSingleton()), mockRisk, ranking.NewRanker(), ranking.NewRanker()) images := make([]*storage.ImageV2, 0, 100) for i := 0; i < 100; i++ { diff --git a/central/imagev2/datastore/datastore_impl.go b/central/imagev2/datastore/datastore_impl.go index 6971d114fa920..461fb17c2bb27 100644 --- a/central/imagev2/datastore/datastore_impl.go +++ b/central/imagev2/datastore/datastore_impl.go @@ -6,7 +6,6 @@ import ( "time" "github.com/pkg/errors" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/globaldb" "github.com/stackrox/rox/central/imagev2/datastore/store" "github.com/stackrox/rox/central/imagev2/views" @@ -16,12 +15,9 @@ import ( v1 "github.com/stackrox/rox/generated/api/v1" "github.com/stackrox/rox/generated/storage" "github.com/stackrox/rox/pkg/concurrency" - "github.com/stackrox/rox/pkg/cve" "github.com/stackrox/rox/pkg/errorhelpers" - "github.com/stackrox/rox/pkg/features" "github.com/stackrox/rox/pkg/images/utils" "github.com/stackrox/rox/pkg/logging" - "github.com/stackrox/rox/pkg/protocompat" "github.com/stackrox/rox/pkg/sac" "github.com/stackrox/rox/pkg/sac/resources" "github.com/stackrox/rox/pkg/scancomponent" @@ -44,13 +40,10 @@ type datastoreImpl struct { imageRanker *ranking.Ranker imageComponentRanker *ranking.Ranker - - imageCVEInfoDS imageCVEInfoDS.DataStore } func newDatastoreImpl(storage store.Store, risks riskDS.DataStore, - imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker, - imageCVEInfo imageCVEInfoDS.DataStore) *datastoreImpl { + imageRanker *ranking.Ranker, imageComponentRanker *ranking.Ranker) *datastoreImpl { ds := &datastoreImpl{ storage: storage, @@ -59,8 +52,6 @@ func newDatastoreImpl(storage store.Store, risks riskDS.DataStore, imageRanker: imageRanker, imageComponentRanker: imageComponentRanker, - imageCVEInfoDS: imageCVEInfo, - keyedMutex: concurrency.NewKeyedMutex(globaldb.DefaultDataStorePoolSize), } return ds @@ -280,20 +271,6 @@ func (ds *datastoreImpl) UpsertImage(ctx context.Context, image *storage.ImageV2 ds.keyedMutex.Lock(image.GetId()) defer ds.keyedMutex.Unlock(image.GetId()) - if features.CVEFixTimestampCriteria.Enabled() { - // Populate the ImageCVEInfo lookup table with CVE timing metadata - if err := ds.upsertImageCVEInfos(ctx, image); err != nil { - log.Warnf("Failed to upsert ImageCVEInfo: %v", err) - // Non-fatal, continue with image upsert - } - - // Enrich the CVEs with accurate timestamps from lookup table - if err := ds.enrichCVEsFromImageCVEInfo(ctx, image); err != nil { - log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) - // Non-fatal, continue with image upsert - } - } - ds.updateComponentRisk(image) utils.FillScanStatsV2(image) @@ -399,83 +376,6 @@ func (ds *datastoreImpl) updateComponentRisk(image *storage.ImageV2) { } } -// upsertImageCVEInfos populates the ImageCVEInfo lookup table with CVE timing metadata. -func (ds *datastoreImpl) upsertImageCVEInfos(ctx context.Context, image *storage.ImageV2) error { - if !features.CVEFixTimestampCriteria.Enabled() { - return nil - } - - infos := make([]*storage.ImageCVEInfo, 0) - now := protocompat.TimestampNow() - - for _, component := range image.GetScan().GetComponents() { - for _, vuln := range component.GetVulns() { - // Determine fix available timestamp: use scanner-provided value if available, - // otherwise fabricate from scan time if the CVE is fixable (has a fix version). - // This handles non-Red Hat data sources that don't provide fix timestamps. - fixAvailableTimestamp := vuln.GetFixAvailableTimestamp() - if fixAvailableTimestamp == nil && vuln.GetFixedBy() != "" { - fixAvailableTimestamp = now - } - - info := &storage.ImageCVEInfo{ - Id: cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource()), - FixAvailableTimestamp: fixAvailableTimestamp, - FirstSystemOccurrence: now, // Smart upsert in ImageCVEInfo datastore preserves existing - } - infos = append(infos, info) - } - } - - return ds.imageCVEInfoDS.UpsertMany(ctx, infos) -} - -// enrichCVEsFromImageCVEInfo enriches the image's CVEs with accurate timestamps from the lookup table. -func (ds *datastoreImpl) enrichCVEsFromImageCVEInfo(ctx context.Context, image *storage.ImageV2) error { - if !features.CVEFixTimestampCriteria.Enabled() { - return nil - } - - // Collect all IDs - ids := make([]string, 0) - for _, component := range image.GetScan().GetComponents() { - for _, vuln := range component.GetVulns() { - ids = append(ids, cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource())) - } - } - - if len(ids) == 0 { - return nil - } - - // Batch fetch - infos, err := ds.imageCVEInfoDS.GetBatch(ctx, ids) - if err != nil { - return err - } - - // Build lookup map - infoMap := make(map[string]*storage.ImageCVEInfo) - for _, info := range infos { - infoMap[info.GetId()] = info - } - - // Enrich CVEs and blank out datasource after using it - for _, component := range image.GetScan().GetComponents() { - for _, vuln := range component.GetVulns() { - id := cve.ImageCVEInfoID(vuln.GetCve(), component.GetName(), vuln.GetDatasource()) - if info, ok := infoMap[id]; ok { - vuln.FixAvailableTimestamp = info.GetFixAvailableTimestamp() - vuln.FirstSystemOccurrence = info.GetFirstSystemOccurrence() - } - // Blank out datasource after using it - this is internal scanner data not meant for end users - vuln.Datasource = "" - } - } - - return nil -} - // ImageSearchResultConverter implements search.SearchResultConverter for image search results. // This enables single-pass query construction for SearchResult protos. type ImageSearchResultConverter struct{} diff --git a/central/imagev2/datastore/datastore_test_constructors.go b/central/imagev2/datastore/datastore_test_constructors.go index 8ad2d8401c852..0fa3f8dc5e127 100644 --- a/central/imagev2/datastore/datastore_test_constructors.go +++ b/central/imagev2/datastore/datastore_test_constructors.go @@ -3,7 +3,6 @@ package datastore import ( "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/imagev2/datastore/keyfence" pgStore "github.com/stackrox/rox/central/imagev2/datastore/store/postgres" "github.com/stackrox/rox/central/ranking" @@ -17,6 +16,5 @@ func GetTestPostgresDataStore(t testing.TB, pool postgres.DB) DataStore { riskStore := riskDS.GetTestPostgresDataStore(t, pool) imageRanker := ranking.ImageRanker() imageComponentRanker := ranking.ComponentRanker() - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(t, pool) - return NewWithPostgres(dbstore, riskStore, imageRanker, imageComponentRanker, imageCVEInfo) + return NewWithPostgres(dbstore, riskStore, imageRanker, imageComponentRanker) } diff --git a/central/imagev2/datastore/singleton.go b/central/imagev2/datastore/singleton.go index 1bad2af434508..fe6f5fb3e6ed7 100644 --- a/central/imagev2/datastore/singleton.go +++ b/central/imagev2/datastore/singleton.go @@ -1,7 +1,6 @@ package datastore import ( - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" "github.com/stackrox/rox/central/globaldb" "github.com/stackrox/rox/central/imagev2/datastore/keyfence" pgStore "github.com/stackrox/rox/central/imagev2/datastore/store/postgres" @@ -19,7 +18,7 @@ var ( func initialize() { storage := pgStore.New(globaldb.GetPostgres(), false, keyfence.ImageKeyFenceSingleton()) - ad = NewWithPostgres(storage, riskDS.Singleton(), ranking.ImageRanker(), ranking.ComponentRanker(), imageCVEInfoDS.Singleton()) + ad = NewWithPostgres(storage, riskDS.Singleton(), ranking.ImageRanker(), ranking.ComponentRanker()) } // Singleton provides the interface for non-service external interaction. diff --git a/central/imagev2/datastore/store/common/parts_test.go b/central/imagev2/datastore/store/common/parts_test.go index c720ac0345818..3d8f59ac2f926 100644 --- a/central/imagev2/datastore/store/common/parts_test.go +++ b/central/imagev2/datastore/store/common/parts_test.go @@ -175,11 +175,13 @@ func TestSplitAndMergeImageV2(t *testing.T) { BaseImageId: "some-id", BaseImageFullName: "registry.example.com/ns/base:tag", BaseImageDigest: "sha256:...", + MaxLayerIndex: 3, }, { BaseImageId: "another-id", BaseImageFullName: "registry.example.com/ns/other:tag", BaseImageDigest: "sha256:...", + MaxLayerIndex: 3, }, }, Metadata: &storage.ImageMetadata{ @@ -323,11 +325,13 @@ func TestSplitAndMergeImageV2(t *testing.T) { { BaseImageId: "some-id", BaseImageFullName: "registry.example.com/ns/base:tag", + MaxLayerIndex: 3, BaseImageDigest: "sha256:...", }, { BaseImageId: "another-id", BaseImageFullName: "registry.example.com/ns/other:tag", + MaxLayerIndex: 3, BaseImageDigest: "sha256:...", }, }, diff --git a/central/imagev2/datastore/store/common/split.go b/central/imagev2/datastore/store/common/split.go index 11c5ebd383ddf..60d4829f87145 100644 --- a/central/imagev2/datastore/store/common/split.go +++ b/central/imagev2/datastore/store/common/split.go @@ -102,8 +102,10 @@ func GenerateImageComponentV2(os string, image *storage.ImageV2, index int, from } ret.LayerType = storage.LayerType_APPLICATION - if len(image.GetBaseImageInfo()) > 0 { - ret.LayerType = storage.LayerType_BASE_IMAGE + if len(image.GetBaseImageInfo()) > 0 && from.GetHasLayerIndex() != nil { + if from.GetLayerIndex() <= image.GetBaseImageInfo()[0].GetMaxLayerIndex() { + ret.LayerType = storage.LayerType_BASE_IMAGE + } } return ret, nil } diff --git a/central/imagev2/datastore/store/postgres/store.go b/central/imagev2/datastore/store/postgres/store.go index 1127f419035a4..c246da7cd07f6 100644 --- a/central/imagev2/datastore/store/postgres/store.go +++ b/central/imagev2/datastore/store/postgres/store.go @@ -15,7 +15,9 @@ import ( "github.com/stackrox/rox/central/metrics" v1 "github.com/stackrox/rox/generated/api/v1" "github.com/stackrox/rox/generated/storage" + "github.com/stackrox/rox/pkg/baseimage" "github.com/stackrox/rox/pkg/concurrency" + "github.com/stackrox/rox/pkg/features" "github.com/stackrox/rox/pkg/logging" ops "github.com/stackrox/rox/pkg/metrics" "github.com/stackrox/rox/pkg/postgres" @@ -295,6 +297,7 @@ func (s *storeImpl) copyFromImageComponentsV2(ctx context.Context, tx *postgres. "operatingsystem", "imageidv2", "location", + "layertype", "serialized", } @@ -315,6 +318,7 @@ func (s *storeImpl) copyFromImageComponentsV2(ctx context.Context, tx *postgres. obj.GetOperatingSystem(), obj.GetImageIdV2(), obj.GetLocation(), + obj.GetLayerType(), serialized, }) @@ -518,6 +522,13 @@ func (s *storeImpl) upsert(ctx context.Context, obj *storage.ImageV2) error { scanUpdated = scanUpdated || componentsEmpty + if features.BaseImageDetection.Enabled() { + // Re-verify base images when base image detection is enabled: + // 1. Legacy images may lack base image info if the feature was enabled after they were scanned. + // 2. User-provided base images may change over time. + scanUpdated = scanUpdated || baseimage.BaseImagesUpdated(oldImage.GetBaseImageInfo(), obj.GetBaseImageInfo()) + } + splitParts, err := common.Split(obj, scanUpdated) if err != nil { return err diff --git a/central/imagev2/datastoretest/datastore_impl_test.go b/central/imagev2/datastoretest/datastore_impl_test.go index 1e92e0eab8a53..3ed6c2147ca99 100644 --- a/central/imagev2/datastoretest/datastore_impl_test.go +++ b/central/imagev2/datastoretest/datastore_impl_test.go @@ -8,7 +8,6 @@ import ( "sort" "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" imageCVEDS "github.com/stackrox/rox/central/cve/image/v2/datastore" imageCVEPostgres "github.com/stackrox/rox/central/cve/image/v2/datastore/store/postgres" imageComponentDS "github.com/stackrox/rox/central/imagecomponent/v2/datastore" @@ -64,8 +63,7 @@ func (s *ImageV2DataStoreTestSuite) SetupSuite() { func (s *ImageV2DataStoreTestSuite) SetupTest() { s.mockRisk = mockRisks.NewMockDataStore(gomock.NewController(s.T())) dbStore := pgStore.New(s.testDB.DB, false, keyfence.ImageKeyFenceSingleton()) - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(s.T(), s.testDB.DB) - s.datastore = imageDataStoreV2.NewWithPostgres(dbStore, s.mockRisk, ranking.NewRanker(), ranking.NewRanker(), imageCVEInfo) + s.datastore = imageDataStoreV2.NewWithPostgres(dbStore, s.mockRisk, ranking.NewRanker(), ranking.NewRanker()) componentStorage := imageComponentPostgres.New(s.testDB.DB) s.componentDataStore = imageComponentDS.New(componentStorage, s.mockRisk, ranking.NewRanker()) diff --git a/central/pruning/pruning_test.go b/central/pruning/pruning_test.go index 517fa32fb0db3..9313db7086fe1 100644 --- a/central/pruning/pruning_test.go +++ b/central/pruning/pruning_test.go @@ -17,7 +17,6 @@ import ( configDatastore "github.com/stackrox/rox/central/config/datastore" configDatastoreMocks "github.com/stackrox/rox/central/config/datastore/mocks" clusterCVEDS "github.com/stackrox/rox/central/cve/cluster/datastore/mocks" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" nodeCVEDS "github.com/stackrox/rox/central/cve/node/datastore" deploymentDatastore "github.com/stackrox/rox/central/deployment/datastore" imageDatastore "github.com/stackrox/rox/central/image/datastore" @@ -255,14 +254,12 @@ func (s *PruningTestSuite) generateImageDataStructures(ctx context.Context) (ale var images imageDatastore.DataStore var imagesV2 imageV2Datastore.DataStore - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(s.T(), s.pool) if features.FlattenImageData.Enabled() { imagesV2 = imageV2Datastore.NewWithPostgres( imageV2Postgres.New(s.pool, true, concurrency.NewKeyFence()), mockRiskDatastore, ranking.ImageRanker(), ranking.ComponentRanker(), - imageCVEInfo, ) } else { images = imageDatastore.NewWithPostgres( @@ -270,7 +267,6 @@ func (s *PruningTestSuite) generateImageDataStructures(ctx context.Context) (ale mockRiskDatastore, ranking.ImageRanker(), ranking.ComponentRanker(), - imageCVEInfo, ) } diff --git a/central/reprocessor/reprocessor_test.go b/central/reprocessor/reprocessor_test.go index abb034535cba2..d95e80c37a9db 100644 --- a/central/reprocessor/reprocessor_test.go +++ b/central/reprocessor/reprocessor_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" imageDatastore "github.com/stackrox/rox/central/image/datastore" imagePostgresV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" imageV2Datastore "github.com/stackrox/rox/central/imagev2/datastore" @@ -35,8 +34,7 @@ func TestImagesWithSignaturesQuery(t *testing.T) { pool := testingDB.DB defer pool.Close() - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(t, pool) - imageDS := imageDatastore.NewWithPostgres(imagePostgresV2.New(pool, false, concurrency.NewKeyFence()), nil, ranking.ImageRanker(), ranking.ComponentRanker(), imageCVEInfo) + imageDS := imageDatastore.NewWithPostgres(imagePostgresV2.New(pool, false, concurrency.NewKeyFence()), nil, ranking.ImageRanker(), ranking.ComponentRanker()) imgWithSignature := fixtures.GetImage() imgWithoutSignature := fixtures.GetImageWithUniqueComponents(10) @@ -82,8 +80,7 @@ func TestImagesWithSignaturesQueryV2(t *testing.T) { pool := testingDB.DB defer pool.Close() - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(t, pool) - imageDS := imageV2Datastore.NewWithPostgres(imageV2PG.New(pool, false, concurrency.NewKeyFence()), nil, ranking.ImageRanker(), ranking.ComponentRanker(), imageCVEInfo) + imageDS := imageV2Datastore.NewWithPostgres(imageV2PG.New(pool, false, concurrency.NewKeyFence()), nil, ranking.ImageRanker(), ranking.ComponentRanker()) imgWithSignature := fixtures.GetImageV2() imgWithoutSignature := fixtures.GetImageV2WithUniqueComponents(10) diff --git a/central/views/deployments/view_test.go b/central/views/deployments/view_test.go index a05c10c46bfcb..2a6cdb213d0da 100644 --- a/central/views/deployments/view_test.go +++ b/central/views/deployments/view_test.go @@ -7,7 +7,6 @@ import ( "sort" "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" deploymentDS "github.com/stackrox/rox/central/deployment/datastore" imageDS "github.com/stackrox/rox/central/image/datastore" imagePostgresV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" @@ -102,13 +101,11 @@ func (s *DeploymentViewTestSuite) SetupSuite() { mockRisk := mockRisks.NewMockDataStore(mockCtrl) // Initialize the datastore. - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(s.T(), s.testDB.DB) imageStore := imageDS.NewWithPostgres( imagePostgresV2.New(s.testDB.DB, false, concurrency.NewKeyFence()), mockRisk, ranking.ImageRanker(), ranking.ComponentRanker(), - imageCVEInfo, ) deploymentStore, err := deploymentDS.NewTestDataStore( s.T(), diff --git a/central/views/imagecveflat/view_test.go b/central/views/imagecveflat/view_test.go index 01a279b1d5e06..9bb239e94698d 100644 --- a/central/views/imagecveflat/view_test.go +++ b/central/views/imagecveflat/view_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" imageCVEV2DS "github.com/stackrox/rox/central/cve/image/v2/datastore" deploymentDS "github.com/stackrox/rox/central/deployment/datastore" imageDS "github.com/stackrox/rox/central/image/datastore" @@ -119,13 +118,11 @@ func (s *ImageCVEFlatViewTestSuite) SetupSuite() { mockRisk := mockRisks.NewMockDataStore(mockCtrl) // Initialize the datastore. - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(s.T(), s.testDB.DB) imageStore := imageDS.NewWithPostgres( imagePostgresV2.New(s.testDB.DB, false, concurrency.NewKeyFence()), mockRisk, ranking.ImageRanker(), ranking.ComponentRanker(), - imageCVEInfo, ) deploymentStore, err := deploymentDS.NewTestDataStore( s.T(), diff --git a/central/vulnmgmt/service/service_impl.go b/central/vulnmgmt/service/service_impl.go index b52b6c6a819f3..0ccf0ada10704 100644 --- a/central/vulnmgmt/service/service_impl.go +++ b/central/vulnmgmt/service/service_impl.go @@ -17,6 +17,7 @@ import ( "github.com/stackrox/rox/pkg/grpc/authz" "github.com/stackrox/rox/pkg/grpc/authz/perrpc" "github.com/stackrox/rox/pkg/grpc/authz/user" + "github.com/stackrox/rox/pkg/images/utils" "github.com/stackrox/rox/pkg/logging" "github.com/stackrox/rox/pkg/postgres" "github.com/stackrox/rox/pkg/sac/resources" @@ -120,6 +121,7 @@ func (s *serviceImpl) VulnMgmtExportWorkloads(req *v1.VulnMgmtExportWorkloadsReq continue } if found { + utils.StripDatasourceNoClone(img.GetScan()) images = append(images, img) imageCache.Add(imgID, img) } else { diff --git a/central/vulnmgmt/vulnerabilityrequest/manager/querymgr/query_manager_impl_test.go b/central/vulnmgmt/vulnerabilityrequest/manager/querymgr/query_manager_impl_test.go index 5bbb0ca4d5064..0533a8ee1e377 100644 --- a/central/vulnmgmt/vulnerabilityrequest/manager/querymgr/query_manager_impl_test.go +++ b/central/vulnmgmt/vulnerabilityrequest/manager/querymgr/query_manager_impl_test.go @@ -6,7 +6,6 @@ import ( "context" "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" imageDS "github.com/stackrox/rox/central/image/datastore" imagePostgresV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" imageV2DS "github.com/stackrox/rox/central/imagev2/datastore" @@ -74,13 +73,11 @@ func (s *VulnReqQueryManagerTestSuite) SetupTest() { } func (s *VulnReqQueryManagerTestSuite) createImageDataStore() { - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(s.T(), s.testDB.DB) s.imageDataStore = imageDS.NewWithPostgres( imagePostgresV2.New(s.testDB.DB, false, concurrency.NewKeyFence()), mockRisks.NewMockDataStore(s.mockCtrl), ranking.NewRanker(), ranking.NewRanker(), - imageCVEInfo, ) if features.FlattenImageData.Enabled() { s.imageV2DataStore = imageV2DS.NewWithPostgres( @@ -88,7 +85,6 @@ func (s *VulnReqQueryManagerTestSuite) createImageDataStore() { mockRisks.NewMockDataStore(s.mockCtrl), ranking.NewRanker(), ranking.NewRanker(), - imageCVEInfo, ) } } diff --git a/central/vulnmgmt/vulnerabilityrequest/manager/requestmgr/manager_impl_flat_cve_data_test.go b/central/vulnmgmt/vulnerabilityrequest/manager/requestmgr/manager_impl_flat_cve_data_test.go index d629494a40b10..c0b99b4d81b35 100644 --- a/central/vulnmgmt/vulnerabilityrequest/manager/requestmgr/manager_impl_flat_cve_data_test.go +++ b/central/vulnmgmt/vulnerabilityrequest/manager/requestmgr/manager_impl_flat_cve_data_test.go @@ -6,7 +6,6 @@ import ( "context" "testing" - imageCVEInfoDS "github.com/stackrox/rox/central/cve/image/info/datastore" imageDS "github.com/stackrox/rox/central/image/datastore" imagePostgresV2 "github.com/stackrox/rox/central/image/datastore/store/v2/postgres" imageV2DS "github.com/stackrox/rox/central/imagev2/datastore" @@ -56,14 +55,12 @@ func (m *managerImplTestFlatData) SetupSuite() { m.Require().NoError(err) var imageStore imageDS.DataStore var imageV2Store imageV2DS.DataStore - imageCVEInfo := imageCVEInfoDS.GetTestPostgresDataStore(m.T(), m.testDB.DB) if features.FlattenImageData.Enabled() { imageV2Store = imageV2DS.NewWithPostgres( imageV2Postgres.New(m.testDB.DB, false, concurrency.NewKeyFence()), mockRisk, ranking.ImageRanker(), ranking.ComponentRanker(), - imageCVEInfo, ) } else { imageStore = imageDS.NewWithPostgres( @@ -71,7 +68,6 @@ func (m *managerImplTestFlatData) SetupSuite() { mockRisk, ranking.ImageRanker(), ranking.ComponentRanker(), - imageCVEInfo, ) } m.manager = &managerImpl{ diff --git a/config-controller/config/default/kustomization.yaml b/config-controller/config/default/kustomization.yaml index 44ca30fe6a803..3afeeb23b0fae 100644 --- a/config-controller/config/default/kustomization.yaml +++ b/config-controller/config/default/kustomization.yaml @@ -1,11 +1,8 @@ # Adds namespace to all resources. namespace: config-controller-system -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. +# Value of this field is prepended to the names of all resources. +# Note that it should also match with the prefix (text before '-system') of the namespace field above. namePrefix: config-controller- # Labels to add to all resources and selectors. diff --git a/deploy/common/k8sbased.sh b/deploy/common/k8sbased.sh index 3e7471429a5cc..1b2fb2d6a485b 100644 --- a/deploy/common/k8sbased.sh +++ b/deploy/common/k8sbased.sh @@ -866,8 +866,8 @@ function launch_sensor { fi if [[ "${SFA_AGENT:-false}" == "true" ]]; then - echo "Enable Sensitive File Activity agent" - extra_helm_config+=(--set "collector.sfaEnabled=true") + echo "Enable File Activity Monitoring" + extra_helm_config+=(--set "collector.famEnabled=true") fi if [[ -n "$CI" ]]; then diff --git a/generated/api/v1/image_service.swagger.json b/generated/api/v1/image_service.swagger.json index efd5c5e4e3c56..c294f0865c1f0 100644 --- a/generated/api/v1/image_service.swagger.json +++ b/generated/api/v1/image_service.swagger.json @@ -600,6 +600,11 @@ "created": { "type": "string", "format": "date-time" + }, + "maxLayerIndex": { + "type": "integer", + "format": "int32", + "description": "Index of the last base image layer, taking into account\n\"empty layers\" (aka. metadata history without SHA)." } } }, diff --git a/generated/api/v1/vuln_mgmt_service.swagger.json b/generated/api/v1/vuln_mgmt_service.swagger.json index b40e5656ed951..5655f69e2ed52 100644 --- a/generated/api/v1/vuln_mgmt_service.swagger.json +++ b/generated/api/v1/vuln_mgmt_service.swagger.json @@ -306,6 +306,11 @@ "created": { "type": "string", "format": "date-time" + }, + "maxLayerIndex": { + "type": "integer", + "format": "int32", + "description": "Index of the last base image layer, taking into account\n\"empty layers\" (aka. metadata history without SHA)." } } }, diff --git a/generated/storage/cve.pb.go b/generated/storage/cve.pb.go index 89540f104688a..5f70d577df0de 100644 --- a/generated/storage/cve.pb.go +++ b/generated/storage/cve.pb.go @@ -1590,6 +1590,7 @@ type ImageCVEV2 struct { ImageIdV2 string `protobuf:"bytes,15,opt,name=image_id_v2,json=imageIdV2,proto3" json:"image_id_v2,omitempty" sql:"fk(ImageV2:id),index=btree,allow-null"` // @gotags: sql:"fk(ImageV2:id),index=btree,allow-null" // Timestamp when the fix for this CVE was made available according to the sources. FixAvailableTimestamp *timestamppb.Timestamp `protobuf:"bytes,16,opt,name=fix_available_timestamp,json=fixAvailableTimestamp,proto3" json:"fix_available_timestamp,omitempty" search:"CVE Fix Available Timestamp,hidden"` // @gotags: search:"CVE Fix Available Timestamp,hidden" + Datasource string `protobuf:"bytes,17,opt,name=datasource,proto3" json:"datasource,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1746,6 +1747,13 @@ func (x *ImageCVEV2) GetFixAvailableTimestamp() *timestamppb.Timestamp { return nil } +func (x *ImageCVEV2) GetDatasource() string { + if x != nil { + return x.Datasource + } + return "" +} + type isImageCVEV2_HasFixedBy interface { isImageCVEV2_HasFixedBy() } @@ -2357,6 +2365,7 @@ type ImageCVEInfo struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" search:"CVE Info" sql:"pk"` // @gotags: search:"CVE Info" sql:"pk" FixAvailableTimestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=fix_available_timestamp,json=fixAvailableTimestamp,proto3" json:"fix_available_timestamp,omitempty" search:"CVE Fix Available Timestamp,hidden"` // @gotags: search:"CVE Fix Available Timestamp,hidden" FirstSystemOccurrence *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=first_system_occurrence,json=firstSystemOccurrence,proto3" json:"first_system_occurrence,omitempty" search:"First System Occurrence Timestamp,hidden"` // @gotags: search:"First System Occurrence Timestamp,hidden" + Cve string `protobuf:"bytes,4,opt,name=cve,proto3" json:"cve,omitempty" search:"CVE" sql:"index"` // @gotags: search:"CVE" sql:"index" unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2412,6 +2421,13 @@ func (x *ImageCVEInfo) GetFirstSystemOccurrence() *timestamppb.Timestamp { return nil } +func (x *ImageCVEInfo) GetCve() string { + if x != nil { + return x.Cve + } + return "" +} + type CVE_DistroSpecific struct { state protoimpl.MessageState `protogen:"open.v1"` Severity VulnerabilitySeverity `protobuf:"varint,1,opt,name=severity,proto3,enum=storage.VulnerabilitySeverity" json:"severity,omitempty"` @@ -2689,7 +2705,7 @@ const file_storage_cve_proto_rawDesc = "" + "\anvdcvss\x18\n" + " \x01(\x02R\anvdcvss\x125\n" + "\fcvss_metrics\x18\v \x03(\v2\x12.storage.CVSSScoreR\vcvssMetrics\x12E\n" + - "\x11nvd_score_version\x18\f \x01(\x0e2\x19.storage.CvssScoreVersionR\x0fnvdScoreVersion:\x02\x18\x01\"\xdc\x05\n" + + "\x11nvd_score_version\x18\f \x01(\x0e2\x19.storage.CvssScoreVersionR\x0fnvdScoreVersion:\x02\x18\x01\"\xfc\x05\n" + "\n" + "ImageCVEV2\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1d\n" + @@ -2709,7 +2725,10 @@ const file_storage_cve_proto_rawDesc = "" + "\fcomponent_id\x18\r \x01(\tR\vcomponentId\x12-\n" + "\badvisory\x18\x0e \x01(\v2\x11.storage.AdvisoryR\badvisory\x12\x1e\n" + "\vimage_id_v2\x18\x0f \x01(\tR\timageIdV2\x12R\n" + - "\x17fix_available_timestamp\x18\x10 \x01(\v2\x1a.google.protobuf.TimestampR\x15fixAvailableTimestampB\x0e\n" + + "\x17fix_available_timestamp\x18\x10 \x01(\v2\x1a.google.protobuf.TimestampR\x15fixAvailableTimestamp\x12\x1e\n" + + "\n" + + "datasource\x18\x11 \x01(\tR\n" + + "datasourceB\x0e\n" + "\fhas_fixed_by\"\xe4\x03\n" + "\aNodeCVE\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x124\n" + @@ -2825,11 +2844,12 @@ const file_storage_cve_proto_rawDesc = "" + "\n" + "\x06MEDIUM\x10\x03\x12\b\n" + "\x04HIGH\x10\x04\x12\f\n" + - "\bCRITICAL\x10\x05\"\xc6\x01\n" + + "\bCRITICAL\x10\x05\"\xd8\x01\n" + "\fImageCVEInfo\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12R\n" + "\x17fix_available_timestamp\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x15fixAvailableTimestamp\x12R\n" + - "\x17first_system_occurrence\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x15firstSystemOccurrence*D\n" + + "\x17first_system_occurrence\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x15firstSystemOccurrence\x12\x10\n" + + "\x03cve\x18\x04 \x01(\tR\x03cve*D\n" + "\x12VulnerabilityState\x12\f\n" + "\bOBSERVED\x10\x00\x12\f\n" + "\bDEFERRED\x10\x01\x12\x12\n" + diff --git a/generated/storage/cve_vtproto.pb.go b/generated/storage/cve_vtproto.pb.go index 35eb569be525f..73f01e2f04092 100644 --- a/generated/storage/cve_vtproto.pb.go +++ b/generated/storage/cve_vtproto.pb.go @@ -270,6 +270,7 @@ func (m *ImageCVEV2) CloneVT() *ImageCVEV2 { r.Advisory = m.Advisory.CloneVT() r.ImageIdV2 = m.ImageIdV2 r.FixAvailableTimestamp = (*timestamppb.Timestamp)((*timestamppb1.Timestamp)(m.FixAvailableTimestamp).CloneVT()) + r.Datasource = m.Datasource if m.HasFixedBy != nil { r.HasFixedBy = m.HasFixedBy.(interface { CloneVT() isImageCVEV2_HasFixedBy @@ -450,6 +451,7 @@ func (m *ImageCVEInfo) CloneVT() *ImageCVEInfo { r.Id = m.Id r.FixAvailableTimestamp = (*timestamppb.Timestamp)((*timestamppb1.Timestamp)(m.FixAvailableTimestamp).CloneVT()) r.FirstSystemOccurrence = (*timestamppb.Timestamp)((*timestamppb1.Timestamp)(m.FirstSystemOccurrence).CloneVT()) + r.Cve = m.Cve if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -911,6 +913,9 @@ func (this *ImageCVEV2) EqualVT(that *ImageCVEV2) bool { if !(*timestamppb1.Timestamp)(this.FixAvailableTimestamp).EqualVT((*timestamppb1.Timestamp)(that.FixAvailableTimestamp)) { return false } + if this.Datasource != that.Datasource { + return false + } return string(this.unknownFields) == string(that.unknownFields) } @@ -1233,6 +1238,9 @@ func (this *ImageCVEInfo) EqualVT(that *ImageCVEInfo) bool { if !(*timestamppb1.Timestamp)(this.FirstSystemOccurrence).EqualVT((*timestamppb1.Timestamp)(that.FirstSystemOccurrence)) { return false } + if this.Cve != that.Cve { + return false + } return string(this.unknownFields) == string(that.unknownFields) } @@ -2037,6 +2045,15 @@ func (m *ImageCVEV2) MarshalToSizedBufferVT(dAtA []byte) (int, error) { } i -= size } + if len(m.Datasource) > 0 { + i -= len(m.Datasource) + copy(dAtA[i:], m.Datasource) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Datasource))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + } if m.FixAvailableTimestamp != nil { size, err := (*timestamppb1.Timestamp)(m.FixAvailableTimestamp).MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -2719,6 +2736,13 @@ func (m *ImageCVEInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.Cve) > 0 { + i -= len(m.Cve) + copy(dAtA[i:], m.Cve) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Cve))) + i-- + dAtA[i] = 0x22 + } if m.FirstSystemOccurrence != nil { size, err := (*timestamppb1.Timestamp)(m.FirstSystemOccurrence).MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -3121,6 +3145,10 @@ func (m *ImageCVEV2) SizeVT() (n int) { l = (*timestamppb1.Timestamp)(m.FixAvailableTimestamp).SizeVT() n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } + l = len(m.Datasource) + if l > 0 { + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -3385,6 +3413,10 @@ func (m *ImageCVEInfo) SizeVT() (n int) { l = (*timestamppb1.Timestamp)(m.FirstSystemOccurrence).SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + l = len(m.Cve) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -5950,6 +5982,38 @@ func (m *ImageCVEV2) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Datasource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Datasource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -7436,6 +7500,38 @@ func (m *ImageCVEInfo) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cve", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Cve = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -10099,6 +10195,42 @@ func (m *ImageCVEV2) UnmarshalVTUnsafe(dAtA []byte) error { return err } iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Datasource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var stringValue string + if intStringLen > 0 { + stringValue = unsafe.String(&dAtA[iNdEx], intStringLen) + } + m.Datasource = stringValue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -11613,6 +11745,42 @@ func (m *ImageCVEInfo) UnmarshalVTUnsafe(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cve", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var stringValue string + if intStringLen > 0 { + stringValue = unsafe.String(&dAtA[iNdEx], intStringLen) + } + m.Cve = stringValue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/generated/storage/image.pb.go b/generated/storage/image.pb.go index bef9f84569e75..102c049cfda62 100644 --- a/generated/storage/image.pb.go +++ b/generated/storage/image.pb.go @@ -1879,8 +1879,11 @@ type BaseImageInfo struct { BaseImageFullName string `protobuf:"bytes,2,opt,name=base_image_full_name,json=baseImageFullName,proto3" json:"base_image_full_name,omitempty"` BaseImageDigest string `protobuf:"bytes,3,opt,name=base_image_digest,json=baseImageDigest,proto3" json:"base_image_digest,omitempty"` Created *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created,proto3" json:"created,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Index of the last base image layer, taking into account + // "empty layers" (aka. metadata history without SHA). + MaxLayerIndex int32 `protobuf:"varint,5,opt,name=max_layer_index,json=maxLayerIndex,proto3" json:"max_layer_index,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *BaseImageInfo) Reset() { @@ -1941,6 +1944,13 @@ func (x *BaseImageInfo) GetCreated() *timestamppb.Timestamp { return nil } +func (x *BaseImageInfo) GetMaxLayerIndex() int32 { + if x != nil { + return x.MaxLayerIndex + } + return 0 +} + type EmbeddedImageScanComponent_Executable struct { state protoimpl.MessageState `protogen:"open.v1"` Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` @@ -2170,12 +2180,13 @@ const file_storage_image_proto_rawDesc = "" + "\vset_fixableJ\x04\b\t\x10\n" + "\"\"\n" + "\fWatchedImage\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\"\xc6\x01\n" + + "\x04name\x18\x01 \x01(\tR\x04name\"\xee\x01\n" + "\rBaseImageInfo\x12\"\n" + "\rbase_image_id\x18\x01 \x01(\tR\vbaseImageId\x12/\n" + "\x14base_image_full_name\x18\x02 \x01(\tR\x11baseImageFullName\x12*\n" + "\x11base_image_digest\x18\x03 \x01(\tR\x0fbaseImageDigest\x124\n" + - "\acreated\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\acreated*s\n" + + "\acreated\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\acreated\x12&\n" + + "\x0fmax_layer_index\x18\x05 \x01(\x05R\rmaxLayerIndex*s\n" + "\n" + "SourceType\x12\x06\n" + "\x02OS\x10\x00\x12\n" + diff --git a/generated/storage/image_vtproto.pb.go b/generated/storage/image_vtproto.pb.go index 733d77470c9f8..5424204c95f3a 100644 --- a/generated/storage/image_vtproto.pb.go +++ b/generated/storage/image_vtproto.pb.go @@ -647,6 +647,7 @@ func (m *BaseImageInfo) CloneVT() *BaseImageInfo { r.BaseImageFullName = m.BaseImageFullName r.BaseImageDigest = m.BaseImageDigest r.Created = (*timestamppb.Timestamp)((*timestamppb1.Timestamp)(m.Created).CloneVT()) + r.MaxLayerIndex = m.MaxLayerIndex if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -1700,6 +1701,9 @@ func (this *BaseImageInfo) EqualVT(that *BaseImageInfo) bool { if !(*timestamppb1.Timestamp)(this.Created).EqualVT((*timestamppb1.Timestamp)(that.Created)) { return false } + if this.MaxLayerIndex != that.MaxLayerIndex { + return false + } return string(this.unknownFields) == string(that.unknownFields) } @@ -3301,6 +3305,11 @@ func (m *BaseImageInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.MaxLayerIndex != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MaxLayerIndex)) + i-- + dAtA[i] = 0x28 + } if m.Created != nil { size, err := (*timestamppb1.Timestamp)(m.Created).MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -4029,6 +4038,9 @@ func (m *BaseImageInfo) SizeVT() (n int) { l = (*timestamppb1.Timestamp)(m.Created).SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + if m.MaxLayerIndex != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.MaxLayerIndex)) + } n += len(m.unknownFields) return n } @@ -8070,6 +8082,25 @@ func (m *BaseImageInfo) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxLayerIndex", wireType) + } + m.MaxLayerIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxLayerIndex |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -12282,6 +12313,25 @@ func (m *BaseImageInfo) UnmarshalVTUnsafe(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxLayerIndex", wireType) + } + m.MaxLayerIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxLayerIndex |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/image/postgres/konflux.Dockerfile b/image/postgres/konflux.Dockerfile index 490be6b1405ef..9df236ead9d5d 100644 --- a/image/postgres/konflux.Dockerfile +++ b/image/postgres/konflux.Dockerfile @@ -1,5 +1,5 @@ ARG PG_VERSION=15 -FROM registry.redhat.io/rhel8/postgresql-${PG_VERSION}:latest@sha256:042f6efe0f16e94ffb2d0a3bede852bb026b6dce661ac5b339e6f63846467b9d AS final +FROM registry.redhat.io/rhel8/postgresql-${PG_VERSION}:latest@sha256:94182920a14a5175523d40c1bdf1168eaabbb6b494eda0519d3a87916ba937d6 AS final USER root diff --git a/image/rhel/konflux.Dockerfile b/image/rhel/konflux.Dockerfile index 62a76a3be257b..ed54e8c39773b 100644 --- a/image/rhel/konflux.Dockerfile +++ b/image/rhel/konflux.Dockerfile @@ -1,7 +1,7 @@ ARG PG_VERSION=15 -FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:527782f4a0270f786192281f68d0374f4a21b3ab759643eee4bfcafb6f539468 AS go-builder +FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:aa03597ee8c7594ffecef5cbb6a0f059d362259d2a41225617b27ec912a3d0d3 AS go-builder RUN dnf -y install --allowerasing jq @@ -20,7 +20,7 @@ ENV CI=1 # TODO(ROX-13200): make sure roxctl cli is built without running go mod tidy. # CLI builds are without strictfipsruntime (and CGO_ENABLED is set to 0) because these binaries are for user download and use outside the cluster. -RUN make cli-build +RUN make roxctl-build ENV CGO_ENABLED=1 # TODO(ROX-27054): Remove the redundant strictfipsruntime option if one is found to be so. @@ -37,7 +37,7 @@ RUN mkdir -p image/rhel/docs/api/v1 && \ RUN make copy-go-binaries-to-image-dir -FROM registry.access.redhat.com/ubi9/nodejs-20:latest@sha256:71a3810707370f30bc0958aea14c3a5af564a3962ae0819bf16fdde7df9b4378 AS ui-builder +FROM registry.access.redhat.com/ubi9/nodejs-20:latest@sha256:89d0be288e9e76dc42bb2b1f76cd9cc619dde6e5e28c05cfeb3dcf4249b55450 AS ui-builder WORKDIR /go/src/github.com/stackrox/rox/app @@ -59,7 +59,7 @@ ENV UI_PKG_INSTALL_EXTRA_ARGS="--ignore-scripts" RUN make -C ui build -FROM registry.access.redhat.com/ubi8/ubi-minimal:latest@sha256:a670c5b613280e17a666c858c9263a50aafe1a023a8d5730c7a83cb53771487b +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest@sha256:48adecc91f276734fa51987bc2203a31db9ba87a512c436c0a3fcac53135378d ARG PG_VERSION diff --git a/image/roxctl/konflux.Dockerfile b/image/roxctl/konflux.Dockerfile index 568001aed31c8..310f7e42fb125 100644 --- a/image/roxctl/konflux.Dockerfile +++ b/image/roxctl/konflux.Dockerfile @@ -4,7 +4,7 @@ # - https://issues.redhat.com/browse/RHTAPBUGS-864 - deprecated-base-image-check behaves incorrectly. # - https://issues.redhat.com/browse/RHTAPBUGS-865 - openshift-golang-builder is not considered to be a valid base image. # -FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:527782f4a0270f786192281f68d0374f4a21b3ab759643eee4bfcafb6f539468 AS builder +FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:aa03597ee8c7594ffecef5cbb6a0f059d362259d2a41225617b27ec912a3d0d3 AS builder WORKDIR /go/src/github.com/stackrox/rox/app @@ -26,7 +26,7 @@ RUN RACE=0 CGO_ENABLED=1 GOOS=linux GOARCH=$(go env GOARCH) scripts/go-build.sh cp bin/linux_$(go env GOARCH)/roxctl image/bin/roxctl -FROM registry.access.redhat.com/ubi8/ubi-minimal:latest@sha256:a670c5b613280e17a666c858c9263a50aafe1a023a8d5730c7a83cb53771487b +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest@sha256:48adecc91f276734fa51987bc2203a31db9ba87a512c436c0a3fcac53135378d COPY --from=builder /go/src/github.com/stackrox/rox/app/image/bin/roxctl /usr/bin/roxctl diff --git a/image/templates/helm/stackrox-secured-cluster/internal/config-shape.yaml b/image/templates/helm/stackrox-secured-cluster/internal/config-shape.yaml index d4c78a88223ca..8c6da732ab99e 100644 --- a/image/templates/helm/stackrox-secured-cluster/internal/config-shape.yaml +++ b/image/templates/helm/stackrox-secured-cluster/internal/config-shape.yaml @@ -134,8 +134,8 @@ collector: complianceImagePullPolicy: null # string complianceResources: null # string | dict nodeScanningResources: null # string | dict - sfaEnabled: null # bool - sfaScanningResources: null # string | dict + famEnabled: null # bool + famResources: null # string | dict serviceTLS: cert: null # string key: null # string diff --git a/image/templates/helm/stackrox-secured-cluster/internal/defaults/40-resources.yaml b/image/templates/helm/stackrox-secured-cluster/internal/defaults/40-resources.yaml index 3a3ec77d3ad8e..1c7672394c9ce 100644 --- a/image/templates/helm/stackrox-secured-cluster/internal/defaults/40-resources.yaml +++ b/image/templates/helm/stackrox-secured-cluster/internal/defaults/40-resources.yaml @@ -43,11 +43,10 @@ collector: memory: "500Mi" cpu: "1" - sfaResources: - resources: - requests: - memory: "320Mi" - cpu: "50m" - limits: - memory: "1Gi" - cpu: "750m" + famResources: + requests: + memory: "320Mi" + cpu: "50m" + limits: + memory: "1Gi" + cpu: "750m" diff --git a/image/templates/helm/stackrox-secured-cluster/internal/expandables.yaml b/image/templates/helm/stackrox-secured-cluster/internal/expandables.yaml index 1bbead90788f6..4c5ebcc9ae580 100644 --- a/image/templates/helm/stackrox-secured-cluster/internal/expandables.yaml +++ b/image/templates/helm/stackrox-secured-cluster/internal/expandables.yaml @@ -28,7 +28,7 @@ collector: resources: true complianceResources: true nodeScanningResources: true - sfaResources: true + famResources: true nodeSelector: true scanner: resources: true diff --git a/image/templates/helm/stackrox-secured-cluster/templates/collector.yaml.htpl b/image/templates/helm/stackrox-secured-cluster/templates/collector.yaml.htpl index 27f318e8ccc9b..af6e5d8c35d14 100644 --- a/image/templates/helm/stackrox-secured-cluster/templates/collector.yaml.htpl +++ b/image/templates/helm/stackrox-secured-cluster/templates/collector.yaml.htpl @@ -110,7 +110,7 @@ spec: [<- if .FeatureFlags.ROX_SENSITIVE_FILE_ACTIVITY >] - {{- if ._rox.collector.sfaEnabled }} + {{- if ._rox.collector.famEnabled }} - name: fact image: {{ quote ._rox.image.fact.fullRef }} imagePullPolicy: {{ ._rox.fact.imagePullPolicy }} @@ -133,7 +133,7 @@ spec: value: "/etc/ssh/sshd_config:/etc/sudoers:/etc/passwd:/etc/shadow" {{- include "srox.envVars" (list . "daemonset" "collector" "fact") | nindent 8 }} resources: - {{- ._rox.collector._sfaResources | nindent 10 }} + {{- ._rox.collector._famResources | nindent 10 }} securityContext: capabilities: drop: diff --git a/operator/Dockerfile b/operator/Dockerfile index fbc959f61815b..0ebaa95528713 100644 --- a/operator/Dockerfile +++ b/operator/Dockerfile @@ -2,7 +2,7 @@ ARG roxpath=/workspace/src/github.com/stackrox/rox ARG TARGET_ARCH=amd64 -FROM registry.access.redhat.com/ubi9/go-toolset:1.25 AS builder +FROM --platform=$BUILDPLATFORM registry.access.redhat.com/ubi9/go-toolset:1.25 AS builder # Build the manager binary ARG TARGET_ARCH diff --git a/operator/Makefile b/operator/Makefile index 919cd8e57f205..53936dce09f31 100644 --- a/operator/Makefile +++ b/operator/Makefile @@ -343,7 +343,7 @@ build/Dockerfile.gen: Dockerfile .PHONY: docker-build docker-build: build/Dockerfile.gen smuggled-status-sh ## Build docker image with the operator. - DOCKER_BUILDKIT=1 BUILDKIT_PROGRESS=plain docker build \ + BUILDKIT_PROGRESS=plain ../scripts/docker-build.sh \ -t ${IMG} \ $(if $(GOARCH),--build-arg TARGET_ARCH=$(GOARCH)) \ -f $< \ @@ -429,7 +429,7 @@ upgrade-dirty-tag-via-olm: kuttl ACTIVATE_PYTHON = python3 -m venv bundle_helpers/.venv ;\ . bundle_helpers/.venv/bin/activate ;\ pip3 install --upgrade pip==21.3.1 setuptools==59.6.0 ;\ - pip3 install -r bundle_helpers/requirements-gha.txt + pip3 install -r bundle_helpers/requirements.txt .PHONY: bundle bundle: yq manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files. diff --git a/operator/README.md b/operator/README.md index 7855ac223b4ab..273efc6748165 100644 --- a/operator/README.md +++ b/operator/README.md @@ -133,7 +133,13 @@ The recommended approach is the following. $ make undeploy uninstall ``` -### Bundling +### Building and using the operator bundle + +*Note:* currently creating a bundle is only supported using the RH ACS branding (ROX-11744). +You need to have the following set before running most targets mentioned in this section. +```bash +$ export ROX_PRODUCT_BRANDING=RHACS_BRANDING +``` ```bash # Refresh bundle metadata. Make sure to check the diff and commit it. @@ -159,19 +165,20 @@ $ make bundle-test $ make bundle-test-image ``` -### Launch the operator on the cluster with OLM and the bundle +#### Launching the operator on the cluster with OLM and the bundle ```bash # 0. Get the operator-sdk program. $ make operator-sdk -# 1. Install OLM. +# 1. Install OLM, unless running on OpenShift. $ make olm-install # 2. Create a namespace for testing bundle. $ kubectl create ns bundle-test # 2. Create image pull secrets. +# You can skip this and the next patch step when using cluster from infra.rox.systems. # If the inner magic does not work, just provide --docker-username and --docker-password with your DockerHub creds. $ kubectl -n bundle-test create secret docker-registry my-opm-image-pull-secrets \ --docker-server=https://quay.io/v2/ \ @@ -283,7 +290,7 @@ Now the latest version (based off of `make tag`) can be installed like so: ROX_PRODUCT_BRANDING=RHACS_BRANDING make deploy-via-olm ``` -This installs the operator into the `rhacs-operator-system` namespace. +This installs the operator into the `stackrox-operator-system` namespace. This can be overridden with a `TEST_NAMESPACE` argument. The version can be overridden with a `VERSION` argument. diff --git a/operator/api/v1alpha1/securedcluster_types.go b/operator/api/v1alpha1/securedcluster_types.go index c878994795ea1..35b098d8fc6ba 100644 --- a/operator/api/v1alpha1/securedcluster_types.go +++ b/operator/api/v1alpha1/securedcluster_types.go @@ -266,9 +266,9 @@ type PerNodeSpec struct { //+operator-sdk:csv:customresourcedefinitions:type=spec,order=3,displayName="Node Scanning Settings" NodeInventory *ContainerSpec `json:"nodeInventory,omitempty"` - // Settings for the Sensitive File Activity container, which is responsible for file activity monitoring on the Node. - //+operator-sdk:csv:customresourcedefinitions:type=spec,order=4,displayName="SFA" - SFA *SFAContainerSpec `json:"sfa,omitempty"` + // Settings for the File Activity Monitoring container, which is responsible for monitoring file operations on the Node. + //+operator-sdk:csv:customresourcedefinitions:type=spec,order=4,displayName="File Activity Monitoring Settings" + FileActivityMonitoring *FAMContainerSpec `json:"fileActivityMonitoring,omitempty"` // To ensure comprehensive monitoring of your cluster activity, Red Hat Advanced Cluster Security // will run services on every node in the cluster, including tainted nodes by default. If you do @@ -370,28 +370,28 @@ type CollectorContainerSpec struct { ContainerSpec `json:",inline"` } -// SFAContainerSpec defines settings for the Sensitive File Activity agent container. -type SFAContainerSpec struct { - // Specifies whether Sensitive File Activity agent is deployed. +// FAMContainerSpec defines settings for the File Activity Monitoring container. +type FAMContainerSpec struct { + // Specifies whether File Activity Monitoring is deployed. // The default is: Disabled. - //+operator-sdk:csv:customresourcedefinitions:type=spec,order=1,displayName="SFA Agent" - Agent *DeploySFAAgent `json:"agent,omitempty"` + //+operator-sdk:csv:customresourcedefinitions:type=spec,order=1,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:select:Enabled", "urn:alm:descriptor:com.tectonic.ui:select:Disabled"} + Mode *FAMMode `json:"mode,omitempty"` //+operator-sdk:csv:customresourcedefinitions:type=spec,order=2 ContainerSpec `json:",inline"` } -// DeploySFAAgent is a type for values of spec.perNode.sfa.agent +// FAMMode is a type for values of spec.perNode.fileActivityMonitoring.mode // +kubebuilder:validation:Enum=Enabled;Disabled -type DeploySFAAgent string +type FAMMode string const ( - SFAAgentEnabled DeploySFAAgent = "Enabled" - SFAAgentDisabled DeploySFAAgent = "Disabled" + FileActivityMonitoringEnabled FAMMode = "Enabled" + FileActivityMonitoringDisabled FAMMode = "Disabled" ) -// Pointer returns the given DeploySFAAgent value as a pointer, needed in k8s resource structs. -func (v DeploySFAAgent) Pointer() *DeploySFAAgent { +// Pointer returns the given Mode value as a pointer, needed in k8s resource structs. +func (v FAMMode) Pointer() *FAMMode { return &v } diff --git a/operator/api/v1alpha1/zz_generated.deepcopy.go b/operator/api/v1alpha1/zz_generated.deepcopy.go index ad07c187331a0..4a5a71ac38d75 100644 --- a/operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/operator/api/v1alpha1/zz_generated.deepcopy.go @@ -947,6 +947,27 @@ func (in *ExposureRouteReencryptTLS) DeepCopy() *ExposureRouteReencryptTLS { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FAMContainerSpec) DeepCopyInto(out *FAMContainerSpec) { + *out = *in + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(FAMMode) + **out = **in + } + in.ContainerSpec.DeepCopyInto(&out.ContainerSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FAMContainerSpec. +func (in *FAMContainerSpec) DeepCopy() *FAMContainerSpec { + if in == nil { + return nil + } + out := new(FAMContainerSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GlobalMonitoring) DeepCopyInto(out *GlobalMonitoring) { *out = *in @@ -1296,9 +1317,9 @@ func (in *PerNodeSpec) DeepCopyInto(out *PerNodeSpec) { *out = new(ContainerSpec) (*in).DeepCopyInto(*out) } - if in.SFA != nil { - in, out := &in.SFA, &out.SFA - *out = new(SFAContainerSpec) + if in.FileActivityMonitoring != nil { + in, out := &in.FileActivityMonitoring, &out.FileActivityMonitoring + *out = new(FAMContainerSpec) (*in).DeepCopyInto(*out) } if in.TaintToleration != nil { @@ -1345,27 +1366,6 @@ func (in *ProcessBaselinesSpec) DeepCopy() *ProcessBaselinesSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SFAContainerSpec) DeepCopyInto(out *SFAContainerSpec) { - *out = *in - if in.Agent != nil { - in, out := &in.Agent, &out.Agent - *out = new(DeploySFAAgent) - **out = **in - } - in.ContainerSpec.DeepCopyInto(&out.ContainerSpec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SFAContainerSpec. -func (in *SFAContainerSpec) DeepCopy() *SFAContainerSpec { - if in == nil { - return nil - } - out := new(SFAContainerSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ScannerAnalyzerComponent) DeepCopyInto(out *ScannerAnalyzerComponent) { *out = *in diff --git a/operator/bundle/manifests/platform.stackrox.io_securedclusters.yaml b/operator/bundle/manifests/platform.stackrox.io_securedclusters.yaml index 51e189b4c716d..b7dbd79c3b7ae 100644 --- a/operator/bundle/manifests/platform.stackrox.io_securedclusters.yaml +++ b/operator/bundle/manifests/platform.stackrox.io_securedclusters.yaml @@ -819,31 +819,18 @@ spec: type: object type: object type: object - hostAliases: - description: HostAliases allows configuring additional hostnames - to resolve in the pod's hosts file. - items: - description: |- - HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the - pod's hosts file. - properties: - hostnames: - description: Hostnames for the above IP address. - items: - type: string - type: array - x-kubernetes-list-type: atomic - ip: - description: IP address of the host file entry. - type: string - required: - - ip - type: object - type: array - nodeInventory: - description: Settings for the Node-Inventory container, which - is responsible for scanning the Nodes' filesystem. + fileActivityMonitoring: + description: Settings for the File Activity Monitoring container, + which is responsible for monitoring file operations on the Node. properties: + mode: + description: |- + Specifies whether File Activity Monitoring is deployed. + The default is: Disabled. + enum: + - Enabled + - Disabled + type: string resources: description: |- Allows overriding the default resource settings for this component. Please consult the documentation @@ -906,18 +893,31 @@ spec: type: object type: object type: object - sfa: - description: Settings for the Sensitive File Activity container, - which is responsible for file activity monitoring on the Node. + hostAliases: + description: HostAliases allows configuring additional hostnames + to resolve in the pod's hosts file. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + description: IP address of the host file entry. + type: string + required: + - ip + type: object + type: array + nodeInventory: + description: Settings for the Node-Inventory container, which + is responsible for scanning the Nodes' filesystem. properties: - agent: - description: |- - Specifies whether Sensitive File Activity agent is deployed. - The default is: Disabled. - enum: - - Enabled - - Disabled - type: string resources: description: |- Allows overriding the default resource settings for this component. Please consult the documentation diff --git a/operator/bundle/manifests/rhacs-operator.clusterserviceversion.yaml b/operator/bundle/manifests/rhacs-operator.clusterserviceversion.yaml index 41743609ee1f5..c901c6988ed61 100644 --- a/operator/bundle/manifests/rhacs-operator.clusterserviceversion.yaml +++ b/operator/bundle/manifests/rhacs-operator.clusterserviceversion.yaml @@ -1407,10 +1407,10 @@ spec: for scanning the Nodes' filesystem. displayName: Node Scanning Settings path: perNode.nodeInventory - - description: Settings for the Sensitive File Activity container, which is - responsible for file activity monitoring on the Node. - displayName: SFA - path: perNode.sfa + - description: Settings for the File Activity Monitoring container, which is + responsible for monitoring file operations on the Node. + displayName: File Activity Monitoring Settings + path: perNode.fileActivityMonitoring - description: 'To ensure comprehensive monitoring of your cluster activity, Red Hat Advanced Cluster Security @@ -1470,25 +1470,28 @@ spec: path: perNode.compliance.resources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: 'Specifies whether File Activity Monitoring is deployed. + + The default is: Disabled.' + displayName: Mode + path: perNode.fileActivityMonitoring.mode + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:select:Enabled + - urn:alm:descriptor:com.tectonic.ui:select:Disabled - description: 'Allows overriding the default resource settings for this component. Please consult the documentation for an overview of default resource requirements and a sizing guide.' displayName: Resources - path: perNode.nodeInventory.resources + path: perNode.fileActivityMonitoring.resources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: 'Specifies whether Sensitive File Activity agent is deployed. - - The default is: Disabled.' - displayName: SFA Agent - path: perNode.sfa.agent - description: 'Allows overriding the default resource settings for this component. Please consult the documentation for an overview of default resource requirements and a sizing guide.' displayName: Resources - path: perNode.sfa.resources + path: perNode.nodeInventory.resources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: 'Should process baselines be automatically locked when the observation @@ -1858,13 +1861,13 @@ spec: \ back to Central. These services allow users to enforce policies and monitor\ \ your OpenShift and Kubernetes clusters. Secured Cluster Services come as two\ \ Deployments (Sensor and Admission Controller) and one DaemonSet (Collector).\n\ - \n**Console Plugin:** RHACS provides a dynamic plugin that displays vulnerability\ - \ management information in the OpenShift web console. Install a SecuredCluster\ - \ to deploy the plugin. Enable the plugin by selecting *Operators* > *Installed\ - \ Operators* or by modifying the console Operator configuration.\n**Important:**\ - \ The Console Plugin requires OpenShift 4.19 or later.\n\n### Central Services\ - \ Explained\n\n| Service | Deployment Type | Description\ - \ |\n| :------------------------------- | :-------------- | :--------------\ + \n**Console Plugin (Tech Preview):** RHACS provides a dynamic plugin that displays\ + \ vulnerability management information in the OpenShift web console. Install a\ + \ SecuredCluster to deploy the plugin. Enable the plugin by selecting *Operators*\ + \ > *Installed Operators* or by modifying the console Operator configuration.\n\ + **Important:** The Console Plugin requires OpenShift 4.19 or later.\n\n### Central\ + \ Services Explained\n\n| Service | Deployment Type |\ + \ Description |\n| :------------------------------- | :-------------- | :--------------\ \ |\n| Central | Deployment | Users interact with\ \ Red Hat Advanced Cluster Security through the user interface or APIs on Central.\ \ Central also sends notifications for violations and interacts with integrations.\ diff --git a/operator/bundle_helpers/.gitignore b/operator/bundle_helpers/.gitignore index dc4a262c3d60f..8bda2111e1e21 100644 --- a/operator/bundle_helpers/.gitignore +++ b/operator/bundle_helpers/.gitignore @@ -1,4 +1,5 @@ /__pycache__/ +# Remnants of the old way we pulled Python dependencies in the operator-bundle build. requirements-build.in pip_find_builddeps.py diff --git a/operator/bundle_helpers/README.md b/operator/bundle_helpers/README.md deleted file mode 100644 index aa8f2a94c2af7..0000000000000 --- a/operator/bundle_helpers/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Bundle Helpers - -For hermetic builds with Konflux, we need to provide the full list of resolved dependencies in `requirements.txt`. -The dependency source files will be prefetched with Cachi2 and made available to the container image build. -Follow the procedure below after any dependencies change for successful builds in Konflux. - -## Prepare the fully resolved requirements files for Cachi2 - -### Prerequisite - -Run the steps inside a container of the same image as the [operator-bundle builder stage](../konflux.bundle.Dockerfile). - -```bash -docker run -it -v "$(git rev-parse --show-toplevel)/operator/bundle_helpers:/src" --entrypoint /bin/bash -w /src registry.access.redhat.com/ubi9/python-39:latest -# inside the container -python3 -m pip install pip-tools -``` - -### Instructions - -1. Generate a fully resolved requirements.txt: - -```bash -pip-compile requirements.in --generate-hashes -``` - -2. Download pip_find_builddeps.py: - -```bash -curl -fO https://raw.githubusercontent.com/containerbuildsystem/cachito/master/bin/pip_find_builddeps.py -chmod +x pip_find_builddeps.py -``` - -3. Generate a fully resolved `requirements-build.txt`: - -```bash -./pip_find_builddeps.py requirements.txt \ - -o requirements-build.in - -pip-compile requirements-build.in --allow-unsafe --generate-hashes -``` - -4. Exit the container and commit the changes. - -For more information, consult the [Cachi2 docs](https://github.com/containerbuildsystem/cachi2/blob/main/docs/pip.md#building-from-source). - -### What does each requirements file do? - -* `requirements.in`: List of project dependencies. -* `requirements-gha.txt`: The list of project dependencies as required by the build process on GHA and locally. This file exists as a workaround due to a different Python version in this context. Any changes in this or the `requirements.in` file should be synced manually to `requirements-gha.txt`. This file will be deleted after ROX-26860. -* `requirements.txt`: Fully resolved list of all transitive project dependencies. -* `requirements-build.txt`: Fully resolved list of all dependencies required to _build_ the project dependencies from sources in Konflux. -* `requirements-build.in` (not commited): Intermediate result for the generation of `requirements.txt`. diff --git a/operator/bundle_helpers/requirements-build.txt b/operator/bundle_helpers/requirements-build.txt deleted file mode 100644 index 5f7bb0f4c1dc5..0000000000000 --- a/operator/bundle_helpers/requirements-build.txt +++ /dev/null @@ -1,86 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --allow-unsafe --generate-hashes requirements-build.in -# -cython==3.0.12 \ - --hash=sha256:0038c9bae46c459669390e53a1ec115f8096b2e4647ae007ff1bf4e6dee92806 \ - --hash=sha256:0faa5e39e5c8cdf6f9c3b1c3f24972826e45911e7f5b99cf99453fca5432f45e \ - --hash=sha256:120681093772bf3600caddb296a65b352a0d3556e962b9b147efcfb8e8c9801b \ - --hash=sha256:1e5eadef80143026944ea8f9904715a008f5108d1d644a89f63094cc37351e73 \ - --hash=sha256:25529ee948f44d9a165ff960c49d4903267c20b5edf2df79b45924802e4cca6e \ - --hash=sha256:2d53de996ed340e9ab0fc85a88aaa8932f2591a2746e1ab1c06e262bd4ec4be7 \ - --hash=sha256:3083465749911ac3b2ce001b6bf17f404ac9dd35d8b08469d19dc7e717f5877a \ - --hash=sha256:309c081057930bb79dc9ea3061a1af5086c679c968206e9c9c2ec90ab7cb471a \ - --hash=sha256:3109e1d44425a2639e9a677b66cd7711721a5b606b65867cb2d8ef7a97e2237b \ - --hash=sha256:34ce459808f7d8d5d4007bc5486fe50532529096b43957af6cbffcb4d9cc5c8d \ - --hash=sha256:36fcd584dae547de6f095500a380f4a0cce72b7a7e409e9ff03cb9beed6ac7a1 \ - --hash=sha256:398d4576c1e1f6316282aa0b4a55139254fbed965cba7813e6d9900d3092b128 \ - --hash=sha256:3ccd1228cc203b1f1b8a3d403f5a20ad1c40e5879b3fbf5851ce09d948982f2c \ - --hash=sha256:3e4fa855d98bc7bd6a2049e0c7dc0dcf595e2e7f571a26e808f3efd84d2db374 \ - --hash=sha256:43c48b5789398b228ea97499f5b864843ba9b1ab837562a9227c6f58d16ede8b \ - --hash=sha256:4aa255781b093a8401109d8f2104bbb2e52de7639d5896aefafddc85c30e0894 \ - --hash=sha256:4ee6f1ea1bead8e6cbc4e64571505b5d8dbdb3b58e679d31f3a84160cebf1a1a \ - --hash=sha256:54115fcc126840926ff3b53cfd2152eae17b3522ae7f74888f8a41413bd32f25 \ - --hash=sha256:563de1728c8e48869d2380a1b76bbc1b1b1d01aba948480d68c1d05e52d20c92 \ - --hash=sha256:57aefa6d3341109e46ec1a13e3a763aaa2cbeb14e82af2485b318194be1d9170 \ - --hash=sha256:5a93cbda00a5451175b97dea5a9440a3fcee9e54b4cba7a7dbcba9a764b22aec \ - --hash=sha256:5e5f17c48a4f41557fbcc7ee660ccfebe4536a34c557f553b6893c1b3c83df2d \ - --hash=sha256:629db614b9c364596d7c975fa3fb3978e8c5349524353dbe11429896a783fc1e \ - --hash=sha256:62b79dcc0de49efe9e84b9d0e2ae0a6fc9b14691a65565da727aa2e2e63c6a28 \ - --hash=sha256:63d840f2975e44d74512f8f34f1f7cb8121c9428e26a3f6116ff273deb5e60a2 \ - --hash=sha256:680f1d6ed4436ae94805db264d6155ed076d2835d84f20dcb31a7a3ad7f8668c \ - --hash=sha256:712c3f31adec140dc60d064a7f84741f50e2c25a8edd7ae746d5eb4d3ef7072a \ - --hash=sha256:731d719423e041242c9303c80cae4327467299b90ffe62d4cc407e11e9ea3160 \ - --hash=sha256:75c5acd40b97cff16fadcf6901a91586cbca5dcdba81f738efaf1f4c6bc8dccb \ - --hash=sha256:77d48f2d4bab9fe1236eb753d18f03e8b2619af5b6f05d51df0532a92dfb38ab \ - --hash=sha256:7cffc3464f641c8d0dda942c7c53015291beea11ec4d32421bed2f13b386b819 \ - --hash=sha256:86c304b20bd57c727c7357e90d5ba1a2b6f1c45492de2373814d7745ef2e63b4 \ - --hash=sha256:879ae9023958d63c0675015369384642d0afb9c9d1f3473df9186c42f7a9d265 \ - --hash=sha256:8ab9f5198af74eb16502cc143cdde9ca1cbbf66ea2912e67440dd18a36e3b5fa \ - --hash=sha256:8c9efe9a0895abee3cadfdad4130b30f7b5e57f6e6a51ef2a44f9fc66a913880 \ - --hash=sha256:8d32856716c369d01f2385ad9177cdd1a11079ac89ea0932dc4882de1aa19174 \ - --hash=sha256:8ee841c0e114efa1e849c281ac9b8df8aa189af10b4a103b1c5fd71cbb799679 \ - --hash=sha256:90cf599372c5a22120609f7d3a963f17814799335d56dd0dcf8fe615980a8ae1 \ - --hash=sha256:9f8c48748a9c94ea5d59c26ab49ad0fad514d36f894985879cf3c3ca0e600bf4 \ - --hash=sha256:a4032e48d4734d2df68235d21920c715c451ac9de15fa14c71b378e8986b83be \ - --hash=sha256:a7fec4f052b8fe173fe70eae75091389955b9a23d5cec3d576d21c5913b49d47 \ - --hash=sha256:af081838b0f9e12a83ec4c3809a00a64c817f489f7c512b0e3ecaf5f90a2a816 \ - --hash=sha256:b588c0a089a9f4dd316d2f9275230bad4a7271e5af04e1dc41d2707c816be44b \ - --hash=sha256:b988bb297ce76c671e28c97d017b95411010f7c77fa6623dd0bb47eed1aee1bc \ - --hash=sha256:ba67eee9413b66dd9fbacd33f0bc2e028a2a120991d77b5fd4b19d0b1e4039b9 \ - --hash=sha256:bee2717e5b5f7d966d0c6e27d2efe3698c357aa4d61bb3201997c7a4f9fe485a \ - --hash=sha256:bfb75123dd4ff767baa37d7036da0de2dfb6781ff256eef69b11b88b9a0691d1 \ - --hash=sha256:c0b91c7ebace030dd558ea28730de8c580680b50768e5af66db2904a3716c3e3 \ - --hash=sha256:c151082884be468f2f405645858a857298ac7f7592729e5b54788b5c572717ba \ - --hash=sha256:c1879c073e2b34924ce9b7ca64c212705dcc416af4337c45f371242b2e5f6d32 \ - --hash=sha256:c3238a29f37999e27494d120983eca90d14896b2887a0bd858a381204549137a \ - --hash=sha256:d3a8f81980ffbd74e52f9186d8f1654e347d0c44bfea6b5997028977f481a179 \ - --hash=sha256:d4b70fc339adba1e2111b074ee6119fe9fd6072c957d8597bce9a0dd1c3c6784 \ - --hash=sha256:d6945694c5b9170cfbd5f2c0d00ef7487a2de7aba83713a64ee4ebce7fad9e05 \ - --hash=sha256:d6c6cd6a75c8393e6805d17f7126b96a894f310a1a9ea91c47d141fb9341bfa8 \ - --hash=sha256:dcdc3e5d4ce0e7a4af6903ed580833015641e968d18d528d8371e2435a34132c \ - --hash=sha256:dfdbea486e702c328338314adb8e80f5f9741f06a0ae83aaec7463bc166d12e8 \ - --hash=sha256:e62564457851db1c40399bd95a5346b9bb99e17a819bf583b362f418d8f3457a \ - --hash=sha256:ea3a0e19ab77266c738aa110684a753a04da4e709472cadeff487133354d6ab8 \ - --hash=sha256:ebc24609613fa06d0d896309f7164ba168f7e8d71c1e490ed2a08d23351c3f41 \ - --hash=sha256:f39640f8df0400cde6882e23c734f15bb8196de0a008ae5dc6c8d1ec5957d7c8 \ - --hash=sha256:fe030d4a00afb2844f5f70896b7f2a1a0d7da09bf3aa3d884cbe5f73fff5d310 \ - --hash=sha256:feb86122a823937cc06e4c029d80ff69f082ebb0b959ab52a5af6cdd271c5dc3 \ - --hash=sha256:ff5c0b6a65b08117d0534941d404833d516dac422eee88c6b4fd55feb409a5ed - # via -r requirements-build.in -flit-core==3.10.1 \ - --hash=sha256:66e5b87874a0d6e39691f0e22f09306736b633548670ad3c09ec9db03c5662f7 \ - --hash=sha256:cb31a76e8b31ad3351bb89e531f64ef2b05d1e65bd939183250bf81ddf4922a8 - # via -r requirements-build.in -wheel==0.45.1 \ - --hash=sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729 \ - --hash=sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248 - # via -r requirements-build.in - -# The following packages are considered to be unsafe in a requirements file: -setuptools==78.1.1 \ - --hash=sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561 \ - --hash=sha256:fcc17fd9cd898242f6b4adfaca46137a9edef687f43e6f78469692a5e70d851d - # via -r requirements-build.in diff --git a/operator/bundle_helpers/requirements-gha.txt b/operator/bundle_helpers/requirements-gha.txt deleted file mode 100644 index a513b595dfd02..0000000000000 --- a/operator/bundle_helpers/requirements-gha.txt +++ /dev/null @@ -1,5 +0,0 @@ -# TODO(ROX-26860): remove this file and use just requirements.txt once the GHA operator build runs with Python 3.9. -# PyYAML > 6.0 requires Python > 3.6. -PyYAML==6.0 -# pytest==7.0.1 is the latest available for the quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 job container's Python. -pytest==7.0.1 diff --git a/operator/bundle_helpers/requirements.in b/operator/bundle_helpers/requirements.in deleted file mode 100644 index aa4d4d0668b61..0000000000000 --- a/operator/bundle_helpers/requirements.in +++ /dev/null @@ -1 +0,0 @@ -pyyaml==6.0.2 diff --git a/operator/bundle_helpers/requirements.txt b/operator/bundle_helpers/requirements.txt index 4184dd797496d..2bf4d90ed30a2 100644 --- a/operator/bundle_helpers/requirements.txt +++ b/operator/bundle_helpers/requirements.txt @@ -1,61 +1,4 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --generate-hashes requirements.in -# -pyyaml==6.0.2 \ - --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ - --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ - --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \ - --hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \ - --hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \ - --hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \ - --hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \ - --hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \ - --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \ - --hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \ - --hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \ - --hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \ - --hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \ - --hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \ - --hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \ - --hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \ - --hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \ - --hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \ - --hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \ - --hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \ - --hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \ - --hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \ - --hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \ - --hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \ - --hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \ - --hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \ - --hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \ - --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \ - --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \ - --hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \ - --hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \ - --hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \ - --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \ - --hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \ - --hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \ - --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \ - --hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \ - --hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \ - --hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \ - --hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \ - --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \ - --hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \ - --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ - --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ - --hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \ - --hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \ - --hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \ - --hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \ - --hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \ - --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \ - --hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \ - --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \ - --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4 - # via -r requirements.in +# PyYAML > 6.0 requires Python > 3.6. +PyYAML==6.0 +# pytest==7.0.1 is the latest available for the quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 job container's Python. +pytest==7.0.1 diff --git a/operator/config/crd/bases/platform.stackrox.io_securedclusters.yaml b/operator/config/crd/bases/platform.stackrox.io_securedclusters.yaml index 168d2f655024d..8a69dfecad4e2 100644 --- a/operator/config/crd/bases/platform.stackrox.io_securedclusters.yaml +++ b/operator/config/crd/bases/platform.stackrox.io_securedclusters.yaml @@ -817,31 +817,18 @@ spec: type: object type: object type: object - hostAliases: - description: HostAliases allows configuring additional hostnames - to resolve in the pod's hosts file. - items: - description: |- - HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the - pod's hosts file. - properties: - hostnames: - description: Hostnames for the above IP address. - items: - type: string - type: array - x-kubernetes-list-type: atomic - ip: - description: IP address of the host file entry. - type: string - required: - - ip - type: object - type: array - nodeInventory: - description: Settings for the Node-Inventory container, which - is responsible for scanning the Nodes' filesystem. + fileActivityMonitoring: + description: Settings for the File Activity Monitoring container, + which is responsible for monitoring file operations on the Node. properties: + mode: + description: |- + Specifies whether File Activity Monitoring is deployed. + The default is: Disabled. + enum: + - Enabled + - Disabled + type: string resources: description: |- Allows overriding the default resource settings for this component. Please consult the documentation @@ -904,18 +891,31 @@ spec: type: object type: object type: object - sfa: - description: Settings for the Sensitive File Activity container, - which is responsible for file activity monitoring on the Node. + hostAliases: + description: HostAliases allows configuring additional hostnames + to resolve in the pod's hosts file. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + description: IP address of the host file entry. + type: string + required: + - ip + type: object + type: array + nodeInventory: + description: Settings for the Node-Inventory container, which + is responsible for scanning the Nodes' filesystem. properties: - agent: - description: |- - Specifies whether Sensitive File Activity agent is deployed. - The default is: Disabled. - enum: - - Enabled - - Disabled - type: string resources: description: |- Allows overriding the default resource settings for this component. Please consult the documentation diff --git a/operator/config/flavors/development_build/kustomization.yaml b/operator/config/flavors/development_build/kustomization.yaml index 8b4912bf36879..30fa503ff29db 100644 --- a/operator/config/flavors/development_build/kustomization.yaml +++ b/operator/config/flavors/development_build/kustomization.yaml @@ -1,11 +1,8 @@ # Adds namespace to all resources. namespace: rhacs-operator-system -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. +# Value of this field is prepended to the names of all resources. +# Note that it should also match with the prefix (text before '-system') of the namespace field above. namePrefix: rhacs-operator- # Labels to add to all resources and selectors. diff --git a/operator/config/flavors/opensource/kustomization.yaml b/operator/config/flavors/opensource/kustomization.yaml index 23a08b1957b9d..9f187bf137186 100644 --- a/operator/config/flavors/opensource/kustomization.yaml +++ b/operator/config/flavors/opensource/kustomization.yaml @@ -1,11 +1,8 @@ # Adds namespace to all resources. namespace: stackrox-operator-system -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. +# Value of this field is prepended to the names of all resources. +# Note that it should also match with the prefix (text before '-system') of the namespace field above. namePrefix: stackrox-operator- # Labels to add to all resources and selectors. diff --git a/operator/config/manifests/bases/rhacs-operator.clusterserviceversion.yaml b/operator/config/manifests/bases/rhacs-operator.clusterserviceversion.yaml index 967ab805dcf3f..d115a22e3eb79 100644 --- a/operator/config/manifests/bases/rhacs-operator.clusterserviceversion.yaml +++ b/operator/config/manifests/bases/rhacs-operator.clusterserviceversion.yaml @@ -1006,10 +1006,13 @@ spec: - urn:alm:descriptor:com.tectonic.ui:select:CORE_BPF - urn:alm:descriptor:com.tectonic.ui:select:NoCollection - description: |- - Specifies whether Sensitive File Activity agent is deployed. + Specifies whether File Activity Monitoring is deployed. The default is: Disabled. - displayName: SFA Agent - path: perNode.sfa.agent + displayName: Mode + path: perNode.fileActivityMonitoring.mode + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:select:Enabled + - urn:alm:descriptor:com.tectonic.ui:select:Disabled - description: |- Should process baselines be automatically locked when the observation period (1 hour by default) ends. The default is: Disabled. @@ -1225,10 +1228,10 @@ spec: When Optional is false, and the specified resource does not exist in the output manifests, an error will be thrown. displayName: Optional path: overlays[0].optional - - description: Settings for the Sensitive File Activity container, which is - responsible for file activity monitoring on the Node. - displayName: SFA - path: perNode.sfa + - description: Settings for the File Activity Monitoring container, which is + responsible for monitoring file operations on the Node. + displayName: File Activity Monitoring Settings + path: perNode.fileActivityMonitoring - description: 'The default is: 5.' displayName: Autoscaling Maximum Replicas path: scanner.analyzer.scaling.maxReplicas @@ -1354,14 +1357,14 @@ spec: Allows overriding the default resource settings for this component. Please consult the documentation for an overview of default resource requirements and a sizing guide. displayName: Resources - path: perNode.nodeInventory.resources + path: perNode.fileActivityMonitoring.resources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: |- Allows overriding the default resource settings for this component. Please consult the documentation for an overview of default resource requirements and a sizing guide. displayName: Resources - path: perNode.sfa.resources + path: perNode.nodeInventory.resources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: |- @@ -1587,7 +1590,7 @@ spec: 2. **Secured Cluster Services** - Secured cluster services are placed on each cluster you manage and report back to Central. These services allow users to enforce policies and monitor your OpenShift and Kubernetes clusters. Secured Cluster Services come as two Deployments (Sensor and Admission Controller) and one DaemonSet (Collector). - **Console Plugin:** RHACS provides a dynamic plugin that displays vulnerability management information in the OpenShift web console. Install a SecuredCluster to deploy the plugin. Enable the plugin by selecting *Operators* > *Installed Operators* or by modifying the console Operator configuration. + **Console Plugin (Tech Preview):** RHACS provides a dynamic plugin that displays vulnerability management information in the OpenShift web console. Install a SecuredCluster to deploy the plugin. Enable the plugin by selecting *Operators* > *Installed Operators* or by modifying the console Operator configuration. **Important:** The Console Plugin requires OpenShift 4.19 or later. ### Central Services Explained diff --git a/operator/config/ui-metadata/bases/rhacs-operator.clusterserviceversion.yaml b/operator/config/ui-metadata/bases/rhacs-operator.clusterserviceversion.yaml index 996390bf38243..e14968528e1ee 100644 --- a/operator/config/ui-metadata/bases/rhacs-operator.clusterserviceversion.yaml +++ b/operator/config/ui-metadata/bases/rhacs-operator.clusterserviceversion.yaml @@ -65,7 +65,7 @@ spec: 2. **Secured Cluster Services** - Secured cluster services are placed on each cluster you manage and report back to Central. These services allow users to enforce policies and monitor your OpenShift and Kubernetes clusters. Secured Cluster Services come as two Deployments (Sensor and Admission Controller) and one DaemonSet (Collector). - **Console Plugin:** RHACS provides a dynamic plugin that displays vulnerability management information in the OpenShift web console. Install a SecuredCluster to deploy the plugin. Enable the plugin by selecting *Operators* > *Installed Operators* or by modifying the console Operator configuration. + **Console Plugin (Tech Preview):** RHACS provides a dynamic plugin that displays vulnerability management information in the OpenShift web console. Install a SecuredCluster to deploy the plugin. Enable the plugin by selecting *Operators* > *Installed Operators* or by modifying the console Operator configuration. **Important:** The Console Plugin requires OpenShift 4.19 or later. ### Central Services Explained diff --git a/operator/install/README.md b/operator/install/README.md index 6911f515765cc..661b05921eafc 100644 --- a/operator/install/README.md +++ b/operator/install/README.md @@ -21,7 +21,7 @@ kubectl rollout status deployment -n stackrox-operator-system stackrox-operator- ## Where to go from here? -Once the operator is running, to actually deploy StackRox you need to create a `Central` and a `SecuredCluster` custom resource. +Once the operator is running, to actually deploy StackRox you need to create a `Central` and/or a `SecuredCluster` custom resource. Please have a look at the [samples](../config/samples) directory. Before applying the `SecuredCluster` CR you need to retrieve from central and apply on the cluster an init bundle or cluster registration secret. @@ -39,11 +39,11 @@ You may encounter a few references to RH ACS when using the operator in places s - the `UserAgent` header used by the operator controller when talking to the kube API server - central web UI when generating init bundles or cluster registration secrets -We hope to clean these up in the next release. +These will be cleaned up in a future release. ## How was this manifest created? ```shell -BUILD_TAG=4.10.0 ROX_PRODUCT_BRANDING=STACKROX_BRANDING make -C operator/ build-installer +BUILD_TAG=4.10 ROX_PRODUCT_BRANDING=STACKROX_BRANDING make -C operator/ build-installer cp operator/dist/install.yaml operator/install/manifest.yaml ``` diff --git a/operator/install/manifest.yaml b/operator/install/manifest.yaml index 363bcc35cbe5f..b742b25d9913c 100644 --- a/operator/install/manifest.yaml +++ b/operator/install/manifest.yaml @@ -2052,8 +2052,8 @@ spec: description: |- Can be specified as "Enabled" or "Disabled". If this field is not specified, the following defaulting takes place: - * for new installations, Scanner V4 is enabled starting with ACS 4.8; - * for upgrades to 4.8 from previous releases, Scanner V4 is disabled. + * for upgrades to 4.8 from previous releases, the default is: Disabled; + * for new installations starting with ACS 4.8, the default is: Enabled. enum: - Default - Enabled @@ -2239,8 +2239,8 @@ spec: enforcement: description: |- Set to Disabled to disable policy enforcement for the admission controller. This is not recommended. - On new deployments starting with version 4.9, defaults to Enabled. - On old deployments, defaults to Enabled if at least one of listenOnCreates or listenOnUpdates is true. + On upgrades to 4.9 from previous releases, defaults to Enabled only if at least one of listenOnCreates or listenOnUpdates is true. + On new deployments starting with version 4.9, the default is: Enabled. enum: - Enabled - Disabled @@ -3062,13 +3062,13 @@ spec: type: object type: object type: object - sfa: - description: Settings for the Sensitive File Activity container, - which is responsible for file activity monitoring on the Node. + fileActivityMonitoring: + description: Settings for the File Activity Monitoring container, + which is responsible for monitoring file operations on the Node. properties: - agent: + mode: description: |- - Specifies whether Sensitive File Activity agent is deployed. + Specifies whether File Activity Monitoring is deployed. The default is: Disabled. enum: - Enabled @@ -3845,10 +3845,14 @@ spec: type: object scannerComponent: description: |- - If you want to enable the Scanner V4 component set this to "AutoSense" + If you want to enable the Scanner V4 component set this to "AutoSense". + A value of "AutoSense" means that Scanner V4 should be installed, + unless there is a Central resource in the same namespace. + In that case typically a central Scanner V4 will be deployed as a component of Central. + A value of "Disabled" means that Scanner V4 should not be installed. If this field is not specified or set to "Default", the following defaulting takes place: - * for new installations, Scanner V4 is enabled starting with ACS 4.8; - * for upgrades to 4.8 from previous releases, Scanner V4 is disabled. + * for upgrades to 4.8 from previous releases, the default is: Disabled; + * for new installations starting with ACS 4.8, the default is: AutoSense. enum: - Default - AutoSense @@ -4599,7 +4603,7 @@ spec: resourceFieldRef: containerName: manager resource: limits.memory - image: quay.io/stackrox-io/stackrox-operator:4.10.0 + image: quay.io/stackrox-io/stackrox-operator:4.10 livenessProbe: httpGet: path: /healthz diff --git a/operator/internal/central/extensions/common_test.go b/operator/internal/central/extensions/common_test.go index d2745ec052111..cbbfc5cb21310 100644 --- a/operator/internal/central/extensions/common_test.go +++ b/operator/internal/central/extensions/common_test.go @@ -287,9 +287,13 @@ func verifyCertMatchesCAHash(t *testing.T, secretData types.SecretDataMap, cache return } + if secondaryCAPEM, hasSecondaryCA := secretData[mtls.SecondaryCACertFileName]; hasSecondaryCA { + caPEM = append(caPEM, secondaryCAPEM...) + } + secretCAHash := confighash.ComputeCAHash(caPEM) assert.Equal(t, secretCAHash, cachedCAHash, - "CA hash in RenderCache should match the CA certificate in secret %s", secretName) + "CA hash in RenderCache should match the CA certificate(s) in secret %s", secretName) } func verifySecretsMatch( diff --git a/operator/internal/central/extensions/reconcile_tls.go b/operator/internal/central/extensions/reconcile_tls.go index 7fde1b2a93a7f..ed383ac1754b9 100644 --- a/operator/internal/central/extensions/reconcile_tls.go +++ b/operator/internal/central/extensions/reconcile_tls.go @@ -1,6 +1,7 @@ package extensions import ( + "bytes" "context" "crypto/x509" "fmt" @@ -62,6 +63,7 @@ type createCentralTLSExtensionRun struct { *commonExtensions.SecretReconciliator ca mtls.CA // primary CA, used to issue Central-services certificates + secondaryCA mtls.CA // secondary CA, for CA rotation support caRotationAction carotation.Action centralObj *platform.Central currentTime time.Time @@ -108,8 +110,13 @@ func (r *createCentralTLSExtensionRun) Execute(ctx context.Context) error { } if r.ca != nil { - // Add the hash of the CA to the render cache for the pod template annotation post renderer - r.renderCache.SetCAHash(r.centralObj, confighash.ComputeCAHash(r.ca.CertPEM())) + // Add the hash of the CA(s) to the render cache for the pod template annotation post renderer. + caPEM := r.ca.CertPEM() + if r.secondaryCA != nil { + // Include secondary CA if present so that pods restart when it's added during CA rotation. + caPEM = append(caPEM, r.secondaryCA.CertPEM()...) + } + r.renderCache.SetCAHash(r.centralObj, confighash.ComputeCAHash(caPEM)) } return nil // reconcileInitBundleSecrets not called due to ROX-9023. TODO(ROX-9969): call after the init-bundle cert rotation stabilization. @@ -170,11 +177,22 @@ func (r *createCentralTLSExtensionRun) validateAndConsumeCentralTLSData(fileMap return errors.Wrap(err, "primary CA is not valid at the present time") } - rotationAction, err := r.determineCARotationAction(fileMap) - if err != nil { - return err + // Load secondary CA (its presence is optional). + r.secondaryCA, err = certgen.LoadSecondaryCAFromFileMap(fileMap) + if err != nil && !errors.Is(err, certgen.ErrNoCACert) { + return errors.Wrap(err, "loading secondary CA failed") + } + if r.secondaryCA != nil { + if err := r.secondaryCA.CheckProperties(); err != nil { + return errors.Wrap(err, "loaded secondary CA is invalid") + } + } + + var secondaryCACert *x509.Certificate + if r.secondaryCA != nil { + secondaryCACert = r.secondaryCA.Certificate() } - r.caRotationAction = rotationAction + r.caRotationAction = carotation.DetermineAction(r.ca.Certificate(), secondaryCACert, r.currentTime) if r.caRotationAction != carotation.NoAction { return errors.New("CA rotation action needed") } @@ -186,23 +204,6 @@ func (r *createCentralTLSExtensionRun) validateAndConsumeCentralTLSData(fileMap return nil } -func (r *createCentralTLSExtensionRun) determineCARotationAction(fileMap types.SecretDataMap) (carotation.Action, error) { - secondaryCA, err := certgen.LoadSecondaryCAFromFileMap(fileMap) - var secondaryCACert *x509.Certificate - // the presence of a secondary CA certificate is optional - if err != nil && !errors.Is(err, certgen.ErrNoCACert) { - return carotation.NoAction, errors.Wrap(err, "loading secondary CA failed") - } - if secondaryCA != nil { - if err := secondaryCA.CheckProperties(); err != nil { - return carotation.NoAction, errors.Wrap(err, "loaded secondary service CA certificate is invalid") - } - secondaryCACert = secondaryCA.Certificate() - } - - return carotation.DetermineAction(r.ca.Certificate(), secondaryCACert, r.currentTime), nil -} - func (r *createCentralTLSExtensionRun) generateCentralTLSData(old types.SecretDataMap) (types.SecretDataMap, error) { var ( err error @@ -223,11 +224,15 @@ func (r *createCentralTLSExtensionRun) generateCentralTLSData(old types.SecretDa } if r.caRotationAction != carotation.NoAction { - primaryCA, err := certgen.LoadCAFromFileMap(newFileMap) + r.ca, err = certgen.LoadCAFromFileMap(newFileMap) if err != nil { return nil, errors.Wrap(err, "reloading new primary CA failed") } - r.ca = primaryCA + + r.secondaryCA, err = certgen.LoadSecondaryCAFromFileMap(newFileMap) + if err != nil && !errors.Is(err, certgen.ErrNoCACert) { + return nil, errors.Wrap(err, "loading secondary CA after rotation action failed") + } } } @@ -385,6 +390,29 @@ func (r *createCentralTLSExtensionRun) validateServiceTLSData(serviceType storag if err := certgen.VerifyCACertInFileMap(fileMap, r.ca); err != nil { return err } + + if centralCARotationEnabled.BooleanSetting() { + if err := r.verifySecondaryCACertInFileMap(fileMap); err != nil { + return err + } + } + return nil +} + +func (r *createCentralTLSExtensionRun) verifySecondaryCACertInFileMap(fileMap types.SecretDataMap) error { + secondaryCACertPEM := fileMap[mtls.SecondaryCACertFileName] + if r.secondaryCA == nil { + if len(secondaryCACertPEM) > 0 { + return errors.New("unexpected secondary CA certificate in file map") + } + return nil + } + if len(secondaryCACertPEM) == 0 { + return errors.New("missing secondary CA certificate in file map") + } + if !bytes.Equal(secondaryCACertPEM, r.secondaryCA.CertPEM()) { + return errors.New("mismatching secondary CA certificate in file map") + } return nil } @@ -410,6 +438,10 @@ func (r *createCentralTLSExtensionRun) generateServiceTLSData(subj mtls.Subject, return err } certgen.AddCACertToFileMap(fileMap, r.ca) + + if centralCARotationEnabled.BooleanSetting() && r.secondaryCA != nil { + certgen.AddSecondaryCACertToFileMap(fileMap, r.secondaryCA) + } return nil } diff --git a/operator/internal/securedcluster/defaults/static.go b/operator/internal/securedcluster/defaults/static.go index 32f1e123a1a90..838e48280c0ff 100644 --- a/operator/internal/securedcluster/defaults/static.go +++ b/operator/internal/securedcluster/defaults/static.go @@ -21,8 +21,8 @@ var staticDefaults = platform.SecuredClusterSpec{ Collection: platform.CollectionCOREBPF.Pointer(), }, TaintToleration: platform.TaintTolerate.Pointer(), - SFA: &platform.SFAContainerSpec{ - Agent: platform.SFAAgentDisabled.Pointer(), + FileActivityMonitoring: &platform.FAMContainerSpec{ + Mode: platform.FileActivityMonitoringDisabled.Pointer(), }, }, AuditLogs: &platform.AuditLogsSpec{ diff --git a/operator/internal/securedcluster/values/translation/translation.go b/operator/internal/securedcluster/values/translation/translation.go index c6fd1f93e7cd6..e965f2d684b0f 100644 --- a/operator/internal/securedcluster/values/translation/translation.go +++ b/operator/internal/securedcluster/values/translation/translation.go @@ -420,7 +420,7 @@ func (t Translator) getCollectorValues(perNode *platform.PerNodeSpec) *translati cv.AddAllFrom(t.getCollectorContainerValues(perNode.Collector)) cv.AddAllFrom(t.getComplianceContainerValues(perNode.Compliance)) cv.AddAllFrom(t.getNodeInventoryContainerValues(perNode.NodeInventory)) - cv.AddAllFrom(t.getSFAContainerValues(perNode.SFA)) + cv.AddAllFrom(t.getFAMContainerValues(perNode.FileActivityMonitoring)) return &cv } @@ -476,22 +476,22 @@ func (t Translator) getNodeInventoryContainerValues(nodeInventory *platform.Cont return &cv } -func (t Translator) getSFAContainerValues(sfaContainerSpec *platform.SFAContainerSpec) *translation.ValuesBuilder { - if sfaContainerSpec == nil { +func (t Translator) getFAMContainerValues(famContainerSpec *platform.FAMContainerSpec) *translation.ValuesBuilder { + if famContainerSpec == nil { return nil } cv := translation.NewValuesBuilder() - switch *sfaContainerSpec.Agent { - case platform.SFAAgentEnabled: - cv.SetBoolValue("sfaEnabled", true) - case platform.SFAAgentDisabled: - cv.SetBoolValue("sfaEnabled", false) + switch *famContainerSpec.Mode { + case platform.FileActivityMonitoringEnabled: + cv.SetBoolValue("famEnabled", true) + case platform.FileActivityMonitoringDisabled: + cv.SetBoolValue("famEnabled", false) default: - return cv.SetError(errors.Errorf("invalid spec.perNode.sfa.agent setting %q", *sfaContainerSpec.Agent)) + return cv.SetError(errors.Errorf("invalid spec.perNode.fileActivityMonitoring.mode setting %q", *famContainerSpec.Mode)) } - cv.AddChild("sfaResources", translation.GetResources(sfaContainerSpec.Resources)) + cv.AddChild("famResources", translation.GetResources(famContainerSpec.Resources)) return &cv } diff --git a/operator/konflux.Dockerfile b/operator/konflux.Dockerfile index 15c11d92f57ae..541f22e124d2a 100644 --- a/operator/konflux.Dockerfile +++ b/operator/konflux.Dockerfile @@ -1,4 +1,4 @@ -FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:527782f4a0270f786192281f68d0374f4a21b3ab759643eee4bfcafb6f539468 AS builder +FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:aa03597ee8c7594ffecef5cbb6a0f059d362259d2a41225617b27ec912a3d0d3 AS builder WORKDIR /go/src/github.com/stackrox/rox/app @@ -17,7 +17,7 @@ ENV CI=1 GOFLAGS="" CGO_ENABLED=1 RUN GOOS=linux GOARCH=$(go env GOARCH) scripts/go-build-file.sh operator/cmd/main.go image/bin/operator -FROM registry.access.redhat.com/ubi8/ubi-minimal:latest@sha256:a670c5b613280e17a666c858c9263a50aafe1a023a8d5730c7a83cb53771487b +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest@sha256:48adecc91f276734fa51987bc2203a31db9ba87a512c436c0a3fcac53135378d ARG BUILD_TAG diff --git a/operator/konflux.bundle.Dockerfile b/operator/konflux.bundle.Dockerfile index e328144d2b31e..890496c6d2db1 100644 --- a/operator/konflux.bundle.Dockerfile +++ b/operator/konflux.bundle.Dockerfile @@ -1,11 +1,7 @@ -FROM registry.access.redhat.com/ubi9/python-39:latest@sha256:8392799f609b0de3f9a4640400d460f5e2563b2b6f09e6b5fe89a67adda75c6a AS builder +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest@sha256:48adecc91f276734fa51987bc2203a31db9ba87a512c436c0a3fcac53135378d AS builder -# Because 'default' user cannot create build/ directory and errrors like: -# mkdir: cannot create directory ‘build/’: Permission denied -USER root - -COPY ./operator/bundle_helpers/requirements.txt /tmp/requirements.txt -RUN pip3 install --no-cache-dir -r /tmp/requirements.txt +# This installs both PyYAML and Python. +RUN microdnf -y install python3.12-pyyaml COPY . /stackrox WORKDIR /stackrox/operator @@ -48,6 +44,10 @@ ARG RELATED_IMAGE_COLLECTOR ENV RELATED_IMAGE_COLLECTOR=$RELATED_IMAGE_COLLECTOR RUN echo "Checking required RELATED_IMAGE_COLLECTOR"; [[ "${RELATED_IMAGE_COLLECTOR}" != "" ]] +ARG RELATED_IMAGE_FACT +ENV RELATED_IMAGE_FACT=$RELATED_IMAGE_FACT +RUN echo "Checking required RELATED_IMAGE_FACT"; [[ "${RELATED_IMAGE_FACT}" != "" ]] + ARG RELATED_IMAGE_ROXCTL ENV RELATED_IMAGE_ROXCTL=$RELATED_IMAGE_ROXCTL RUN echo "Checking required RELATED_IMAGE_ROXCTL"; [[ "${RELATED_IMAGE_ROXCTL}" != "" ]] diff --git a/operator/tools/envtest/go.mod b/operator/tools/envtest/go.mod index 6586fc3461a54..e72e7bf2b7868 100644 --- a/operator/tools/envtest/go.mod +++ b/operator/tools/envtest/go.mod @@ -1,15 +1,17 @@ module github.com/stackrox/rox/operator/tools/envtest -go 1.25 +go 1.25.0 -require sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240215124517-56159419231e +require sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20260209172322-2053ba3d414e require ( - github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/zapr v1.2.4 // indirect - github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/text v0.12.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/zapr v1.3.0 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.1 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + golang.org/x/text v0.34.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/operator/tools/envtest/go.sum b/operator/tools/envtest/go.sum index e5e52d5bea292..cbf375b7a075c 100644 --- a/operator/tools/envtest/go.sum +++ b/operator/tools/envtest/go.sum @@ -1,97 +1,60 @@ -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y= +github.com/onsi/ginkgo/v2 v2.27.4/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240215124517-56159419231e h1:zlN3M47kIntFr5Z6qMOSMg8nO6lrywD94H29TPDZjZk= -sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240215124517-56159419231e/go.mod h1:TF/lVLWS+JNNaVqJuDDictY2hZSXSsIHCx4FClMvqFg= +k8s.io/apimachinery v0.36.0-alpha.1 h1:MrQLU+TD3A2/ywQiTHEJ5BEKKk3XHpy0RkT98V0XdKI= +k8s.io/apimachinery v0.36.0-alpha.1/go.mod h1:hQkG060WLAG1TIkYsu5lj3tb6YdNpKe5Zrr2UPGg+/k= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20260209172322-2053ba3d414e h1:DDMrrZMTI9XOXbEQ3FXH2UHlpCg8XbDD3YXJNb6TWn4= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20260209172322-2053ba3d414e/go.mod h1:IlbgWQkCYbpbkygXxnd/sLJWL9WQk9NvvVhkJCm5P7Q= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/pkg/baseimage/util.go b/pkg/baseimage/util.go new file mode 100644 index 0000000000000..f19bba9513cd8 --- /dev/null +++ b/pkg/baseimage/util.go @@ -0,0 +1,24 @@ +package baseimage + +import "github.com/stackrox/rox/generated/storage" + +func BaseImagesUpdated(prev, cur []*storage.BaseImageInfo) bool { + if len(prev) != len(cur) { + return true + } + + existing := make(map[string]int) + for _, p := range prev { + existing[p.GetBaseImageDigest()]++ + } + + for _, c := range cur { + digest := c.GetBaseImageDigest() + if count, ok := existing[digest]; !ok || count == 0 { + return true // Found a current digest or more occurrences than before + } + existing[digest]-- + } + + return false +} diff --git a/pkg/certgen/ca.go b/pkg/certgen/ca.go index 01a82ab1a2b94..a9c719338d4fa 100644 --- a/pkg/certgen/ca.go +++ b/pkg/certgen/ca.go @@ -80,6 +80,12 @@ func AddCACertToFileMap(fileMap map[string][]byte, ca mtls.CA) { fileMap[mtls.CACertFileName] = ca.CertPEM() } +// AddSecondaryCACertToFileMap adds the public secondary CA certificate to the file map. +// This is used for service TLS secrets that need to trust both CAs but should not have signing capability. +func AddSecondaryCACertToFileMap(fileMap map[string][]byte, ca mtls.CA) { + fileMap[mtls.SecondaryCACertFileName] = ca.CertPEM() +} + // VerifyCACertInFileMap verifies that the public CA certificate stored in the given file // map is the same as the given one. func VerifyCACertInFileMap(fileMap map[string][]byte, ca mtls.CA) error { diff --git a/pkg/features/list.go b/pkg/features/list.go index 1bf3a2d4e7823..3cfa019b415a8 100644 --- a/pkg/features/list.go +++ b/pkg/features/list.go @@ -114,7 +114,7 @@ var ( CVEFixTimestampCriteria = registerFeature("Enable grace period criteria based on CVE fix timestamp", "ROX_CVE_FIX_TIMESTAMP", enabled) // BaseImageDetection enables base image detection and management functionality. - BaseImageDetection = registerFeature("Enable base image detection and management functionality", "ROX_BASE_IMAGE_DETECTION") + BaseImageDetection = registerFeature("Enable base image detection and management functionality", "ROX_BASE_IMAGE_DETECTION", enabled) // DelegatedBaseImageScanning enables delegation of base image repository scanning to secured clusters. DelegatedBaseImageScanning = registerFeature("Enable delegated base image scanning to secured clusters", "ROX_DELEGATED_BASE_IMAGE_SCANNING") diff --git a/pkg/images/enricher/enricher.go b/pkg/images/enricher/enricher.go index da254d9f9c4ff..e102cb902fbae 100644 --- a/pkg/images/enricher/enricher.go +++ b/pkg/images/enricher/enricher.go @@ -140,12 +140,21 @@ type CVESuppressor interface { EnrichImageV2WithSuppressedCVEs(image *storage.ImageV2) } +// CVEInfoEnricher provides enrichment for CVE timing metadata (FixAvailableTimestamp and FirstSystemOccurrence). +type CVEInfoEnricher interface { + // EnrichImageWithCVEInfo enriches a V1 image's CVEs with timing metadata from the ImageCVEInfo lookup table. + EnrichImageWithCVEInfo(ctx context.Context, image *storage.Image) error + + // EnrichImageV2WithCVEInfo enriches a V2 image's CVEs with timing metadata from the ImageCVEInfo lookup table. + EnrichImageV2WithCVEInfo(ctx context.Context, image *storage.ImageV2) error +} + // TODO(ROX-30117): Remove this and use ImageGetterV2 after ImageV2 model is fully rolled out. // ImageGetter will be used to retrieve a specific image from the datastore. type ImageGetter func(ctx context.Context, id string) (*storage.Image, bool, error) // BaseImageGetter will be used to get base images of a given image -type BaseImageGetter func(ctx context.Context, layers []string) ([]*storage.BaseImageInfo, error) +type BaseImageGetter func(ctx context.Context, layers []string) ([]*storage.BaseImage, error) // SignatureIntegrationGetter will be used to retrieve all available signature integrations. type SignatureIntegrationGetter func(ctx context.Context) ([]*storage.SignatureIntegration, error) @@ -156,11 +165,12 @@ type signatureVerifierForIntegrations func(ctx context.Context, integrations []* // New returns a new ImageEnricher instance for the given subsystem. // (The subsystem is just used for Prometheus metrics.) -func New(cvesSuppressorV2 CVESuppressor, is integration.Set, subsystem pkgMetrics.Subsystem, metadataCache cache.ImageMetadata, baseImageGetter BaseImageGetter, +func New(cvesSuppressorV2 CVESuppressor, cveInfoEnricher CVEInfoEnricher, is integration.Set, subsystem pkgMetrics.Subsystem, metadataCache cache.ImageMetadata, baseImageGetter BaseImageGetter, imageGetter ImageGetter, healthReporter integrationhealth.Reporter, signatureIntegrationGetter SignatureIntegrationGetter, scanDelegator delegatedregistry.Delegator) ImageEnricher { enricher := &enricherImpl{ cvesSuppressorV2: cvesSuppressorV2, + cveInfoEnricher: cveInfoEnricher, integrations: is, // number of consecutive errors per registry or scanner to ascertain health of the integration diff --git a/pkg/images/enricher/enricher_impl.go b/pkg/images/enricher/enricher_impl.go index ab7492499560a..238f25d11cd1a 100644 --- a/pkg/images/enricher/enricher_impl.go +++ b/pkg/images/enricher/enricher_impl.go @@ -26,9 +26,11 @@ import ( "github.com/stackrox/rox/pkg/protoutils" registryTypes "github.com/stackrox/rox/pkg/registries/types" "github.com/stackrox/rox/pkg/sac" + "github.com/stackrox/rox/pkg/sac/resources" scannerTypes "github.com/stackrox/rox/pkg/scanners/types" "github.com/stackrox/rox/pkg/signatures" "github.com/stackrox/rox/pkg/sync" + pkgUtils "github.com/stackrox/rox/pkg/utils" scannerV1 "github.com/stackrox/scanner/generated/scanner/api/v1" "golang.org/x/time/rate" ) @@ -46,6 +48,7 @@ var ( type enricherImpl struct { cvesSuppressorV2 CVESuppressor + cveInfoEnricher CVEInfoEnricher integrations integration.Set errorsPerRegistry map[registryTypes.ImageRegistry]int32 @@ -81,6 +84,7 @@ func (e *enricherImpl) EnrichWithVulnerabilities(image *storage.Image, component }, noImageScannersErr } + e.enrichWithBaseImage(context.Background(), image) for _, imageScanner := range scanners.GetAll() { scanner := imageScanner.GetScanner() if vulnScanner, ok := scanner.(scannerTypes.ImageVulnerabilityGetter); ok { @@ -95,6 +99,14 @@ func (e *enricherImpl) EnrichWithVulnerabilities(image *storage.Image, component ScanResult: ScanNotDone, }, errors.Wrapf(err, "retrieving image vulnerabilities from %s [%s]", scanner.Name(), scanner.Type()) } + + // Enrich CVEs with timing metadata (FixAvailableTimestamp, FirstSystemOccurrence) + if e.cveInfoEnricher != nil { + if err := e.cveInfoEnricher.EnrichImageWithCVEInfo(context.Background(), image); err != nil { + log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) + } + } + e.cvesSuppressorV2.EnrichImageWithSuppressedCVEs(image) return EnrichmentResult{ @@ -164,6 +176,8 @@ func (e *enricherImpl) delegateEnrichImage(ctx context.Context, enrichCtx Enrich if exists && cachedImageIsValid(existingImg) { updated := e.updateImageWithExistingImage(image, existingImg, enrichCtx.FetchOpt) if updated { + // Image is cached, but we force base image detection in case base images tags were updated. + e.enrichWithBaseImage(ctx, image) e.cvesSuppressorV2.EnrichImageWithSuppressedCVEs(image) // Errors for signature verification will be logged, so we can safely ignore them for the time being. _, _ = e.enrichWithSignatureVerificationData(ctx, enrichCtx, image) @@ -184,6 +198,13 @@ func (e *enricherImpl) delegateEnrichImage(ctx context.Context, enrichCtx Enrich image.Reset() protocompat.Merge(image, scannedImage) + // Enrich CVEs with timing metadata (FixAvailableTimestamp, FirstSystemOccurrence) + if e.cveInfoEnricher != nil { + if err := e.cveInfoEnricher.EnrichImageWithCVEInfo(ctx, image); err != nil { + log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) + } + } + e.cvesSuppressorV2.EnrichImageWithSuppressedCVEs(image) return true, nil } @@ -223,6 +244,48 @@ func (e *enricherImpl) updateImageWithExistingImage(image *storage.Image, existi return e.useExistingScan(image, existingImage, option) } +func (e *enricherImpl) enrichWithBaseImage(ctx context.Context, image *storage.Image) { + if !features.BaseImageDetection.Enabled() { + return + } + if image.GetMetadata() == nil { + log.Warnw("Matching image with base images failed as there's no image metadata", + logging.ImageID(image.GetId()), + logging.String("image_name", image.GetName().GetFullName())) + return + } + layers := image.GetMetadata().GetLayerShas() + if len(layers) == 0 { + log.Warnw("Matching image with base images failed as there's no image layer SHAs", + logging.ImageID(image.GetId()), + logging.String("image_name", image.GetName().GetFullName())) + return + } + + adminCtx := sac.WithGlobalAccessScopeChecker(ctx, + sac.AllowFixedScopes( + sac.AccessModeScopeKeys(storage.Access_READ_ACCESS), + sac.ResourceScopeKeys(resources.ImageAdministration), + ), + ) + + matchedBaseImages, err := e.baseImageGetter(adminCtx, layers) + if err != nil { + log.Warnw("Matching image with base images failed", + logging.ImageID(image.GetId()), + logging.Err(err), + logging.String("image_name", image.GetName().GetFullName())) + return + } + + if len(matchedBaseImages) > 0 { + log.Debugw("Matching image with base images succeeded", + logging.ImageID(image.GetId()), + logging.String("image_name", image.GetName().GetFullName())) + image.BaseImageInfo = toBaseImageInfos(image.GetMetadata(), matchedBaseImages) + } +} + // EnrichImage enriches an image with the integration set present. func (e *enricherImpl) EnrichImage(ctx context.Context, enrichContext EnrichmentContext, image *storage.Image) (EnrichmentResult, error) { shouldDelegate, err := e.delegateEnrichImage(ctx, enrichContext, image) @@ -272,6 +335,9 @@ func (e *enricherImpl) EnrichImage(ctx context.Context, enrichContext Enrichment updated = updated || didUpdateMetadata + e.enrichWithBaseImage(ctx, image) + updated = updated || len(image.GetBaseImageInfo()) > 0 + // Update the image with existing values depending on the FetchOption provided or whether any are available. // This makes sure that we fetch any existing image only once from database. useExistingScanIfPossible := e.updateImageFromDatabase(ctx, image, enrichContext.FetchOpt) @@ -304,23 +370,19 @@ func (e *enricherImpl) EnrichImage(ctx context.Context, enrichContext Enrichment updated = updated || didUpdateSigVerificationData + // Enrich CVEs with timing metadata (FixAvailableTimestamp, FirstSystemOccurrence) + if e.cveInfoEnricher != nil { + if err := e.cveInfoEnricher.EnrichImageWithCVEInfo(ctx, image); err != nil { + log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) + } + } + e.cvesSuppressorV2.EnrichImageWithSuppressedCVEs(image) if !errorList.Empty() { errorList.AddError(delegateErr) } - if features.BaseImageDetection.Enabled() { - image.BaseImageInfo, err = e.baseImageGetter(ctx, image.GetMetadata().GetLayerShas()) - if err != nil { - log.Warnw("Matching image with base images", - logging.FromContext(ctx), - logging.ImageID(image.GetId()), - logging.Err(err), - logging.String("request_image", image.GetName().GetFullName())) - } - } - return EnrichmentResult{ ImageUpdated: updated, ScanResult: scanResult, @@ -1060,3 +1122,95 @@ func FillScanStats(i *storage.Image) { } } } + +// toBaseImageInfos converts matched BaseImage objects to BaseImageInfo for storage in the image. +// It computes the max layer index based on the first base image's metadata. +func toBaseImageInfos(metadata *storage.ImageMetadata, baseImages []*storage.BaseImage) []*storage.BaseImageInfo { + if len(baseImages) == 0 { + return nil + } + + // Verify all base images have the same layer count. + // If not, this indicates a bug in the matcher (e.g., returning nested base images). + firstLayerCount := len(baseImages[0].GetLayers()) + for _, bi := range baseImages[1:] { + if len(bi.GetLayers()) != firstLayerCount { + pkgUtils.Should(errors.Errorf( + "base images have inconsistent layer counts: %s has %d layers, %s has %d layers", + baseImages[0].GetId(), firstLayerCount, bi.GetId(), len(bi.GetLayers()))) + break + } + } + + maxIndex, err := resolveLayerBoundary(metadata, firstLayerCount) + if err != nil { + log.Warnw("Failed to resolve base image layer boundary, ignoring base image matches", + logging.String("base_image_id", baseImages[0].GetId()), + logging.Err(err)) + return nil + } + + infos := make([]*storage.BaseImageInfo, 0, len(baseImages)) + for _, bi := range baseImages { + infos = append(infos, &storage.BaseImageInfo{ + BaseImageId: bi.GetId(), + BaseImageFullName: fmt.Sprintf("%s:%s", bi.GetRepository(), bi.GetTag()), + BaseImageDigest: bi.GetManifestDigest(), + Created: bi.GetCreated(), + MaxLayerIndex: int32(maxIndex), + }) + } + return infos +} + +// resolveLayerBoundary converts the base image's content layer count to the +// manifest index of its last layer. +// +// Components use manifest indices (which include empty layers), while base image +// layer counts exclude empty layers. This function bridges that gap by recounting +// the last layer index using empty layers when the image has V2 metadata. +func resolveLayerBoundary(metadata *storage.ImageMetadata, baseImageLayerCount int) (int, error) { + if baseImageLayerCount <= 0 { + return 0, errors.New("base image has no content layers") + } + + metadataLayers := metadata.GetV1().GetLayers() + layerIndex := baseImageLayerCount - 1 + + // If V1 layer metadata is available and V2 exists, account for empty + // layers by finding the actual manifest index. + if len(metadataLayers) > 0 && metadata.GetV2() != nil { + contentIndex := 0 + for i, l := range metadataLayers { + if l.GetEmpty() { + continue + } + if contentIndex == layerIndex { + return i, nil + } + contentIndex++ + } + return 0, fmt.Errorf( + "base image claims %d content layers but image only has %d non-empty layers", + baseImageLayerCount, contentIndex) + } + + // V1-only, or V2 without V1 layer metadata: content index equals manifest + // index directly. Use LayerShas for validation since it always contains + // content layers. + layerCount := len(metadata.GetLayerShas()) + if layerCount == 0 { + // This is not expected, but since an empty layer SHA list should never match, we + // attempt to check layer count based on V1 manifest layer count. + layerCount = len(metadataLayers) + } + if layerCount == 0 { + return 0, errors.New("invalid base image match: image has no layer metadata") + } + if layerIndex >= layerCount { + return 0, fmt.Errorf( + "invalid base image match: base image claims %d layers but image only has %d", + baseImageLayerCount, layerCount) + } + return layerIndex, nil +} diff --git a/pkg/images/enricher/enricher_impl_test.go b/pkg/images/enricher/enricher_impl_test.go index 6b6f5fcb17801..ba996156257c5 100644 --- a/pkg/images/enricher/enricher_impl_test.go +++ b/pkg/images/enricher/enricher_impl_test.go @@ -42,6 +42,10 @@ func imageGetterPanicOnCall(_ context.Context, _ string) (*storage.Image, bool, panic("Unexpected call to imageGetter") } +func emptyBaseImageGetter(_ context.Context, _ []string) ([]*storage.BaseImage, error) { + return nil, nil +} + var _ signatures.SignatureFetcher = (*fakeSigFetcher)(nil) var _ scannertypes.Scanner = (*fakeScanner)(nil) @@ -51,18 +55,30 @@ var ( _ types.ImageRegistry = (*fakeRegistryScanner)(nil) ) +type baseImageGetterMock struct { + callCount int +} + +func (m *baseImageGetterMock) get(_ context.Context, _ []string) ([]*storage.BaseImage, error) { + m.callCount++ + return nil, nil +} + func TestEnricherFlow(t *testing.T) { + t.Setenv(features.BaseImageDetection.EnvVar(), "true") + cases := []struct { - name string - ctx EnrichmentContext - inMetadataCache bool - shortCircuitRegistry bool - shortCircuitScanner bool - image *storage.Image - imageGetter ImageGetter - fsr *fakeRegistryScanner - result EnrichmentResult - errorExpected bool + name string + ctx EnrichmentContext + inMetadataCache bool + shortCircuitRegistry bool + shortCircuitScanner bool + image *storage.Image + imageGetter ImageGetter + fsr *fakeRegistryScanner + result EnrichmentResult + errorExpected bool + expectedBaseImageCalls int }{ { name: "nothing in the cache", @@ -74,8 +90,10 @@ func TestEnricherFlow(t *testing.T) { Id: "id", Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: true, requestedScan: true, @@ -84,6 +102,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "scan and metadata in both caches", @@ -95,6 +114,9 @@ func TestEnricherFlow(t *testing.T) { shortCircuitScanner: true, image: &storage.Image{ Id: "id", + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, imageGetter: imageGetterFromImage(&storage.Image{ Id: "id", @@ -110,6 +132,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data in both caches, but force refetch", @@ -121,8 +144,10 @@ func TestEnricherFlow(t *testing.T) { Id: "id", Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: true, requestedScan: true, @@ -131,6 +156,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: " data in both caches but force refetch use names", @@ -142,6 +168,9 @@ func TestEnricherFlow(t *testing.T) { Id: "id", Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, fsr: newFakeRegistryScanner(opts{ requestedMetadata: true, @@ -151,6 +180,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data in both caches but force refetch scans only", @@ -161,8 +191,10 @@ func TestEnricherFlow(t *testing.T) { image: &storage.Image{ Id: "id", Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: true, @@ -171,6 +203,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "set ScannerTypeHint to something not found in integrations", @@ -183,8 +216,8 @@ func TestEnricherFlow(t *testing.T) { image: &storage.Image{ Id: "id", Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, + // no need to pass metadata }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: false, @@ -193,6 +226,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanNotDone, }, + expectedBaseImageCalls: 0, }, { name: "set ScannerTypeHint to something found in integrations", @@ -204,8 +238,10 @@ func TestEnricherFlow(t *testing.T) { image: &storage.Image{ Id: "id", Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: true, @@ -214,6 +250,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data not in caches, and no external metadata", @@ -223,8 +260,7 @@ func TestEnricherFlow(t *testing.T) { inMetadataCache: false, shortCircuitRegistry: true, shortCircuitScanner: true, - image: &storage.Image{Id: "id"}, - + image: &storage.Image{Id: "id", Name: &storage.ImageName{Registry: "reg"}}, fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: false, @@ -233,6 +269,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: false, ScanResult: ScanNotDone, }, + expectedBaseImageCalls: 0, }, { name: "data not in cache, but image already has metadata and scan", @@ -244,7 +281,7 @@ func TestEnricherFlow(t *testing.T) { shortCircuitScanner: true, image: &storage.Image{ Id: "id", - Metadata: &storage.ImageMetadata{}, + Metadata: &storage.ImageMetadata{DataSource: &storage.DataSource{Id: "exists"}, LayerShas: []string{"SHA1"}}, Scan: &storage.ImageScan{}, Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, @@ -257,6 +294,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: false, ScanResult: ScanNotDone, }, + expectedBaseImageCalls: 1, }, { name: "data not in cache and ignore existing images", @@ -270,7 +308,10 @@ func TestEnricherFlow(t *testing.T) { Registry: "reg", }, Names: []*storage.ImageName{{Registry: "reg"}}, - Scan: &storage.ImageScan{}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, + Scan: &storage.ImageScan{}, }, imageGetter: imageGetterPanicOnCall, fsr: newFakeRegistryScanner(opts{ @@ -281,6 +322,7 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data in cache and ignore existing images", @@ -292,7 +334,7 @@ func TestEnricherFlow(t *testing.T) { shortCircuitScanner: false, image: &storage.Image{ Id: "id", - Metadata: &storage.ImageMetadata{}, + Metadata: &storage.ImageMetadata{DataSource: &storage.DataSource{Id: "exists"}, LayerShas: []string{"SHA1"}}, Scan: &storage.ImageScan{}, Name: &storage.ImageName{Registry: "reg"}, Names: []*storage.ImageName{{Registry: "reg"}}, @@ -306,18 +348,17 @@ func TestEnricherFlow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { ctrl := gomock.NewController(t) - fsr := newFakeRegistryScanner(opts{}) registrySet := registryMocks.NewMockSet(ctrl) registrySet.EXPECT().Get(gomock.Any()).Return(fsr).AnyTimes() - set := mocks.NewMockSet(ctrl) set.EXPECT().RegistrySet().AnyTimes().Return(registrySet) @@ -328,42 +369,48 @@ func TestEnricherFlow(t *testing.T) { scannerSet := scannerMocks.NewMockSet(ctrl) if !c.shortCircuitScanner { - scannerSet.EXPECT().IsEmpty().Return(false) + scannerSet.EXPECT().IsEmpty().Return(false).AnyTimes() scannerSet.EXPECT().GetAll().Return([]scannertypes.ImageScannerWithDataSource{fsr}).AnyTimes() - set.EXPECT().ScannerSet().Return(scannerSet) + set.EXPECT().ScannerSet().Return(scannerSet).AnyTimes() } mockReporter := reporterMocks.NewMockReporter(ctrl) mockReporter.EXPECT().UpdateIntegrationHealthAsync(gomock.Any()).AnyTimes() + mockBaseGetter := &baseImageGetterMock{} + enricherImpl := &enricherImpl{ cvesSuppressorV2: &fakeCVESuppressorV2{}, integrations: set, errorsPerScanner: map[scannertypes.ImageScannerWithDataSource]int32{fsr: 0}, errorsPerRegistry: map[types.ImageRegistry]int32{fsr: 0}, integrationHealthReporter: mockReporter, - metadataLimiter: rate.NewLimiter(rate.Every(50*time.Millisecond), 1), + metadataLimiter: rate.NewLimiter(rate.Inf, 0), metadataCache: newCache(), metrics: newMetrics(pkgMetrics.CentralSubsystem), imageGetter: emptyImageGetter, signatureIntegrationGetter: emptySignatureIntegrationGetter, signatureFetcher: &fakeSigFetcher{}, + baseImageGetter: mockBaseGetter.get, } - if c.inMetadataCache { - enricherImpl.metadataCache.Add(c.image.GetId(), c.image.GetMetadata()) + + if c.inMetadataCache && c.image != nil { + enricherImpl.metadataCache.Add(getRef(c.image), c.image.GetMetadata()) } if c.imageGetter != nil { enricherImpl.imageGetter = c.imageGetter } - result, err := enricherImpl.EnrichImage(emptyCtx, c.ctx, c.image) - if !c.errorExpected { - require.NoError(t, err) - } else { + + result, err := enricherImpl.EnrichImage(context.Background(), c.ctx, c.image) + + if c.errorExpected { require.Error(t, err) + } else { + require.NoError(t, err) } - assert.Equal(t, c.result, result) - assert.Equal(t, c.fsr, fsr) + assert.Equal(t, c.result, result) + assert.Equal(t, c.expectedBaseImageCalls, mockBaseGetter.callCount, "Mismatch in: %s", c.name) }) } } @@ -400,6 +447,7 @@ func TestCVESuppression(t *testing.T) { imageGetter: emptyImageGetter, signatureIntegrationGetter: emptySignatureIntegrationGetter, signatureFetcher: &fakeSigFetcher{}, + baseImageGetter: emptyBaseImageGetter, } img := &storage.Image{Id: "id", Name: &storage.ImageName{Registry: "reg"}, @@ -1080,9 +1128,14 @@ func TestDelegateEnrichImage(t *testing.T) { func TestEnrichImage_Delegate(t *testing.T) { deleEnrichCtx := EnrichmentContext{Delegable: true} + + // Track call counts + biMock := &baseImageGetterMock{} + e := enricherImpl{ cvesSuppressorV2: &fakeCVESuppressorV2{}, imageGetter: emptyImageGetter, + baseImageGetter: biMock.get, // Inject the tracker } var dele *delegatorMocks.MockDelegator @@ -1090,6 +1143,7 @@ func TestEnrichImage_Delegate(t *testing.T) { ctrl := gomock.NewController(t) dele = delegatorMocks.NewMockDelegator(ctrl) e.scanDelegator = dele + e.baseImageGetter = biMock.get // Reset for every sub-test } t.Run("delegate enrich error", func(t *testing.T) { @@ -1100,18 +1154,65 @@ func TestEnrichImage_Delegate(t *testing.T) { assert.Equal(t, result.ScanResult, ScanNotDone) assert.False(t, result.ImageUpdated) assert.ErrorIs(t, err, errBroken) + + // Verify: Should NOT call baseImageGetter on delegation failure + assert.Equal(t, 0, biMock.callCount) }) t.Run("delegate enrich success", func(t *testing.T) { setup(t) - fakeImage := &storage.Image{} + fakeImage := &storage.Image{ + Id: "sha256:delegate", + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"layer1"}, + }, + } + dele.EXPECT().GetDelegateClusterID(emptyCtx, gomock.Any()).Return("cluster-id", true, nil) dele.EXPECT().DelegateScanImage(emptyCtx, gomock.Any(), "cluster-id", "", gomock.Any()).Return(fakeImage, nil) result, err := e.EnrichImage(emptyCtx, deleEnrichCtx, fakeImage) + assert.Equal(t, result.ScanResult, ScanSucceeded) assert.True(t, result.ImageUpdated) assert.NoError(t, err) + + // No cached image. + assert.Equal(t, 0, biMock.callCount) + }) + + t.Run("delegate enrich success with image cache", func(t *testing.T) { + setup(t) + + inputImage := &storage.Image{ + Id: "sha256:delegate-cached", + Name: &storage.ImageName{FullName: "reg/img:tag"}, + } + + cachedImage := &storage.Image{ + Id: "sha256:delegate-cached", + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"layer1", "layer2"}, + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{{Instruction: "FROM"}}, + }, + }, + Scan: &storage.ImageScan{ + ScannerVersion: "1.0", + }, + } + e.imageGetter = imageGetterFromImage(cachedImage) + + dele.EXPECT().GetDelegateClusterID(gomock.Any(), gomock.Any()).Return("cluster-id", true, nil) + + result, err := e.EnrichImage(emptyCtx, deleEnrichCtx, inputImage) + + assert.NoError(t, err) + assert.True(t, result.ImageUpdated) + assert.Equal(t, ScanSucceeded, result.ScanResult) + + assert.Equal(t, 1, biMock.callCount, "Base image getter should be called for cached delegated images") + assert.NotNil(t, inputImage.GetMetadata()) }) } @@ -1388,11 +1489,15 @@ func TestEnrichImageWithBaseImages(t *testing.T) { const expectedDigest = "sha256:abcdef123456" // CHANGE: Replace mockMatcher with a function closure - mockBaseImageGetter := func(ctx context.Context, layers []string) ([]*storage.BaseImageInfo, error) { - return []*storage.BaseImageInfo{ + mockBaseImageGetter := func(ctx context.Context, layers []string) ([]*storage.BaseImage, error) { + return []*storage.BaseImage{ { - BaseImageFullName: expectedName, - BaseImageDigest: expectedDigest, + Repository: "docker.io/library/alpine", + Tag: "3.18", + ManifestDigest: expectedDigest, + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "sha1", Index: 0}, + }, }, }, nil } @@ -1400,12 +1505,12 @@ func TestEnrichImageWithBaseImages(t *testing.T) { testImpl := &enricherImpl{ cvesSuppressorV2: &fakeCVESuppressorV2{}, integrations: set, - metadataLimiter: rate.NewLimiter(rate.Inf, 0), + metadataLimiter: rate.NewLimiter(rate.Every(50*time.Millisecond), 1), metadataCache: newCache(), metrics: newMetrics(pkgMetrics.CentralSubsystem), imageGetter: emptyImageGetter, signatureIntegrationGetter: emptySignatureIntegrationGetter, - baseImageGetter: mockBaseImageGetter, // Updated field name/type + baseImageGetter: mockBaseImageGetter, integrationHealthReporter: reporterMocks.NewMockReporter(ctrl), } @@ -1421,6 +1526,12 @@ func TestEnrichImageWithBaseImages(t *testing.T) { Metadata: &storage.ImageMetadata{ LayerShas: []string{"sha1", "sha2"}, DataSource: &storage.DataSource{Id: "test-id"}, + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {Instruction: "ADD"}, + {Instruction: "RUN"}, + }, + }, }, } @@ -1434,9 +1545,205 @@ func TestEnrichImageWithBaseImages(t *testing.T) { } func newEnricher(set *mocks.MockSet, mockReporter *reporterMocks.MockReporter) ImageEnricher { - return New(&fakeCVESuppressorV2{}, set, pkgMetrics.CentralSubsystem, + return New(&fakeCVESuppressorV2{}, nil, set, pkgMetrics.CentralSubsystem, newCache(), - nil, + emptyBaseImageGetter, emptyImageGetter, mockReporter, emptySignatureIntegrationGetter, nil) } + +func TestResolveLayerBoundary(t *testing.T) { + cases := map[string]struct { + metadata *storage.ImageMetadata + baseContentLayers int + expected int + expectError bool + }{ + "V2 present with empty layers": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {Empty: true}, // 0: empty (ENV) + {Empty: false}, // 1: content layer 0 + {Empty: false}, // 2: content layer 1 + {Empty: true}, // 3: empty (LABEL) + {Empty: false}, // 4: content layer 2 + }, + }, + V2: &storage.V2Metadata{}, + }, + baseContentLayers: 2, // base has 2 content layers + expected: 2, // manifest index of last base layer + }, + "V2 present all content layers": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {Empty: false}, // 0 + {Empty: false}, // 1 + {Empty: false}, // 2 + }, + }, + V2: &storage.V2Metadata{}, + }, + baseContentLayers: 2, + expected: 1, + }, + "V1 only - direct mapping": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {}, // 0 + {}, // 1 + {}, // 2 + }, + }, + // No V2 + }, + baseContentLayers: 2, + expected: 1, + }, + "error: no content layers": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{{Empty: false}}, + }, + V2: &storage.V2Metadata{}, + }, + baseContentLayers: 0, + expectError: true, + }, + "error: not enough layers V1": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{{}}, + }, + }, + baseContentLayers: 5, + expectError: true, + }, + "error: not enough content layers V2": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {Empty: true}, + {Empty: false}, + }, + }, + V2: &storage.V2Metadata{}, + }, + baseContentLayers: 5, + expectError: true, + }, + "V2 without V1 layers - uses LayerShas": { + metadata: &storage.ImageMetadata{ + V2: &storage.V2Metadata{}, + LayerShas: []string{"sha1", "sha2", "sha3"}, + // V1 is nil or has no layers + }, + baseContentLayers: 2, + expected: 1, + }, + "no layer metadata at all": { + metadata: &storage.ImageMetadata{}, + baseContentLayers: 2, + expectError: true, + }, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + result, err := resolveLayerBoundary(c.metadata, c.baseContentLayers) + if c.expectError { + assert.Error(t, err) + } else { + require.NoError(t, err) + assert.Equal(t, c.expected, result) + } + }) + } +} + +func TestToBaseImageInfos(t *testing.T) { + cases := map[string]struct { + metadata *storage.ImageMetadata + baseImages []*storage.BaseImage + expected []*storage.BaseImageInfo + }{ + "computes max layer index with empty layers": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {Empty: false}, // 0: content 0 + {Empty: true}, // 1: empty + {Empty: false}, // 2: content 1 + {Empty: false}, // 3: content 2 (app layer) + }, + }, + V2: &storage.V2Metadata{}, + }, + baseImages: []*storage.BaseImage{ + { + Id: "base-1", + Repository: "rhel", + Tag: "8", + ManifestDigest: "sha256:abc", + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "layer-1", Index: 0}, + {LayerDigest: "layer-2", Index: 1}, + }, + }, + }, + expected: []*storage.BaseImageInfo{ + { + BaseImageId: "base-1", + BaseImageFullName: "rhel:8", + BaseImageDigest: "sha256:abc", + MaxLayerIndex: 2, // content layer 1 is at manifest index 2 + }, + }, + }, + "skips base image if boundary resolution fails": { + metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {Empty: false}, + }, + }, + V2: &storage.V2Metadata{}, + }, + baseImages: []*storage.BaseImage{ + { + Id: "bad-base", + Repository: "too-many", + Tag: "layers", + Layers: []*storage.BaseImageLayer{ + {}, {}, {}, {}, {}, // 5 layers but image only has 1 + }, + }, + }, + expected: nil, // skipped due to error + }, + "empty base images returns nil": { + metadata: &storage.ImageMetadata{}, + baseImages: nil, + expected: nil, + }, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + result := toBaseImageInfos(c.metadata, c.baseImages) + if c.expected == nil { + assert.Empty(t, result) + } else { + require.Len(t, result, len(c.expected)) + for i, exp := range c.expected { + assert.Equal(t, exp.GetBaseImageId(), result[i].GetBaseImageId()) + assert.Equal(t, exp.GetBaseImageFullName(), result[i].GetBaseImageFullName()) + assert.Equal(t, exp.GetMaxLayerIndex(), result[i].GetMaxLayerIndex()) + } + } + }) + } +} diff --git a/pkg/images/enricher/enricher_v2.go b/pkg/images/enricher/enricher_v2.go index e564d7bd4f005..90122ddab9e51 100644 --- a/pkg/images/enricher/enricher_v2.go +++ b/pkg/images/enricher/enricher_v2.go @@ -35,16 +35,17 @@ type ImageEnricherV2 interface { type ImageGetterV2 func(ctx context.Context, id string) (*storage.ImageV2, bool, error) // BaseImageGetterV2 will be used to get base images of a given image -type BaseImageGetterV2 func(ctx context.Context, layers []string) ([]*storage.BaseImageInfo, error) +type BaseImageGetterV2 func(ctx context.Context, layers []string) ([]*storage.BaseImage, error) // NewV2 returns a new ImageEnricherV2 instance for the given subsystem. // (The subsystem is just used for Prometheus metrics.) -func NewV2(cvesSuppressor CVESuppressor, is integration.Set, subsystem pkgMetrics.Subsystem, metadataCache cache.ImageMetadata, baseImageGetter BaseImageGetterV2, +func NewV2(cvesSuppressor CVESuppressor, cveInfoEnricher CVEInfoEnricher, is integration.Set, subsystem pkgMetrics.Subsystem, metadataCache cache.ImageMetadata, baseImageGetter BaseImageGetterV2, imageGetter ImageGetterV2, healthReporter integrationhealth.Reporter, signatureIntegrationGetter SignatureIntegrationGetter, scanDelegator delegatedregistry.Delegator) ImageEnricherV2 { enricher := &enricherV2Impl{ - cvesSuppressor: cvesSuppressor, - integrations: is, + cvesSuppressor: cvesSuppressor, + cveInfoEnricher: cveInfoEnricher, + integrations: is, // number of consecutive errors per registry or scanner to ascertain health of the integration errorsPerRegistry: make(map[registryTypes.ImageRegistry]int32), diff --git a/pkg/images/enricher/enricher_v2_impl.go b/pkg/images/enricher/enricher_v2_impl.go index e339e7541f33c..3d9f3b1ac836f 100644 --- a/pkg/images/enricher/enricher_v2_impl.go +++ b/pkg/images/enricher/enricher_v2_impl.go @@ -26,6 +26,7 @@ import ( "github.com/stackrox/rox/pkg/protoutils" registryTypes "github.com/stackrox/rox/pkg/registries/types" "github.com/stackrox/rox/pkg/sac" + "github.com/stackrox/rox/pkg/sac/resources" scannerTypes "github.com/stackrox/rox/pkg/scanners/types" "github.com/stackrox/rox/pkg/signatures" "github.com/stackrox/rox/pkg/sync" @@ -36,8 +37,9 @@ import ( var _ ImageEnricherV2 = (*enricherV2Impl)(nil) type enricherV2Impl struct { - cvesSuppressor CVESuppressor - integrations integration.Set + cvesSuppressor CVESuppressor + cveInfoEnricher CVEInfoEnricher + integrations integration.Set errorsPerRegistry map[registryTypes.ImageRegistry]int32 registryErrorsLock sync.RWMutex @@ -72,6 +74,7 @@ func (e *enricherV2Impl) EnrichWithVulnerabilities(imageV2 *storage.ImageV2, com }, errors.New("no image scanners are integrated") } + e.enrichWithBaseImage(context.Background(), imageV2) for _, imageScanner := range scanners.GetAll() { scanner := imageScanner.GetScanner() if vulnScanner, ok := scanner.(scannerTypes.ImageVulnerabilityGetter); ok { @@ -86,6 +89,14 @@ func (e *enricherV2Impl) EnrichWithVulnerabilities(imageV2 *storage.ImageV2, com ScanResult: ScanNotDone, }, errors.Wrapf(err, "retrieving image vulnerabilities from %s [%s]", scanner.Name(), scanner.Type()) } + + // Enrich CVEs with timing metadata (FixAvailableTimestamp, FirstSystemOccurrence) + if e.cveInfoEnricher != nil { + if err := e.cveInfoEnricher.EnrichImageV2WithCVEInfo(context.Background(), imageV2); err != nil { + log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) + } + } + e.cvesSuppressor.EnrichImageV2WithSuppressedCVEs(imageV2) return EnrichmentResult{ @@ -156,6 +167,8 @@ func (e *enricherV2Impl) delegateEnrichImage(ctx context.Context, enrichCtx Enri if exists && cachedImageV2IsValid(existingImg) { updated := e.updateImageWithExistingImage(imageV2, existingImg, enrichCtx.FetchOpt) if updated { + // Image is cached, but we force base image detection in case base images tags were updated. + e.enrichWithBaseImage(ctx, imageV2) e.cvesSuppressor.EnrichImageV2WithSuppressedCVEs(imageV2) // Errors for signature verification will be logged, so we can safely ignore them for the time being. _, _ = e.enrichWithSignatureVerificationData(ctx, enrichCtx, imageV2) @@ -176,6 +189,13 @@ func (e *enricherV2Impl) delegateEnrichImage(ctx context.Context, enrichCtx Enri imageV2.Reset() protocompat.Merge(imageV2, scannedImage) + // Enrich CVEs with timing metadata (FixAvailableTimestamp, FirstSystemOccurrence) + if e.cveInfoEnricher != nil { + if err := e.cveInfoEnricher.EnrichImageV2WithCVEInfo(ctx, imageV2); err != nil { + log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) + } + } + e.cvesSuppressor.EnrichImageV2WithSuppressedCVEs(imageV2) return true, nil } @@ -212,6 +232,48 @@ func (e *enricherV2Impl) updateImageWithExistingImage(imageV2 *storage.ImageV2, return e.useExistingScan(imageV2, existingImageV2, option) } +func (e *enricherV2Impl) enrichWithBaseImage(ctx context.Context, imageV2 *storage.ImageV2) { + if !features.BaseImageDetection.Enabled() { + return + } + if imageV2.GetMetadata() == nil { + log.Warnw("Matching image with base images failed as there's no image metadata", + logging.ImageID(imageV2.GetId()), + logging.String("image_name", imageV2.GetName().GetFullName())) + return + } + layers := imageV2.GetMetadata().GetLayerShas() + if len(layers) == 0 { + log.Warnw("Matching image with base images failed as there's no image layer SHAs", + logging.ImageID(imageV2.GetId()), + logging.String("image_name", imageV2.GetName().GetFullName())) + return + } + + adminCtx := sac.WithGlobalAccessScopeChecker(ctx, + sac.AllowFixedScopes( + sac.AccessModeScopeKeys(storage.Access_READ_ACCESS), + sac.ResourceScopeKeys(resources.ImageAdministration), + ), + ) + + matchedBaseImages, err := e.baseImageGetter(adminCtx, layers) + if err != nil { + log.Warnw("Matching image with base images failed", + logging.ImageID(imageV2.GetId()), + logging.Err(err), + logging.String("image_name", imageV2.GetName().GetFullName())) + return + } + + if len(matchedBaseImages) > 0 { + log.Debugw("Matching image with base images succeeded", + logging.ImageID(imageV2.GetId()), + logging.String("image_name", imageV2.GetName().GetFullName())) + imageV2.BaseImageInfo = toBaseImageInfos(imageV2.GetMetadata(), matchedBaseImages) + } +} + // EnrichImage enriches an image with the integration set present. func (e *enricherV2Impl) EnrichImage(ctx context.Context, enrichContext EnrichmentContext, imageV2 *storage.ImageV2) (EnrichmentResult, error) { shouldDelegate, err := e.delegateEnrichImage(ctx, enrichContext, imageV2) @@ -261,6 +323,9 @@ func (e *enricherV2Impl) EnrichImage(ctx context.Context, enrichContext Enrichme updated = updated || didUpdateMetadata + e.enrichWithBaseImage(ctx, imageV2) + updated = updated || len(imageV2.GetBaseImageInfo()) > 0 + // Update the image with existing values depending on the FetchOption provided or whether any are available. // This makes sure that we fetch any existing image only once from database. useExistingScanIfPossible := e.updateImageFromDatabase(ctx, imageV2, enrichContext.FetchOpt) @@ -293,19 +358,15 @@ func (e *enricherV2Impl) EnrichImage(ctx context.Context, enrichContext Enrichme updated = updated || didUpdateSigVerificationData - e.cvesSuppressor.EnrichImageV2WithSuppressedCVEs(imageV2) - - if features.BaseImageDetection.Enabled() { - imageV2.BaseImageInfo, err = e.baseImageGetter(ctx, imageV2.GetMetadata().GetLayerShas()) - if err != nil { - log.Warnw("Matching image with base images", - logging.FromContext(ctx), - logging.ImageID(imageV2.GetId()), - logging.Err(err), - logging.String("request_image", imageV2.GetName().GetFullName())) + // Enrich CVEs with timing metadata (FixAvailableTimestamp, FirstSystemOccurrence) + if e.cveInfoEnricher != nil { + if err := e.cveInfoEnricher.EnrichImageV2WithCVEInfo(ctx, imageV2); err != nil { + log.Warnf("Failed to enrich CVEs from ImageCVEInfo: %v", err) } } + e.cvesSuppressor.EnrichImageV2WithSuppressedCVEs(imageV2) + if !errorList.Empty() { errorList.AddError(delegateErr) } diff --git a/pkg/images/enricher/enricher_v2_impl_test.go b/pkg/images/enricher/enricher_v2_impl_test.go index 660d27d28be4f..90fc438f18816 100644 --- a/pkg/images/enricher/enricher_v2_impl_test.go +++ b/pkg/images/enricher/enricher_v2_impl_test.go @@ -17,6 +17,7 @@ import ( reporterMocks "github.com/stackrox/rox/pkg/integrationhealth/mocks" pkgMetrics "github.com/stackrox/rox/pkg/metrics" "github.com/stackrox/rox/pkg/protoassert" + "github.com/stackrox/rox/pkg/protocompat" registryMocks "github.com/stackrox/rox/pkg/registries/mocks" "github.com/stackrox/rox/pkg/registries/types" scannerMocks "github.com/stackrox/rox/pkg/scanners/mocks" @@ -43,6 +44,10 @@ func imageGetterV2PanicOnCall(_ context.Context, _ string) (*storage.ImageV2, bo panic("Unexpected call to imageGetter") } +func emptyBaseImageGetterV2(_ context.Context, _ []string) ([]*storage.BaseImage, error) { + return nil, nil +} + var _ signatures.SignatureFetcher = (*fakeSigFetcher)(nil) var _ scannertypes.Scanner = (*fakeScanner)(nil) @@ -52,19 +57,32 @@ var ( _ types.ImageRegistry = (*fakeRegistryScanner)(nil) ) +type baseImageV2GetterMock struct { + callCount int +} + +func (m *baseImageV2GetterMock) get(_ context.Context, _ []string) ([]*storage.BaseImage, error) { + m.callCount++ + return nil, nil +} + func TestEnricherV2Flow(t *testing.T) { testutils.MustUpdateFeature(t, features.FlattenImageData, true) + // Ensure base image detection logic is toggled on for the test + t.Setenv(features.BaseImageDetection.EnvVar(), "true") + cases := []struct { - name string - ctx EnrichmentContext - inMetadataCache bool - shortCircuitRegistry bool - shortCircuitScanner bool - image *storage.ImageV2 - imageGetter ImageGetterV2 - fsr *fakeRegistryScanner - result EnrichmentResult - errorExpected bool + name string + ctx EnrichmentContext + inMetadataCache bool + shortCircuitRegistry bool + shortCircuitScanner bool + image *storage.ImageV2 + imageGetter ImageGetterV2 + fsr *fakeRegistryScanner + result EnrichmentResult + errorExpected bool + expectedBaseImageCalls int // track Base Image logic }{ { name: "nothing in the cache", @@ -76,8 +94,10 @@ func TestEnricherV2Flow(t *testing.T) { Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: true, requestedScan: true, @@ -86,6 +106,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "scan and metadata in both caches", @@ -99,13 +120,15 @@ func TestEnricherV2Flow(t *testing.T) { Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, imageGetter: imageGetterV2FromImage(&storage.ImageV2{ Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, Scan: &storage.ImageScan{}}), - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: false, @@ -114,6 +137,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data in both caches, but force refetch", @@ -125,8 +149,10 @@ func TestEnricherV2Flow(t *testing.T) { Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: true, requestedScan: true, @@ -135,6 +161,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: " data in both caches but force refetch use names", @@ -146,6 +173,9 @@ func TestEnricherV2Flow(t *testing.T) { Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, fsr: newFakeRegistryScanner(opts{ requestedMetadata: true, @@ -155,6 +185,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data in both caches but force refetch scans only", @@ -166,8 +197,10 @@ func TestEnricherV2Flow(t *testing.T) { Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: true, @@ -176,6 +209,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "set ScannerTypeHint to something not found in integrations", @@ -189,8 +223,8 @@ func TestEnricherV2Flow(t *testing.T) { Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, + // no need to pass metadata }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: false, @@ -199,6 +233,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanNotDone, }, + expectedBaseImageCalls: 0, }, { name: "set ScannerTypeHint to something found in integrations", @@ -211,8 +246,10 @@ func TestEnricherV2Flow(t *testing.T) { Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: true, @@ -221,6 +258,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data not in caches, and no external metadata", @@ -235,7 +273,6 @@ func TestEnricherV2Flow(t *testing.T) { Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, }, - fsr: newFakeRegistryScanner(opts{ requestedMetadata: false, requestedScan: false, @@ -244,6 +281,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: false, ScanResult: ScanNotDone, }, + expectedBaseImageCalls: 0, }, { name: "data not in cache, but image already has metadata and scan", @@ -256,7 +294,7 @@ func TestEnricherV2Flow(t *testing.T) { image: &storage.ImageV2{ Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", - Metadata: &storage.ImageMetadata{}, + Metadata: &storage.ImageMetadata{DataSource: &storage.DataSource{Id: "exists"}, LayerShas: []string{"SHA1"}}, Scan: &storage.ImageScan{}, Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, }, @@ -268,6 +306,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: false, ScanResult: ScanNotDone, }, + expectedBaseImageCalls: 1, }, { name: "data not in cache and ignore existing images", @@ -280,6 +319,9 @@ func TestEnricherV2Flow(t *testing.T) { Digest: "sha", Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, Scan: &storage.ImageScan{}, + Metadata: &storage.ImageMetadata{ + LayerShas: []string{"SHA1"}, + }, }, imageGetter: imageGetterV2PanicOnCall, fsr: newFakeRegistryScanner(opts{ @@ -290,6 +332,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, { name: "data in cache and ignore existing images", @@ -302,7 +345,7 @@ func TestEnricherV2Flow(t *testing.T) { image: &storage.ImageV2{ Id: utils.NewImageV2ID(&storage.ImageName{Registry: "reg", FullName: "reg"}, "sha"), Digest: "sha", - Metadata: &storage.ImageMetadata{}, + Metadata: &storage.ImageMetadata{DataSource: &storage.DataSource{Id: "exists"}, LayerShas: []string{"SHA1"}}, Scan: &storage.ImageScan{}, Name: &storage.ImageName{Registry: "reg", FullName: "reg"}, }, @@ -315,6 +358,7 @@ func TestEnricherV2Flow(t *testing.T) { ImageUpdated: true, ScanResult: ScanSucceeded, }, + expectedBaseImageCalls: 1, }, } @@ -337,42 +381,49 @@ func TestEnricherV2Flow(t *testing.T) { scannerSet := scannerMocks.NewMockSet(ctrl) if !c.shortCircuitScanner { - scannerSet.EXPECT().IsEmpty().Return(false) + scannerSet.EXPECT().IsEmpty().Return(false).AnyTimes() scannerSet.EXPECT().GetAll().Return([]scannertypes.ImageScannerWithDataSource{fsr}).AnyTimes() - set.EXPECT().ScannerSet().Return(scannerSet) + set.EXPECT().ScannerSet().Return(scannerSet).AnyTimes() } mockReporter := reporterMocks.NewMockReporter(ctrl) mockReporter.EXPECT().UpdateIntegrationHealthAsync(gomock.Any()).AnyTimes() + // Setup mock for base image getter + mockBaseGetter := &baseImageV2GetterMock{} + enricherImpl := &enricherV2Impl{ cvesSuppressor: &fakeCVESuppressorV2{}, integrations: set, errorsPerScanner: map[scannertypes.ImageScannerWithDataSource]int32{fsr: 0}, errorsPerRegistry: map[types.ImageRegistry]int32{fsr: 0}, integrationHealthReporter: mockReporter, - metadataLimiter: rate.NewLimiter(rate.Every(50*time.Millisecond), 1), + metadataLimiter: rate.NewLimiter(rate.Inf, 0), metadataCache: newCache(), metrics: newMetrics(pkgMetrics.CentralSubsystem), imageGetter: emptyImageGetterV2, signatureIntegrationGetter: emptySignatureIntegrationGetter, signatureFetcher: &fakeSigFetcher{}, + baseImageGetter: mockBaseGetter.get, } - if c.inMetadataCache { + + if c.inMetadataCache && c.image != nil { enricherImpl.metadataCache.Add(c.image.GetId(), c.image.GetMetadata()) } if c.imageGetter != nil { enricherImpl.imageGetter = c.imageGetter } - result, err := enricherImpl.EnrichImage(emptyCtx, c.ctx, c.image) - if !c.errorExpected { - require.NoError(t, err) - } else { + + result, err := enricherImpl.EnrichImage(context.Background(), c.ctx, c.image) + + if c.errorExpected { require.Error(t, err) + } else { + require.NoError(t, err) } - assert.Equal(t, c.result, result) - assert.Equal(t, c.fsr, fsr) + assert.Equal(t, c.result, result) + assert.Equal(t, c.expectedBaseImageCalls, mockBaseGetter.callCount, "Mismatch in: %s", c.name) }) } } @@ -409,6 +460,7 @@ func TestCVESuppressionV2(t *testing.T) { imageGetter: emptyImageGetterV2, signatureIntegrationGetter: emptySignatureIntegrationGetter, signatureFetcher: &fakeSigFetcher{}, + baseImageGetter: emptyBaseImageGetterV2, } img := &storage.ImageV2{ @@ -1057,9 +1109,13 @@ func TestDelegateEnrichImageV2(t *testing.T) { func TestEnrichImageV2_Delegate(t *testing.T) { testutils.MustUpdateFeature(t, features.FlattenImageData, true) deleEnrichCtx := EnrichmentContext{Delegable: true} + + biMock := &baseImageV2GetterMock{} + e := enricherV2Impl{ - cvesSuppressor: &fakeCVESuppressorV2{}, - imageGetter: emptyImageGetterV2, + cvesSuppressor: &fakeCVESuppressorV2{}, + imageGetter: emptyImageGetterV2, + baseImageGetter: biMock.get, // Inject tracker } var dele *delegatorMocks.MockDelegator @@ -1067,6 +1123,7 @@ func TestEnrichImageV2_Delegate(t *testing.T) { ctrl := gomock.NewController(t) dele = delegatorMocks.NewMockDelegator(ctrl) e.scanDelegator = dele + e.baseImageGetter = biMock.get // Reset for every sub-test } t.Run("delegate enrich error", func(t *testing.T) { @@ -1074,21 +1131,70 @@ func TestEnrichImageV2_Delegate(t *testing.T) { dele.EXPECT().GetDelegateClusterID(emptyCtx, gomock.Any()).Return("", true, errBroken) result, err := e.EnrichImage(emptyCtx, deleEnrichCtx, nil) - assert.Equal(t, result.ScanResult, ScanNotDone) + + assert.Equal(t, ScanNotDone, result.ScanResult) assert.False(t, result.ImageUpdated) assert.ErrorIs(t, err, errBroken) + assert.Equal(t, 0, biMock.callCount, "Base image should not be fetched on error") }) t.Run("delegate enrich success", func(t *testing.T) { setup(t) - fakeImage := &storage.ImageV2{} + fakeImage := &storage.ImageV2{Id: "sha256:delegate"} + dele.EXPECT().GetDelegateClusterID(emptyCtx, gomock.Any()).Return("cluster-id", true, nil) dele.EXPECT().DelegateScanImageV2(emptyCtx, gomock.Any(), "cluster-id", "", gomock.Any()).Return(fakeImage, nil) result, err := e.EnrichImage(emptyCtx, deleEnrichCtx, fakeImage) - assert.Equal(t, result.ScanResult, ScanSucceeded) + + assert.Equal(t, ScanSucceeded, result.ScanResult) assert.True(t, result.ImageUpdated) assert.NoError(t, err) + + assert.Equal(t, 0, biMock.callCount, "Base image should not be fetched for fresh scans") + }) + t.Run("delegate enrich success with image cache", func(t *testing.T) { + setup(t) + + const sha = "sha256:delegate-cached" + imgName := &storage.ImageName{FullName: "reg/img:tag"} + + derivedID := utils.NewImageV2ID(imgName, sha) + + inputImage := &storage.ImageV2{ + Id: derivedID, // Use the derived ID + Digest: sha, + Name: imgName, + } + + cachedImage := &storage.ImageV2{ + Id: derivedID, // Use the same derived ID + Digest: sha, + Name: imgName, + Metadata: &storage.ImageMetadata{ + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{{Instruction: "FROM"}}, + }, + V2: &storage.V2Metadata{ + Digest: sha, + }, + LayerShas: []string{"layer1", "layer2"}, + }, + Scan: &storage.ImageScan{ + ScannerVersion: "1.0", + ScanTime: protocompat.TimestampNow(), + }, + } + + e.imageGetter = imageGetterV2FromImage(cachedImage) + + dele.EXPECT().GetDelegateClusterID(gomock.Any(), gomock.Any()).Return("cluster-id", true, nil) + + result, err := e.EnrichImage(emptyCtx, deleEnrichCtx, inputImage) + + assert.NoError(t, err) + assert.True(t, result.ImageUpdated) + assert.Equal(t, 1, biMock.callCount, "Base image getter should be hit") }) } @@ -1250,11 +1356,15 @@ func TestEnrichImageWithBaseImagesV2(t *testing.T) { const expectedDigest = "sha256:abcdef123456" // CHANGE: Define the mock function instead of the gomock matcher - mockBaseImageGetter := func(ctx context.Context, layers []string) ([]*storage.BaseImageInfo, error) { - return []*storage.BaseImageInfo{ + mockBaseImageGetter := func(ctx context.Context, layers []string) ([]*storage.BaseImage, error) { + return []*storage.BaseImage{ { - BaseImageFullName: expectedName, - BaseImageDigest: expectedDigest, + Repository: "docker.io/library/alpine", + Tag: "3.18", + ManifestDigest: expectedDigest, + Layers: []*storage.BaseImageLayer{ + {LayerDigest: "sha1", Index: 0}, + }, }, }, nil } @@ -1285,6 +1395,12 @@ func TestEnrichImageWithBaseImagesV2(t *testing.T) { Metadata: &storage.ImageMetadata{ LayerShas: []string{"sha1", "sha2"}, DataSource: &storage.DataSource{Id: "test-id"}, + V1: &storage.V1Metadata{ + Layers: []*storage.ImageLayer{ + {Instruction: "ADD"}, + {Instruction: "RUN"}, + }, + }, }, } @@ -1301,9 +1417,9 @@ func TestEnrichImageWithBaseImagesV2(t *testing.T) { } func newEnricherV2(set *mocks.MockSet, mockReporter *reporterMocks.MockReporter) ImageEnricherV2 { - return NewV2(&fakeCVESuppressorV2{}, set, pkgMetrics.CentralSubsystem, + return NewV2(&fakeCVESuppressorV2{}, nil, set, pkgMetrics.CentralSubsystem, newCache(), - nil, + emptyBaseImageGetterV2, emptyImageGetterV2, mockReporter, emptySignatureIntegrationGetter, nil) } diff --git a/pkg/images/enricher/mocks/enricher.go b/pkg/images/enricher/mocks/enricher.go index 75e10897573cb..b9b7a62f77cd9 100644 --- a/pkg/images/enricher/mocks/enricher.go +++ b/pkg/images/enricher/mocks/enricher.go @@ -136,3 +136,55 @@ func (mr *MockCVESuppressorMockRecorder) EnrichImageWithSuppressedCVEs(image any mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnrichImageWithSuppressedCVEs", reflect.TypeOf((*MockCVESuppressor)(nil).EnrichImageWithSuppressedCVEs), image) } + +// MockCVEInfoEnricher is a mock of CVEInfoEnricher interface. +type MockCVEInfoEnricher struct { + ctrl *gomock.Controller + recorder *MockCVEInfoEnricherMockRecorder + isgomock struct{} +} + +// MockCVEInfoEnricherMockRecorder is the mock recorder for MockCVEInfoEnricher. +type MockCVEInfoEnricherMockRecorder struct { + mock *MockCVEInfoEnricher +} + +// NewMockCVEInfoEnricher creates a new mock instance. +func NewMockCVEInfoEnricher(ctrl *gomock.Controller) *MockCVEInfoEnricher { + mock := &MockCVEInfoEnricher{ctrl: ctrl} + mock.recorder = &MockCVEInfoEnricherMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCVEInfoEnricher) EXPECT() *MockCVEInfoEnricherMockRecorder { + return m.recorder +} + +// EnrichImageV2WithCVEInfo mocks base method. +func (m *MockCVEInfoEnricher) EnrichImageV2WithCVEInfo(ctx context.Context, image *storage.ImageV2) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnrichImageV2WithCVEInfo", ctx, image) + ret0, _ := ret[0].(error) + return ret0 +} + +// EnrichImageV2WithCVEInfo indicates an expected call of EnrichImageV2WithCVEInfo. +func (mr *MockCVEInfoEnricherMockRecorder) EnrichImageV2WithCVEInfo(ctx, image any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnrichImageV2WithCVEInfo", reflect.TypeOf((*MockCVEInfoEnricher)(nil).EnrichImageV2WithCVEInfo), ctx, image) +} + +// EnrichImageWithCVEInfo mocks base method. +func (m *MockCVEInfoEnricher) EnrichImageWithCVEInfo(ctx context.Context, image *storage.Image) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnrichImageWithCVEInfo", ctx, image) + ret0, _ := ret[0].(error) + return ret0 +} + +// EnrichImageWithCVEInfo indicates an expected call of EnrichImageWithCVEInfo. +func (mr *MockCVEInfoEnricherMockRecorder) EnrichImageWithCVEInfo(ctx, image any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnrichImageWithCVEInfo", reflect.TypeOf((*MockCVEInfoEnricher)(nil).EnrichImageWithCVEInfo), ctx, image) +} diff --git a/pkg/images/utils/test/utils_test.go b/pkg/images/utils/test/utils_test.go index 3723648eb746c..4ebfa4400c4fc 100644 --- a/pkg/images/utils/test/utils_test.go +++ b/pkg/images/utils/test/utils_test.go @@ -601,3 +601,42 @@ func TestFillScanStatsV2(t *testing.T) { }) } } + +func TestStripDatasourceNoClone(t *testing.T) { + original := &storage.ImageScan{ + Components: []*storage.EmbeddedImageScanComponent{ + { + Name: "comp1", + Vulns: []*storage.EmbeddedVulnerability{ + { + Cve: "cve-1", + Datasource: "test-ds-1", + }, + { + Cve: "cve-2", + Datasource: "test-ds-2", + }, + }, + }, + { + Name: "comp2", + Vulns: []*storage.EmbeddedVulnerability{ + { + Cve: "cve-3", + Datasource: "test-ds-3", + }, + { + Cve: "cve-4", + Datasource: "test-ds-4", + }, + }, + }, + }, + } + + utils.StripDatasourceNoClone(original) + assert.Equal(t, "", original.GetComponents()[0].GetVulns()[0].GetDatasource()) + assert.Equal(t, "", original.GetComponents()[0].GetVulns()[1].GetDatasource()) + assert.Equal(t, "", original.GetComponents()[1].GetVulns()[0].GetDatasource()) + assert.Equal(t, "", original.GetComponents()[1].GetVulns()[1].GetDatasource()) +} diff --git a/pkg/images/utils/utils.go b/pkg/images/utils/utils.go index d25df8df9db5b..8e920cb41becf 100644 --- a/pkg/images/utils/utils.go +++ b/pkg/images/utils/utils.go @@ -481,3 +481,11 @@ func FillScanStatsV2(i *storage.ImageV2) { } } } + +func StripDatasourceNoClone(scan *storage.ImageScan) { + for _, c := range scan.GetComponents() { + for _, v := range c.GetVulns() { + v.Datasource = "" + } + } +} diff --git a/pkg/postgres/schema/image_cve_infos.go b/pkg/postgres/schema/image_cve_infos.go index a1c3fefdda1e2..90166bc6228f0 100644 --- a/pkg/postgres/schema/image_cve_infos.go +++ b/pkg/postgres/schema/image_cve_infos.go @@ -42,5 +42,6 @@ type ImageCveInfos struct { ID string `gorm:"column:id;type:varchar;primaryKey"` FixAvailableTimestamp *time.Time `gorm:"column:fixavailabletimestamp;type:timestamp"` FirstSystemOccurrence *time.Time `gorm:"column:firstsystemoccurrence;type:timestamp"` + Cve string `gorm:"column:cve;type:varchar;index:imagecveinfos_cve,type:btree"` Serialized []byte `gorm:"column:serialized;type:bytea"` } diff --git a/pkg/scannerv4/client/client.go b/pkg/scannerv4/client/client.go index 8f28691514f86..3ce05d42a14ed 100644 --- a/pkg/scannerv4/client/client.go +++ b/pkg/scannerv4/client/client.go @@ -2,6 +2,7 @@ package client import ( "context" + "crypto/x509" "errors" "fmt" "net/url" @@ -118,7 +119,7 @@ func NewGRPCScanner(ctx context.Context, opts ...Option) (Scanner, error) { if o.comboMode { // Both o.indexerOpts and o.matcherOpts are the same, so just choose one. - conn, err := createGRPCConn(ctx, o.indexerOpts) + conn, err := createGRPCConn(ctx, o.indexerOpts, o.rootCAs) if err != nil { return nil, err } @@ -141,7 +142,7 @@ func NewGRPCScanner(ctx context.Context, opts ...Option) (Scanner, error) { var indexerClient v4.IndexerClient if o.indexerOpts.address != "" { - conn, err := createGRPCConn(ctx, o.indexerOpts) + conn, err := createGRPCConn(ctx, o.indexerOpts, o.rootCAs) if err != nil { return nil, err } @@ -151,7 +152,7 @@ func NewGRPCScanner(ctx context.Context, opts ...Option) (Scanner, error) { var matcherClient v4.MatcherClient if o.matcherOpts.address != "" { - conn, err := createGRPCConn(ctx, o.matcherOpts) + conn, err := createGRPCConn(ctx, o.matcherOpts, o.rootCAs) if err != nil { return nil, err } @@ -176,7 +177,7 @@ func (c *gRPCScanner) Close() error { return errList.ToError() } -func createGRPCConn(ctx context.Context, o connOptions) (*grpc.ClientConn, error) { +func createGRPCConn(ctx context.Context, o connOptions, rootCAs []*x509.Certificate) (*grpc.ClientConn, error) { // Prefix address with dns:/// to use the DNS name resolver. address := "dns:///" + o.address @@ -219,6 +220,10 @@ func createGRPCConn(ctx context.Context, o connOptions) (*grpc.ClientConn, error clientconn.MaxMsgReceiveSize(maxRespMsgSize), clientconn.WithDialOptions(dialOpts...), } + + if len(rootCAs) > 0 { + connOpts = append(connOpts, clientconn.AddRootCAs(rootCAs...)) + } return clientconn.AuthenticatedGRPCConnection(ctx, address, o.mTLSSubject, connOpts...) } diff --git a/pkg/scannerv4/client/options.go b/pkg/scannerv4/client/options.go index 6133365b3c332..9141b2e02ea44 100644 --- a/pkg/scannerv4/client/options.go +++ b/pkg/scannerv4/client/options.go @@ -1,6 +1,7 @@ package client import ( + "crypto/x509" "errors" "fmt" "net" @@ -41,6 +42,7 @@ type options struct { indexerOpts connOptions matcherOpts connOptions comboMode bool + rootCAs []*x509.Certificate } type ImageRegistryOpt struct { @@ -141,6 +143,13 @@ func WithMatcherAddress(address string) Option { } } +// WithRootCAs specifies additional root CAs to trust when verifying the server's certificate. +func WithRootCAs(certs ...*x509.Certificate) Option { + return func(o *options) { + o.rootCAs = append(o.rootCAs, certs...) + } +} + func makeOptions(opts ...Option) (options, error) { o := defaultOptions for _, opt := range opts { diff --git a/proto/storage/cve.proto b/proto/storage/cve.proto index 5a932d6db6d69..8705fa75ed5e1 100644 --- a/proto/storage/cve.proto +++ b/proto/storage/cve.proto @@ -199,6 +199,7 @@ message ImageCVEV2 { // Timestamp when the fix for this CVE was made available according to the sources. google.protobuf.Timestamp fix_available_timestamp = 16; // @gotags: search:"CVE Fix Available Timestamp,hidden" + string datasource = 17; } message NodeCVE { @@ -341,4 +342,5 @@ message ImageCVEInfo { string id = 1; // @gotags: search:"CVE Info" sql:"pk" google.protobuf.Timestamp fix_available_timestamp = 2; // @gotags: search:"CVE Fix Available Timestamp,hidden" google.protobuf.Timestamp first_system_occurrence = 3; // @gotags: search:"First System Occurrence Timestamp,hidden" + string cve = 4; // @gotags: search:"CVE" sql:"index" } diff --git a/proto/storage/image.proto b/proto/storage/image.proto index a2104b1f43eda..6b81ad3ceb282 100644 --- a/proto/storage/image.proto +++ b/proto/storage/image.proto @@ -260,4 +260,7 @@ message BaseImageInfo { string base_image_full_name = 2; string base_image_digest = 3; google.protobuf.Timestamp created = 4; + // Index of the last base image layer, taking into account + // "empty layers" (aka. metadata history without SHA). + int32 max_layer_index = 5; } diff --git a/proto/storage/proto.lock b/proto/storage/proto.lock index a168c3d3e088c..d777a4ae0e09c 100644 --- a/proto/storage/proto.lock +++ b/proto/storage/proto.lock @@ -6603,6 +6603,11 @@ "id": 16, "name": "fix_available_timestamp", "type": "google.protobuf.Timestamp" + }, + { + "id": 17, + "name": "datasource", + "type": "string" } ] }, @@ -6890,6 +6895,11 @@ "id": 3, "name": "first_system_occurrence", "type": "google.protobuf.Timestamp" + }, + { + "id": 4, + "name": "cve", + "type": "string" } ] } @@ -9491,6 +9501,11 @@ "id": 4, "name": "created", "type": "google.protobuf.Timestamp" + }, + { + "id": 5, + "name": "max_layer_index", + "type": "int32" } ] } diff --git a/rpms.in.yaml b/rpms.in.yaml index ece356584c5b3..ea9f137d25850 100644 --- a/rpms.in.yaml +++ b/rpms.in.yaml @@ -7,6 +7,8 @@ packages: # final stage in image/rhel/konflux.Dockerfile - findutils - postgresql +# builder stage in operator/konflux.bundle.Dockerfile +- python3.12-pyyaml moduleEnable: # final stage in image/rhel/konflux.Dockerfile - postgresql:15 diff --git a/rpms.lock.yaml b/rpms.lock.yaml index 2d9fe0962e441..c57484eb23bf3 100644 --- a/rpms.lock.yaml +++ b/rpms.lock.yaml @@ -18,6 +18,13 @@ arches: name: libxkbcommon evr: 0.9.1-1.el8 sourcerpm: libxkbcommon-0.9.1-1.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/m/mpdecimal-2.5.1-3.el8.aarch64.rpm + repoid: rhel-8-for-aarch64-appstream-rpms + size: 95196 + checksum: sha256:02fdb7a4c616e2705ee31f6f834fbbb7aed91ca3cedf0ed3d5fd4c771ca46336 + name: mpdecimal + evr: 2.5.1-3.el8 + sourcerpm: mpdecimal-2.5.1-3.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/o/oniguruma-6.8.2-3.el8.aarch64.rpm repoid: rhel-8-for-aarch64-appstream-rpms size: 185652 @@ -25,20 +32,48 @@ arches: name: oniguruma evr: 6.8.2-3.el8 sourcerpm: oniguruma-6.8.2-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.aarch64.rpm repoid: rhel-8-for-aarch64-appstream-rpms - size: 1785883 - checksum: sha256:24562212b8673ccfbcfb80f7b3f6eca08ae83d65a2e2aadc924472a7bd97d6db + size: 1798263 + checksum: sha256:252c77d8411563980a3faa4fd4afca997bbd6f3456c1891036edaf429f676e34 name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/postgresql-private-libs-15.14-1.module+el8.10.0+23423+5a199198.aarch64.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/postgresql-private-libs-15.15-1.module+el8.10.0+23782+2d6b2a31.aarch64.rpm repoid: rhel-8-for-aarch64-appstream-rpms - size: 129399 - checksum: sha256:94c27b96fd1a6d76c801cdbfc07da04d6220640c2f83a533b21711789e347714 + size: 129939 + checksum: sha256:48e3f2c86fe94721c78b0c824a3dc6c75bd848291a502493cccb3ea953a09810 name: postgresql-private-libs - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/python3.12-3.12.12-2.el8_10.aarch64.rpm + repoid: rhel-8-for-aarch64-appstream-rpms + size: 31284 + checksum: sha256:f270a7bc12f08292e2a9b0db384a5bed3dda75c265d95597168613a830f5ef39 + name: python3.12 + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/python3.12-libs-3.12.12-2.el8_10.aarch64.rpm + repoid: rhel-8-for-aarch64-appstream-rpms + size: 10269428 + checksum: sha256:b3c91a832b5ef43cb9ca10d07a1942d5202e63eba80134f32af8843a6142479d + name: python3.12-libs + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/python3.12-pip-wheel-23.2.1-4.el8.noarch.rpm + repoid: rhel-8-for-aarch64-appstream-rpms + size: 1539820 + checksum: sha256:c5daaf3d7ef6c52f178ec6c20e49fa9ddb4506f1b0ee5cd1688046c28eb5e1cb + name: python3.12-pip-wheel + evr: 23.2.1-4.el8 + sourcerpm: python3.12-pip-23.2.1-4.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/p/python3.12-pyyaml-6.0.1-2.el8.aarch64.rpm + repoid: rhel-8-for-aarch64-appstream-rpms + size: 198784 + checksum: sha256:6a4945457be6e77d81f9dd7dce182d501d7fe90277b351db15f2b95589545711 + name: python3.12-pyyaml + evr: 6.0.1-2.el8 + sourcerpm: python3.12-pyyaml-6.0.1-2.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/Packages/x/xkeyboard-config-2.28-1.el8.noarch.rpm repoid: rhel-8-for-aarch64-appstream-rpms size: 801000 @@ -74,13 +109,13 @@ arches: name: bash evr: 4.4.20-6.el8_10 sourcerpm: bash-4.4.20-6.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/b/brotli-1.0.6-3.el8.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/b/brotli-1.0.6-4.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 321484 - checksum: sha256:14df7263bcc35cb6633321f36149ddadd479ca334798bb33544109a2c61a6213 + size: 320588 + checksum: sha256:0a1b984adc1bba4069243c00cc38530ab9eb74ac4efee473bc5301ea6e5e3b36 name: brotli - evr: 1.0.6-3.el8 - sourcerpm: brotli-1.0.6-3.el8.src.rpm + evr: 1.0.6-4.el8_10 + sourcerpm: brotli-1.0.6-4.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/b/bzip2-libs-1.0.6-28.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 49732 @@ -207,20 +242,20 @@ arches: name: dbus-tools evr: 1:1.12.8-27.el8_10 sourcerpm: dbus-1.12.8-27.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.2.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.3.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 384528 - checksum: sha256:033c79a4a469245425c6293ab95ffa7963eaabe0871a1266ab7bedfe8670e0de + size: 383544 + checksum: sha256:c2b79444a0fd22507b15728b6e0e33364af0f15c540ed9197f60a46b2deda559 name: device-mapper - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.2.aarch64.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.3.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 409080 - checksum: sha256:015d8a22550b22dffcd0da73bcd32517a3cd8d5e35c11723eea1ca6d31a5e50e + size: 408068 + checksum: sha256:3fec4e2ec36933b654e90252c1e101c6bdbfc643eda693f1f0dcf3bc4403d8dd name: device-mapper-libs - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/d/diffutils-3.6-6.el8.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 360676 @@ -333,13 +368,13 @@ arches: name: gettext-libs evr: 0.19.8.1-17.el8 sourcerpm: gettext-0.19.8.1-17.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/g/glib2-2.56.4-167.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/g/glib2-2.56.4-168.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 2555008 - checksum: sha256:7b666d9dda0acf4abba674ee76037c390aeeb91230367603302acae208f701a5 + size: 2554640 + checksum: sha256:66f593a251f997a439a2a278aa10640a09e018697b3ba1fe7918ce646314f021 name: glib2 - evr: 2.56.4-167.el8_10 - sourcerpm: glib2-2.56.4-167.el8_10.src.rpm + evr: 2.56.4-168.el8_10 + sourcerpm: glib2-2.56.4-168.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/g/glibc-2.28-251.el8_10.27.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 1884224 @@ -522,13 +557,13 @@ arches: name: libattr evr: 2.4.48-3.el8 sourcerpm: attr-2.4.48-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libblkid-2.32.1-47.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libblkid-2.32.1-48.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 218828 - checksum: sha256:f095a01eb9eb5d47a41beebfb0f9069365ca0a67ab2e137bc8501c748344b3ea + size: 219120 + checksum: sha256:02202c15390d7ecf9c48e4bce8b0a81b5eff270ffcfbec998c4546bf9483d293 name: libblkid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libcap-2.48-6.el8_9.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 75344 @@ -578,13 +613,13 @@ arches: name: libdb-utils evr: 5.3.28-42.el8_4 sourcerpm: libdb-5.3.28-42.el8_4.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libfdisk-2.32.1-47.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libfdisk-2.32.1-48.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 249284 - checksum: sha256:77480a0068650a9b639f0d8ce7875be243e8577c85d1453b17a7360bc30999cf + size: 249448 + checksum: sha256:71b9420a10ef6d32a46068dd0a8f8cd44b3eefabe02bde00346d6cc72cb7d5cc name: libfdisk - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libffi-3.1-24.el8.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 37560 @@ -641,13 +676,13 @@ arches: name: libkcapi-hmaccalc evr: 1.4.0-2.el8 sourcerpm: libkcapi-1.4.0-2.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libmount-2.32.1-47.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libmount-2.32.1-48.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 234412 - checksum: sha256:9515a7b004a80109e8d7097403cb85f93d2ea886be7663fd7df7371e3cf3cb4b + size: 234604 + checksum: sha256:d94b2c54047114f914301266ca4185dcb2b90e32b3feb7fcb88c8777f992ed4b name: libmount - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libnghttp2-1.33.0-6.el8_10.1.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 77144 @@ -683,13 +718,13 @@ arches: name: libseccomp evr: 2.5.2-1.el8 sourcerpm: libseccomp-2.5.2-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libselinux-2.9-10.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libselinux-2.9-11.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 166492 - checksum: sha256:5a2eeeaa180de98a3774877571c8a7bdebd77deca9b741a92be428413ab8e38b + size: 165608 + checksum: sha256:e34001b4096c6ac6b70c4ed82927095f367bde77567be9f59ac8751cfda8ad64 name: libselinux - evr: 2.9-10.el8_10 - sourcerpm: libselinux-2.9-10.el8_10.src.rpm + evr: 2.9-11.el8_10 + sourcerpm: libselinux-2.9-11.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libsemanage-2.9-12.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 168536 @@ -711,13 +746,13 @@ arches: name: libsigsegv evr: 2.11-5.el8 sourcerpm: libsigsegv-2.11-5.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libsmartcols-2.32.1-47.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libsmartcols-2.32.1-48.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 178592 - checksum: sha256:c0038da4290bbbad241f36f5f7f9b16b0bb11baf108973eef0b9a9dc41301e65 + size: 178700 + checksum: sha256:55da9f33dd305e6d6e156b96fde1f0a2b96b184507b80575b832033aaaaece1b name: libsmartcols - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libssh-0.9.6-16.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 214584 @@ -767,13 +802,13 @@ arches: name: libutempter evr: 1.1.6-14.el8 sourcerpm: libutempter-1.1.6-14.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libuuid-2.32.1-47.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libuuid-2.32.1-48.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 100032 - checksum: sha256:24ecbd85e9f6a07435abd85815526ad7d3f2292451424b41685d377a3088fd29 + size: 100212 + checksum: sha256:0cd068fb65f72bd3be463f4aed931340bad45ebdb1adf2a0ed1b9a3f3d9b96d5 name: libuuid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libverto-0.3.2-2.el8.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 24168 @@ -795,6 +830,13 @@ arches: name: libxml2 evr: 2.9.7-21.el8_10.3 sourcerpm: libxml2-2.9.7-21.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libyaml-0.1.7-5.el8.aarch64.rpm + repoid: rhel-8-for-aarch64-baseos-rpms + size: 58456 + checksum: sha256:7864fbc866ae5a3e59b4f0f114b77ff52b55e76c5388a917f82a6097f02a4db7 + name: libyaml + evr: 0.1.7-5.el8 + sourcerpm: libyaml-0.1.7-5.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/l/libzstd-1.4.4-1.el8.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 246104 @@ -886,13 +928,13 @@ arches: name: openssl-pkcs11 evr: 0.4.10-3.el8 sourcerpm: openssl-pkcs11-0.4.10-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/o/os-prober-1.74-9.el8.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/o/os-prober-1.74-11.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 56816 - checksum: sha256:cdc45c915674781f5db481d48a9ca6f40ed0ff1971c3bcb68c41da1aa00081e5 + size: 56284 + checksum: sha256:9adcbcb24e5dfd4cf8345dca4473073598c1f666c07543ca725b86fb5ae2b862 name: os-prober - evr: 1.74-9.el8 - sourcerpm: os-prober-1.74-9.el8.src.rpm + evr: 1.74-11.el8_10 + sourcerpm: os-prober-1.74-11.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/p/p11-kit-0.23.22-2.el8.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 316568 @@ -935,13 +977,13 @@ arches: name: pigz evr: 2.4-4.el8 sourcerpm: pigz-2.4-4.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/p/platform-python-3.6.8-71.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/p/platform-python-3.6.8-73.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 89844 - checksum: sha256:22b8476ce131da79ae5afdec7c685f9f7c3cfeac3303d2eccde6ef9e97279584 + size: 90128 + checksum: sha256:cb401dbc47e47579f66f572f6f0e3a02d4749da0d76e02ebb4ede439f55084b2 name: platform-python - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/p/platform-python-pip-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 1633024 @@ -977,13 +1019,13 @@ arches: name: publicsuffix-list-dafsa evr: 20180723-1.el8 sourcerpm: publicsuffix-list-20180723-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/p/python3-libs-3.6.8-71.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/p/python3-libs-3.6.8-73.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 8113884 - checksum: sha256:d17af894fad9fe0582b21f9abb6371c0eda62753101b9fe373928092b509d38c + size: 8116152 + checksum: sha256:846ef7d5e0e250663bf90557b3d6fb813299fe4cf207d53666e9ee5a4669e447 name: python3-libs - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/p/python3-pip-wheel-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 886996 @@ -1068,34 +1110,34 @@ arches: name: sqlite-libs evr: 3.26.0-20.el8_10 sourcerpm: sqlite-3.26.0-20.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-239-82.el8_10.8.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-239-82.el8_10.13.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 3513088 - checksum: sha256:c94f8fcedeb97ef9908137ec0d8b9a7618ab82618b3ecf7f345e25aa7ed5a267 + size: 3514456 + checksum: sha256:529f476e7b67ac581382275d9365490ba3b24f9cd7a68a8937dc22a97c8cc516 name: systemd - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-libs-239-82.el8_10.8.aarch64.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-libs-239-82.el8_10.13.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 1097868 - checksum: sha256:422451943b582df3f0ed2b30347c5fef85455beffe5a58cb67c2f1783d8a11a2 + size: 1099868 + checksum: sha256:f78d5d354e950c37542dc4cb1155c3cd490b3f844d3319362ec730274be345f5 name: systemd-libs - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-pam-239-82.el8_10.8.aarch64.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-pam-239-82.el8_10.13.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 487656 - checksum: sha256:af8b62ab3a3b79c2cbd7130c8a5a97801dfe1f4a3c266ef1b421db443bf90eb4 + size: 489180 + checksum: sha256:740ee08a8727c7672aefbf21c6d4afbdcbfb05076db43139a9b5adc1c70bbb7d name: systemd-pam - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-udev-239-82.el8_10.8.aarch64.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/s/systemd-udev-239-82.el8_10.13.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 1626444 - checksum: sha256:a77e034e5905688284937ae0ba9c998a6e1dd926240dd428653c09840f94ef9e + size: 1627748 + checksum: sha256:296e74ad60ed8ba21439f5fed1578baee5cd2e37b659e125990380e3d6391b9b name: systemd-udev - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/t/trousers-0.3.15-2.el8.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 151356 @@ -1117,13 +1159,13 @@ arches: name: tzdata evr: 2025c-1.el8 sourcerpm: tzdata-2025c-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/u/util-linux-2.32.1-47.el8_10.aarch64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/u/util-linux-2.32.1-48.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms - size: 2587504 - checksum: sha256:5632571c56cabce61cd6c7f88411e0f77743a9cc163f677a73a6b603b8f15044 + size: 2587976 + checksum: sha256:8a737712dfe00ec954e1f959c1b25faaf02700548efd4dfa37539a3dcaa9022e name: util-linux - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/os/Packages/w/which-2.21-21.el8_10.aarch64.rpm repoid: rhel-8-for-aarch64-baseos-rpms size: 50372 @@ -1165,18 +1207,42 @@ arches: checksum: sha256:ca72f33bbbdd245bf1d2385e5f934d36b0ebdc9854b242fce7be0bb56bfa8255 name: libxkbcommon evr: 0.9.1-1.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/m/mpdecimal-2.5.1-3.el8.src.rpm + repoid: rhel-8-for-aarch64-appstream-source-rpms + size: 3333112 + checksum: sha256:36811086e6cf10de04a5cfcbc3599228e073a44e032fac74d72857c970f06cae + name: mpdecimal + evr: 2.5.1-3.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/o/oniguruma-6.8.2-3.el8.src.rpm repoid: rhel-8-for-aarch64-appstream-source-rpms size: 982385 checksum: sha256:31cd372131f6eb404ce90285210fd74021914b4eb52e933b2aeebfa955099faa name: oniguruma evr: 6.8.2-3.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm repoid: rhel-8-for-aarch64-appstream-source-rpms - size: 53572917 - checksum: sha256:4a2c66b6b48cbf761ed5d454022f80fd6e63f89a84f095dac2683663960e9272 + size: 45654458 + checksum: sha256:30795de4ed7a01becc64ee50796e7c76b9195ff1eed0a341b279aeb3e4b15527 name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/p/python3.12-3.12.12-2.el8_10.src.rpm + repoid: rhel-8-for-aarch64-appstream-source-rpms + size: 20872264 + checksum: sha256:351a9a7709a0e1f8c6c80c39d6c47f7e5f8b4a52a1e0eb86eaa023661fe385fa + name: python3.12 + evr: 3.12.12-2.el8_10 + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/p/python3.12-pip-23.2.1-4.el8.src.rpm + repoid: rhel-8-for-aarch64-appstream-source-rpms + size: 9393232 + checksum: sha256:5661eadc28225da228c8a053fe6606cd2159238a469bc9a55fce9dbebb5e2232 + name: python3.12-pip + evr: 23.2.1-4.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/p/python3.12-pyyaml-6.0.1-2.el8.src.rpm + repoid: rhel-8-for-aarch64-appstream-source-rpms + size: 131090 + checksum: sha256:4254452a01f54622981f2716889690c281d1a5352ec07dbc919c96c3724ff7dc + name: python3.12-pyyaml + evr: 6.0.1-2.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/source/SRPMS/Packages/x/xkeyboard-config-2.28-1.el8.src.rpm repoid: rhel-8-for-aarch64-appstream-source-rpms size: 1699339 @@ -1213,12 +1279,12 @@ arches: checksum: sha256:f0e4182affffe350e5dbd55e410baed663d514cd6832108b83899ac8d1524830 name: bash evr: 4.4.20-6.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/b/brotli-1.0.6-3.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/b/brotli-1.0.6-4.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 23835509 - checksum: sha256:d269796bbd35c8ef524e4070d347f8b74cf1f10caa1bd4b19c30d69f24761f2a + size: 23845976 + checksum: sha256:87db48ae61691c6d457824c9391839cff50a576d03f17fe710f745e93050b826 name: brotli - evr: 1.0.6-3.el8 + evr: 1.0.6-4.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/b/bzip2-1.0.6-28.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 807250 @@ -1363,12 +1429,12 @@ arches: checksum: sha256:114be9b072a7726f2ac557fda6b8a86254ae3b7ed984ed14cfa7733bea9005d4 name: gettext evr: 0.19.8.1-17.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/g/glib2-2.56.4-167.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/g/glib2-2.56.4-168.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 7164394 - checksum: sha256:80ee50b39aa478e1503dbd18626df91a023d30e3f9b6fb588fa82e6ce2b5972e + size: 7169961 + checksum: sha256:6b67584ae03d06c58331b29141f63b0b86e256ddef78ec9c48f80bdfcdb76890 name: glib2 - evr: 2.56.4-167.el8_10 + evr: 2.56.4-168.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/g/glibc-2.28-251.el8_10.27.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 18525139 @@ -1531,12 +1597,12 @@ arches: checksum: sha256:322f0b9e2a909001e5e688b8ad52a5e6361ab350fa4fced3f446a6d1a3f2074a name: libseccomp evr: 2.5.2-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/libselinux-2.9-10.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/libselinux-2.9-11.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 355220 - checksum: sha256:2f61feb51798629d4f7b78130e68eb2516463da41d6e7b64d82d28d17355b3f1 + size: 355013 + checksum: sha256:47297c6a5ffa7556e1a19ac8f65b593f0cbb403cc743fde89e3c9a0424b1b0fc name: libselinux - evr: 2.9-10.el8_10 + evr: 2.9-11.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/libsemanage-2.9-12.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 268557 @@ -1603,18 +1669,24 @@ arches: checksum: sha256:a236b9807436c13e06c88926d7d3b25c2746f5b7fb12fadc41462a00d448a1f7 name: libxml2 evr: 2.9.7-21.el8_10.3 + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/libyaml-0.1.7-5.el8.src.rpm + repoid: rhel-8-for-aarch64-baseos-source-rpms + size: 540142 + checksum: sha256:5053fdb2c1384f513795f67c997eef3bc41290958ed8da17cf19edebc3dfdc83 + name: libyaml + evr: 0.1.7-5.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/lua-5.3.4-12.el8.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 437265 checksum: sha256:764fa61f3a6678bf93d94351468e49863176420688ab4e8c1aa6a5eb84ecf23d name: lua evr: 5.3.4-12.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.2.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.3.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 3185875 - checksum: sha256:c464de2287071dd2c498af02ce271d6153a354bfbce16b271c7131f98a55f8c8 + size: 3196004 + checksum: sha256:350e26dbc6f830fdb3548319013264cb2049858907c093a90b84a5945f6a4835 name: lvm2 - evr: 8:2.03.14-15.el8_10.2 + evr: 8:2.03.14-15.el8_10.3 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/l/lz4-1.8.3-5.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 347074 @@ -1669,12 +1741,12 @@ arches: checksum: sha256:a737e7fe890c5f53c1bc0c5925375791d8890f9d51c4a509091b41efa3f92861 name: openssl-pkcs11 evr: 0.4.10-3.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/o/os-prober-1.74-9.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/o/os-prober-1.74-11.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 55171 - checksum: sha256:0577008638e1644fed230d55b221b485e6cdc702cda9c27cf74ab7adcb8b8f00 + size: 55952 + checksum: sha256:602a6f146d9b36de4d52f744ad8d4084b87515e16a04c98c7d21368e7351194e name: os-prober - evr: 1.74-9.el8 + evr: 1.74-11.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/p/p11-kit-0.23.22-2.el8.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 909983 @@ -1735,12 +1807,12 @@ arches: checksum: sha256:31ae9c84f36f7d4e51b0e945e5d12210594defd3ea16cf5645c21d42fd6332fa name: python-setuptools evr: 39.2.0-9.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/p/python3-3.6.8-71.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/p/python3-3.6.8-73.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 19241145 - checksum: sha256:e7012ea23f3816772d64357f7db534f83c55279bcbefdecaefe2573d4734c6a3 + size: 19249994 + checksum: sha256:a4ffe561e7b271c2c78df1a1689e853315c6359c98c85f89e1dd067e634c0b51 name: python3 - evr: 3.6.8-71.el8_10 + evr: 3.6.8-73.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/r/readline-7.0-10.el8.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 2937518 @@ -1789,12 +1861,12 @@ arches: checksum: sha256:26dc49ea369dc145166e0a3959cc132f45e3345b99a75420c8932af24f44668c name: sqlite evr: 3.26.0-20.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.13.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 9188443 - checksum: sha256:a3ade60f73bb3137b94ac38205c321511b70e2bf61b79e2a25e31015fb415844 + size: 9204931 + checksum: sha256:6176d1736de4a4ff55021f7ad56e8cf5fdb459514f2ac45422c41bbfd5957a7b name: systemd - evr: 239-82.el8_10.8 + evr: 239-82.el8_10.13 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/t/texinfo-6.5-7.el8.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 4544531 @@ -1813,12 +1885,12 @@ arches: checksum: sha256:c9798a08b98344921713d3183bda98727df494d83f96924604b6b755ddc30f61 name: tzdata evr: 2025c-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-47.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-48.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms - size: 4817466 - checksum: sha256:e10e379f1386bdd6315e20cf735616747690c137ada562f47da85ca90ea966ee + size: 4820524 + checksum: sha256:c3ef99808b2afcaf8a5cf2dfef379980779bc1bee42688006fa22b5806b3471d name: util-linux - evr: 2.32.1-47.el8_10 + evr: 2.32.1-48.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/baseos/source/SRPMS/Packages/w/which-2.21-21.el8_10.src.rpm repoid: rhel-8-for-aarch64-baseos-source-rpms size: 171834 @@ -1844,10 +1916,10 @@ arches: name: zstd evr: 1.4.4-1.el8 module_metadata: - - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/repodata/1f6247087f10c5eaeccd512675154440e86abecf4842fae14e6d9835b61d44c7-modules.yaml.gz + - url: https://cdn.redhat.com/content/dist/rhel8/8/aarch64/appstream/os/repodata/3d72f862f2de42dab8082b452696bff9ce2eb76d2809834a0c3207f216735ceb-modules.yaml.gz repoid: rhel-8-for-aarch64-appstream-rpms - size: 755348 - checksum: sha256:1f6247087f10c5eaeccd512675154440e86abecf4842fae14e6d9835b61d44c7 + size: 766812 + checksum: sha256:3d72f862f2de42dab8082b452696bff9ce2eb76d2809834a0c3207f216735ceb - arch: ppc64le packages: - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/j/jq-1.6-11.el8_10.ppc64le.rpm @@ -1864,6 +1936,13 @@ arches: name: libxkbcommon evr: 0.9.1-1.el8 sourcerpm: libxkbcommon-0.9.1-1.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/m/mpdecimal-2.5.1-3.el8.ppc64le.rpm + repoid: rhel-8-for-ppc64le-appstream-rpms + size: 107920 + checksum: sha256:becf9d9d37f87c08958351a21b6e83adb3a80beb1d3e68b4dab4e409e8167dc6 + name: mpdecimal + evr: 2.5.1-3.el8 + sourcerpm: mpdecimal-2.5.1-3.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/o/oniguruma-6.8.2-3.el8.ppc64le.rpm repoid: rhel-8-for-ppc64le-appstream-rpms size: 204564 @@ -1871,20 +1950,48 @@ arches: name: oniguruma evr: 6.8.2-3.el8 sourcerpm: oniguruma-6.8.2-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.ppc64le.rpm repoid: rhel-8-for-ppc64le-appstream-rpms - size: 1864363 - checksum: sha256:6eb4836967b76fc22d7fe6c58cfeee10f51e7fd8902e99597d0ed5ee8328a600 + size: 1877303 + checksum: sha256:e60f7686d3bea0245ef49253c5705f2b66a2f23ba68b2c2768955bd3c303748c name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/postgresql-private-libs-15.14-1.module+el8.10.0+23423+5a199198.ppc64le.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/postgresql-private-libs-15.15-1.module+el8.10.0+23782+2d6b2a31.ppc64le.rpm repoid: rhel-8-for-ppc64le-appstream-rpms - size: 150687 - checksum: sha256:d50be28a27596fc611792e11609c61a8e5163615ab09bbd5db4ac6df562ae7c4 + size: 151435 + checksum: sha256:80c3061d69e75e725dd9de7084f948b82e37ec98e62a8522c7a79dcea803b74a name: postgresql-private-libs - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/python3.12-3.12.12-2.el8_10.ppc64le.rpm + repoid: rhel-8-for-ppc64le-appstream-rpms + size: 31480 + checksum: sha256:b46f760c95b16f8236abeab7177f0a5b4ffabc8f8f1d0affa973f28a323609ca + name: python3.12 + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/python3.12-libs-3.12.12-2.el8_10.ppc64le.rpm + repoid: rhel-8-for-ppc64le-appstream-rpms + size: 10777180 + checksum: sha256:bea75db484e02151e369098c17d671c4bd1ecf10127ef3571a16c0a8911c90a6 + name: python3.12-libs + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/python3.12-pip-wheel-23.2.1-4.el8.noarch.rpm + repoid: rhel-8-for-ppc64le-appstream-rpms + size: 1539820 + checksum: sha256:c5daaf3d7ef6c52f178ec6c20e49fa9ddb4506f1b0ee5cd1688046c28eb5e1cb + name: python3.12-pip-wheel + evr: 23.2.1-4.el8 + sourcerpm: python3.12-pip-23.2.1-4.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/p/python3.12-pyyaml-6.0.1-2.el8.ppc64le.rpm + repoid: rhel-8-for-ppc64le-appstream-rpms + size: 206180 + checksum: sha256:c7c68c07ce5ffe935b07cc4c886c95707ad8e05be1c9ba32e2371bab2d4182ff + name: python3.12-pyyaml + evr: 6.0.1-2.el8 + sourcerpm: python3.12-pyyaml-6.0.1-2.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/Packages/x/xkeyboard-config-2.28-1.el8.noarch.rpm repoid: rhel-8-for-ppc64le-appstream-rpms size: 801000 @@ -1920,13 +2027,13 @@ arches: name: bash evr: 4.4.20-6.el8_10 sourcerpm: bash-4.4.20-6.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/b/brotli-1.0.6-3.el8.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/b/brotli-1.0.6-4.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 336612 - checksum: sha256:e695072a3790e6c1229abfa1f703f081941be82064a9faab686cb7122838759f + size: 335632 + checksum: sha256:7791ae466716f187d4e3fbca1ca890552a4161968d58f12bf407d76ed48339c5 name: brotli - evr: 1.0.6-3.el8 - sourcerpm: brotli-1.0.6-3.el8.src.rpm + evr: 1.0.6-4.el8_10 + sourcerpm: brotli-1.0.6-4.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/b/bzip2-libs-1.0.6-28.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 54676 @@ -2053,20 +2160,20 @@ arches: name: dbus-tools evr: 1:1.12.8-27.el8_10 sourcerpm: dbus-1.12.8-27.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.2.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.3.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 389876 - checksum: sha256:05e03ef1ff1bebf2b6e812aaec94e99e159c5a9e24dc787d455e4639f6d2d20c + size: 388884 + checksum: sha256:fb96e882135eb1b7c7c375b043ae9e168e043ff230f8cedb41577536a0546423 name: device-mapper - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.2.ppc64le.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.3.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 429972 - checksum: sha256:6c17208c14104afa2003a83a8104eb5ffc5784652f80aa27ab737873c2b824ea + size: 428964 + checksum: sha256:2abb3d7a7fdc091571ff63f61d0bb3f0fa85db3b6c42b5b27430f54d9e5805dc name: device-mapper-libs - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/d/diffutils-3.6-6.el8.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 375484 @@ -2179,13 +2286,13 @@ arches: name: gettext-libs evr: 0.19.8.1-17.el8 sourcerpm: gettext-0.19.8.1-17.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/g/glib2-2.56.4-167.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/g/glib2-2.56.4-168.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 2705184 - checksum: sha256:be9bc79cace8aa17ac4e654cc8029b0a96e353e245eb9992e25db83bb9133568 + size: 2705108 + checksum: sha256:2168f27bece077449911a4fc63cb56fd49751f683b379fdc90bf3d63e513c44d name: glib2 - evr: 2.56.4-167.el8_10 - sourcerpm: glib2-2.56.4-167.el8_10.src.rpm + evr: 2.56.4-168.el8_10 + sourcerpm: glib2-2.56.4-168.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/g/glibc-2.28-251.el8_10.27.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 3516168 @@ -2368,13 +2475,13 @@ arches: name: libattr evr: 2.4.48-3.el8 sourcerpm: attr-2.4.48-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libblkid-2.32.1-47.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libblkid-2.32.1-48.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 247084 - checksum: sha256:0588a0f4ec7a55aaee28a3c34f2c02fc90d01af3a2a9b2a3e10bffc371b239c1 + size: 247288 + checksum: sha256:b147c1a3933ee6249a3ec6bd8b531532bc13cdf7c62edef811e8b933f36cc227 name: libblkid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libcap-2.48-6.el8_9.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 81276 @@ -2424,13 +2531,13 @@ arches: name: libdb-utils evr: 5.3.28-42.el8_4 sourcerpm: libdb-5.3.28-42.el8_4.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libfdisk-2.32.1-47.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libfdisk-2.32.1-48.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 275884 - checksum: sha256:3fee492a9a891261d9a38749ceece9ee6511549033ec7ab6c9a5d7c9b28803fb + size: 276132 + checksum: sha256:4403752475cb3641193b4edb130a98436bb184eaa46820645baefd61c4bc5c47 name: libfdisk - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libffi-3.1-24.el8.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 40004 @@ -2487,13 +2594,13 @@ arches: name: libkcapi-hmaccalc evr: 1.4.0-2.el8 sourcerpm: libkcapi-1.4.0-2.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libmount-2.32.1-47.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libmount-2.32.1-48.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 265396 - checksum: sha256:d8652ce55eff19ee1b6be7521bac17fa0b0a3f4db1feeaf9be8fd85b9a3336af + size: 265624 + checksum: sha256:a4e0cf5c1b0a92a399f88a2ae484b8e3bd14163d93b942e5a2a642fe0044c99f name: libmount - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libnghttp2-1.33.0-6.el8_10.1.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 87792 @@ -2536,13 +2643,13 @@ arches: name: libseccomp evr: 2.5.2-1.el8 sourcerpm: libseccomp-2.5.2-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libselinux-2.9-10.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libselinux-2.9-11.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 182304 - checksum: sha256:52cf0555fe9dc44219153a68fb4411c78347e96e3edb7b5830a9db28fdec3699 + size: 181376 + checksum: sha256:cf149e59cd091aeba1b59078ed981d53e29eda9a0a1aae362609b1450aaf2e27 name: libselinux - evr: 2.9-10.el8_10 - sourcerpm: libselinux-2.9-10.el8_10.src.rpm + evr: 2.9-11.el8_10 + sourcerpm: libselinux-2.9-11.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libsemanage-2.9-12.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 183976 @@ -2564,13 +2671,13 @@ arches: name: libsigsegv evr: 2.11-5.el8 sourcerpm: libsigsegv-2.11-5.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libsmartcols-2.32.1-47.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libsmartcols-2.32.1-48.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 195556 - checksum: sha256:0dc6f9098a57ee71436a48337927da6b47e2d5312e52b725ce99d9a05d311d6e + size: 195728 + checksum: sha256:8b907b6793e7a1451e8fe3dab0a68447de80f7dc3bd16975e857910ae46676f5 name: libsmartcols - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libssh-0.9.6-16.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 245868 @@ -2620,13 +2727,13 @@ arches: name: libutempter evr: 1.1.6-14.el8 sourcerpm: libutempter-1.1.6-14.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libuuid-2.32.1-47.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libuuid-2.32.1-48.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 102548 - checksum: sha256:0b3bbe3ae4996e754868de28635ff8a696987ab2e316e75b4389608edf4348fa + size: 102736 + checksum: sha256:215aed0a7da0ff753c3b5a7b0f828744b0dbff2ed944f9ce46e4a4368d7c9d3b name: libuuid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libverto-0.3.2-2.el8.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 26016 @@ -2648,6 +2755,13 @@ arches: name: libxml2 evr: 2.9.7-21.el8_10.3 sourcerpm: libxml2-2.9.7-21.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libyaml-0.1.7-5.el8.ppc64le.rpm + repoid: rhel-8-for-ppc64le-baseos-rpms + size: 69348 + checksum: sha256:9f1810ee304c2827027a4dadb0142f6940c28991b5371cbe302593eece6c25e4 + name: libyaml + evr: 0.1.7-5.el8 + sourcerpm: libyaml-0.1.7-5.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/l/libzstd-1.4.4-1.el8.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 282940 @@ -2739,13 +2853,13 @@ arches: name: openssl-pkcs11 evr: 0.4.10-3.el8 sourcerpm: openssl-pkcs11-0.4.10-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/o/os-prober-1.74-9.el8.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/o/os-prober-1.74-11.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 57116 - checksum: sha256:0db7648b03c119d2a1361712aed1c06e8ab0780adb29572da2d11a7f5e7e6770 + size: 56564 + checksum: sha256:a9988162a41de0029b12bef9ce2ceb91aa3e7c53220064a6f9aa2f780ddeb688 name: os-prober - evr: 1.74-9.el8 - sourcerpm: os-prober-1.74-9.el8.src.rpm + evr: 1.74-11.el8_10 + sourcerpm: os-prober-1.74-11.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/p/p11-kit-0.23.22-2.el8.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 335268 @@ -2788,13 +2902,13 @@ arches: name: pigz evr: 2.4-4.el8 sourcerpm: pigz-2.4-4.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/p/platform-python-3.6.8-71.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/p/platform-python-3.6.8-73.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 90356 - checksum: sha256:59053949e72772d34408de641ce14f6d717d0c5eb011bc89240c01d1e5764964 + size: 90640 + checksum: sha256:cb324c2c023ab359b9b2ba1380a90a1bd272f11021fbed5b7504ecf367a0e18e name: platform-python - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/p/platform-python-pip-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 1633024 @@ -2830,13 +2944,13 @@ arches: name: publicsuffix-list-dafsa evr: 20180723-1.el8 sourcerpm: publicsuffix-list-20180723-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/p/python3-libs-3.6.8-71.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/p/python3-libs-3.6.8-73.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 8510436 - checksum: sha256:f3de14c44b546400f9131a12fdd716e19d4df13a6a3cfeab9621793aca6c94e6 + size: 8550808 + checksum: sha256:bc91eea3ea4299828514b6e81c0e864f9c53548a194e6e2493771b72452333aa name: python3-libs - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/p/python3-pip-wheel-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 886996 @@ -2921,34 +3035,34 @@ arches: name: sqlite-libs evr: 3.26.0-20.el8_10 sourcerpm: sqlite-3.26.0-20.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-239-82.el8_10.8.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-239-82.el8_10.13.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 3886804 - checksum: sha256:861ab3ad615884b38cd186ade1cc74249e0b5a3e7465318504ab08c8355c4842 + size: 3889304 + checksum: sha256:1ede7d1324cb3c51492693d4ecb8b5e4c4e93544a7a4a62afc00e83535789fb0 name: systemd - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-libs-239-82.el8_10.8.ppc64le.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-libs-239-82.el8_10.13.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 1201844 - checksum: sha256:255bcea5675d0b6415cf95f7e44993cb5d2c9dbe300c0199fb5e7875f277af1c + size: 1203244 + checksum: sha256:a966bbf40612aef09d92b2fe0684bdf304c6f4778927106c1170ee428bc62c7b name: systemd-libs - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-pam-239-82.el8_10.8.ppc64le.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-pam-239-82.el8_10.13.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 552628 - checksum: sha256:f8800e69da7366f813d16c43c22d5ad77a36cc2b6befbbcdbcf71819adc97283 + size: 554400 + checksum: sha256:4157bb1244b7102308cc1da1bed8d757806c29ee0d7dfb7b323ab01f345d8ecc name: systemd-pam - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-udev-239-82.el8_10.8.ppc64le.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/s/systemd-udev-239-82.el8_10.13.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 1627128 - checksum: sha256:45511abfd2506c0145cefbac5cc195cf526f6c71c484f15491937db7f0f1ce43 + size: 1628676 + checksum: sha256:41b00948a476a5495cbac6dffbede3b534888fdb585cecfdee763375139eeb4c name: systemd-udev - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/t/trousers-0.3.15-2.el8.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 159044 @@ -2970,13 +3084,13 @@ arches: name: tzdata evr: 2025c-1.el8 sourcerpm: tzdata-2025c-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/u/util-linux-2.32.1-47.el8_10.ppc64le.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/u/util-linux-2.32.1-48.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms - size: 2700484 - checksum: sha256:b48627739d83c990f30f2fb460a9aff87182e9a3160704e2a818c00a65dc7f03 + size: 2701164 + checksum: sha256:53a056e9e249281bef1227be4150f5d92d6fcf7efa5b347ed200d7b1d995e823 name: util-linux - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/os/Packages/w/which-2.21-21.el8_10.ppc64le.rpm repoid: rhel-8-for-ppc64le-baseos-rpms size: 52168 @@ -3018,18 +3132,42 @@ arches: checksum: sha256:ca72f33bbbdd245bf1d2385e5f934d36b0ebdc9854b242fce7be0bb56bfa8255 name: libxkbcommon evr: 0.9.1-1.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/m/mpdecimal-2.5.1-3.el8.src.rpm + repoid: rhel-8-for-ppc64le-appstream-source-rpms + size: 3333112 + checksum: sha256:36811086e6cf10de04a5cfcbc3599228e073a44e032fac74d72857c970f06cae + name: mpdecimal + evr: 2.5.1-3.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/o/oniguruma-6.8.2-3.el8.src.rpm repoid: rhel-8-for-ppc64le-appstream-source-rpms size: 982385 checksum: sha256:31cd372131f6eb404ce90285210fd74021914b4eb52e933b2aeebfa955099faa name: oniguruma evr: 6.8.2-3.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm repoid: rhel-8-for-ppc64le-appstream-source-rpms - size: 53572917 - checksum: sha256:4a2c66b6b48cbf761ed5d454022f80fd6e63f89a84f095dac2683663960e9272 + size: 45654458 + checksum: sha256:30795de4ed7a01becc64ee50796e7c76b9195ff1eed0a341b279aeb3e4b15527 name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/p/python3.12-3.12.12-2.el8_10.src.rpm + repoid: rhel-8-for-ppc64le-appstream-source-rpms + size: 20872264 + checksum: sha256:351a9a7709a0e1f8c6c80c39d6c47f7e5f8b4a52a1e0eb86eaa023661fe385fa + name: python3.12 + evr: 3.12.12-2.el8_10 + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/p/python3.12-pip-23.2.1-4.el8.src.rpm + repoid: rhel-8-for-ppc64le-appstream-source-rpms + size: 9393232 + checksum: sha256:5661eadc28225da228c8a053fe6606cd2159238a469bc9a55fce9dbebb5e2232 + name: python3.12-pip + evr: 23.2.1-4.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/p/python3.12-pyyaml-6.0.1-2.el8.src.rpm + repoid: rhel-8-for-ppc64le-appstream-source-rpms + size: 131090 + checksum: sha256:4254452a01f54622981f2716889690c281d1a5352ec07dbc919c96c3724ff7dc + name: python3.12-pyyaml + evr: 6.0.1-2.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/source/SRPMS/Packages/x/xkeyboard-config-2.28-1.el8.src.rpm repoid: rhel-8-for-ppc64le-appstream-source-rpms size: 1699339 @@ -3066,12 +3204,12 @@ arches: checksum: sha256:f0e4182affffe350e5dbd55e410baed663d514cd6832108b83899ac8d1524830 name: bash evr: 4.4.20-6.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/b/brotli-1.0.6-3.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/b/brotli-1.0.6-4.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 23835509 - checksum: sha256:d269796bbd35c8ef524e4070d347f8b74cf1f10caa1bd4b19c30d69f24761f2a + size: 23845976 + checksum: sha256:87db48ae61691c6d457824c9391839cff50a576d03f17fe710f745e93050b826 name: brotli - evr: 1.0.6-3.el8 + evr: 1.0.6-4.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/b/bzip2-1.0.6-28.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 807250 @@ -3216,12 +3354,12 @@ arches: checksum: sha256:114be9b072a7726f2ac557fda6b8a86254ae3b7ed984ed14cfa7733bea9005d4 name: gettext evr: 0.19.8.1-17.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/g/glib2-2.56.4-167.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/g/glib2-2.56.4-168.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 7164394 - checksum: sha256:80ee50b39aa478e1503dbd18626df91a023d30e3f9b6fb588fa82e6ce2b5972e + size: 7169961 + checksum: sha256:6b67584ae03d06c58331b29141f63b0b86e256ddef78ec9c48f80bdfcdb76890 name: glib2 - evr: 2.56.4-167.el8_10 + evr: 2.56.4-168.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/g/glibc-2.28-251.el8_10.27.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 18525139 @@ -3390,12 +3528,12 @@ arches: checksum: sha256:322f0b9e2a909001e5e688b8ad52a5e6361ab350fa4fced3f446a6d1a3f2074a name: libseccomp evr: 2.5.2-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/libselinux-2.9-10.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/libselinux-2.9-11.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 355220 - checksum: sha256:2f61feb51798629d4f7b78130e68eb2516463da41d6e7b64d82d28d17355b3f1 + size: 355013 + checksum: sha256:47297c6a5ffa7556e1a19ac8f65b593f0cbb403cc743fde89e3c9a0424b1b0fc name: libselinux - evr: 2.9-10.el8_10 + evr: 2.9-11.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/libsemanage-2.9-12.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 268557 @@ -3462,18 +3600,24 @@ arches: checksum: sha256:a236b9807436c13e06c88926d7d3b25c2746f5b7fb12fadc41462a00d448a1f7 name: libxml2 evr: 2.9.7-21.el8_10.3 + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/libyaml-0.1.7-5.el8.src.rpm + repoid: rhel-8-for-ppc64le-baseos-source-rpms + size: 540142 + checksum: sha256:5053fdb2c1384f513795f67c997eef3bc41290958ed8da17cf19edebc3dfdc83 + name: libyaml + evr: 0.1.7-5.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/lua-5.3.4-12.el8.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 437265 checksum: sha256:764fa61f3a6678bf93d94351468e49863176420688ab4e8c1aa6a5eb84ecf23d name: lua evr: 5.3.4-12.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.2.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.3.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 3185875 - checksum: sha256:c464de2287071dd2c498af02ce271d6153a354bfbce16b271c7131f98a55f8c8 + size: 3196004 + checksum: sha256:350e26dbc6f830fdb3548319013264cb2049858907c093a90b84a5945f6a4835 name: lvm2 - evr: 8:2.03.14-15.el8_10.2 + evr: 8:2.03.14-15.el8_10.3 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/l/lz4-1.8.3-5.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 347074 @@ -3528,12 +3672,12 @@ arches: checksum: sha256:a737e7fe890c5f53c1bc0c5925375791d8890f9d51c4a509091b41efa3f92861 name: openssl-pkcs11 evr: 0.4.10-3.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/o/os-prober-1.74-9.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/o/os-prober-1.74-11.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 55171 - checksum: sha256:0577008638e1644fed230d55b221b485e6cdc702cda9c27cf74ab7adcb8b8f00 + size: 55952 + checksum: sha256:602a6f146d9b36de4d52f744ad8d4084b87515e16a04c98c7d21368e7351194e name: os-prober - evr: 1.74-9.el8 + evr: 1.74-11.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/p/p11-kit-0.23.22-2.el8.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 909983 @@ -3594,12 +3738,12 @@ arches: checksum: sha256:31ae9c84f36f7d4e51b0e945e5d12210594defd3ea16cf5645c21d42fd6332fa name: python-setuptools evr: 39.2.0-9.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/p/python3-3.6.8-71.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/p/python3-3.6.8-73.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 19241145 - checksum: sha256:e7012ea23f3816772d64357f7db534f83c55279bcbefdecaefe2573d4734c6a3 + size: 19249994 + checksum: sha256:a4ffe561e7b271c2c78df1a1689e853315c6359c98c85f89e1dd067e634c0b51 name: python3 - evr: 3.6.8-71.el8_10 + evr: 3.6.8-73.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/r/readline-7.0-10.el8.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 2937518 @@ -3648,12 +3792,12 @@ arches: checksum: sha256:26dc49ea369dc145166e0a3959cc132f45e3345b99a75420c8932af24f44668c name: sqlite evr: 3.26.0-20.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.13.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 9188443 - checksum: sha256:a3ade60f73bb3137b94ac38205c321511b70e2bf61b79e2a25e31015fb415844 + size: 9204931 + checksum: sha256:6176d1736de4a4ff55021f7ad56e8cf5fdb459514f2ac45422c41bbfd5957a7b name: systemd - evr: 239-82.el8_10.8 + evr: 239-82.el8_10.13 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/t/texinfo-6.5-7.el8.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 4544531 @@ -3672,12 +3816,12 @@ arches: checksum: sha256:c9798a08b98344921713d3183bda98727df494d83f96924604b6b755ddc30f61 name: tzdata evr: 2025c-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-47.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-48.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms - size: 4817466 - checksum: sha256:e10e379f1386bdd6315e20cf735616747690c137ada562f47da85ca90ea966ee + size: 4820524 + checksum: sha256:c3ef99808b2afcaf8a5cf2dfef379980779bc1bee42688006fa22b5806b3471d name: util-linux - evr: 2.32.1-47.el8_10 + evr: 2.32.1-48.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/baseos/source/SRPMS/Packages/w/which-2.21-21.el8_10.src.rpm repoid: rhel-8-for-ppc64le-baseos-source-rpms size: 171834 @@ -3703,10 +3847,10 @@ arches: name: zstd evr: 1.4.4-1.el8 module_metadata: - - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/repodata/82f87cf7ecb10bffa94c725b33719688bb26f81e8390cfbde8c23b0d68b0afe8-modules.yaml.gz + - url: https://cdn.redhat.com/content/dist/rhel8/8/ppc64le/appstream/os/repodata/9b18459472b2f83bdf1393e092983daf106d3cafe9d6f0a68704dbd38980c09d-modules.yaml.gz repoid: rhel-8-for-ppc64le-appstream-rpms - size: 752834 - checksum: sha256:82f87cf7ecb10bffa94c725b33719688bb26f81e8390cfbde8c23b0d68b0afe8 + size: 761744 + checksum: sha256:9b18459472b2f83bdf1393e092983daf106d3cafe9d6f0a68704dbd38980c09d - arch: s390x packages: - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/j/jq-1.6-11.el8_10.s390x.rpm @@ -3723,6 +3867,13 @@ arches: name: libxkbcommon evr: 0.9.1-1.el8 sourcerpm: libxkbcommon-0.9.1-1.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/m/mpdecimal-2.5.1-3.el8.s390x.rpm + repoid: rhel-8-for-s390x-appstream-rpms + size: 97316 + checksum: sha256:68089fe2afcbc5ce486d6e233de53df547052182afc88ac47c539d2841d55dab + name: mpdecimal + evr: 2.5.1-3.el8 + sourcerpm: mpdecimal-2.5.1-3.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/o/oniguruma-6.8.2-3.el8.s390x.rpm repoid: rhel-8-for-s390x-appstream-rpms size: 188988 @@ -3786,20 +3937,48 @@ arches: name: perl-libnet evr: 3.11-3.el8 sourcerpm: perl-libnet-3.11-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.s390x.rpm repoid: rhel-8-for-s390x-appstream-rpms - size: 1769979 - checksum: sha256:cb724993ae1ac5099ba3eebd84fdb7acc8716f3502a3c794f011046c00bfadd8 + size: 1782631 + checksum: sha256:f0afab8138e3ce7ab6bb930e9a3ac03f03c1616abedbca3390c0fde2a3f39479 name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/postgresql-private-libs-15.14-1.module+el8.10.0+23423+5a199198.s390x.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/postgresql-private-libs-15.15-1.module+el8.10.0+23782+2d6b2a31.s390x.rpm repoid: rhel-8-for-s390x-appstream-rpms - size: 128367 - checksum: sha256:bb5e475ffe306636145ecc909d945341326346ea34f1564674f46e933aff3dea + size: 128795 + checksum: sha256:32f31046e29c5dc0d48ae70fd732028069dbb5d6531a2bd72b538b850f27ffd1 name: postgresql-private-libs - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/python3.12-3.12.12-2.el8_10.s390x.rpm + repoid: rhel-8-for-s390x-appstream-rpms + size: 31036 + checksum: sha256:d20eba2f096fe4fde5aa2827d7919e57b0fca265aed2415694745c92adf768ca + name: python3.12 + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/python3.12-libs-3.12.12-2.el8_10.s390x.rpm + repoid: rhel-8-for-s390x-appstream-rpms + size: 10205624 + checksum: sha256:02c440f4a8eec6b1c88c1e66d52d41d59a63cd54542b98197abe8fac55925b07 + name: python3.12-libs + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/python3.12-pip-wheel-23.2.1-4.el8.noarch.rpm + repoid: rhel-8-for-s390x-appstream-rpms + size: 1539820 + checksum: sha256:c5daaf3d7ef6c52f178ec6c20e49fa9ddb4506f1b0ee5cd1688046c28eb5e1cb + name: python3.12-pip-wheel + evr: 23.2.1-4.el8 + sourcerpm: python3.12-pip-23.2.1-4.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/p/python3.12-pyyaml-6.0.1-2.el8.s390x.rpm + repoid: rhel-8-for-s390x-appstream-rpms + size: 198108 + checksum: sha256:23a5eead78f86d5f5b4382e6c6fed3eca6a4fcd21e6620a3f2c590d97e8354db + name: python3.12-pyyaml + evr: 6.0.1-2.el8 + sourcerpm: python3.12-pyyaml-6.0.1-2.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/Packages/x/xkeyboard-config-2.28-1.el8.noarch.rpm repoid: rhel-8-for-s390x-appstream-rpms size: 801000 @@ -3835,13 +4014,13 @@ arches: name: bash evr: 4.4.20-6.el8_10 sourcerpm: bash-4.4.20-6.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/b/brotli-1.0.6-3.el8.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/b/brotli-1.0.6-4.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 323352 - checksum: sha256:e134da086a66848af20f21dcebbeca19fde6a4af3016a09d5fde3984317e2c33 + size: 322524 + checksum: sha256:b81abd727d7147f63b380b23a945c8fbc7b138b4a297ff8b2ffc66a5b763477e name: brotli - evr: 1.0.6-3.el8 - sourcerpm: brotli-1.0.6-3.el8.src.rpm + evr: 1.0.6-4.el8_10 + sourcerpm: brotli-1.0.6-4.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/b/bzip2-libs-1.0.6-28.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 49852 @@ -3961,20 +4140,20 @@ arches: name: dbus-tools evr: 1:1.12.8-27.el8_10 sourcerpm: dbus-1.12.8-27.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.2.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.3.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 383276 - checksum: sha256:922dfc2ec369944152bd17078c901d709dbaec818f02a21ce7fce96d24820a21 + size: 382296 + checksum: sha256:5ab3b0bdfe8afc2c73f29a68b0fa49956891db99ca429d4e52b86360b7961e8b name: device-mapper - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.2.s390x.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.3.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 408880 - checksum: sha256:a25311e54344b073e5bb455a640ff79214616edbbf4f4121fffa6de9f6148782 + size: 407904 + checksum: sha256:ac30ee54bf7f236bf3ef453d383e886adb920ba95dc08dc130d8a4603895cc01 name: device-mapper-libs - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/d/diffutils-3.6-6.el8.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 364352 @@ -4080,13 +4259,13 @@ arches: name: gdbm-libs evr: 1:1.18-2.el8 sourcerpm: gdbm-1.18-2.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/g/glib2-2.56.4-167.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/g/glib2-2.56.4-168.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 2533872 - checksum: sha256:2a62ce51041c154b6fd8eb53d047282f8a24c564bdea96e03bda3f2b0073d468 + size: 2534132 + checksum: sha256:a71c1f62688f6b25c654634891583662ee14ac89fb7b81bbb81269cb9c80a47c name: glib2 - evr: 2.56.4-167.el8_10 - sourcerpm: glib2-2.56.4-167.el8_10.src.rpm + evr: 2.56.4-168.el8_10 + sourcerpm: glib2-2.56.4-168.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/g/glibc-2.28-251.el8_10.27.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 1876988 @@ -4213,13 +4392,13 @@ arches: name: libattr evr: 2.4.48-3.el8 sourcerpm: attr-2.4.48-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libblkid-2.32.1-47.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libblkid-2.32.1-48.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 217464 - checksum: sha256:8a29b8ce7cafb898bcc8a3998eb1faf948538d4e293902eb36cd8caeaa732ca8 + size: 217612 + checksum: sha256:8d5c68fd87e697e0e309212426e4addf8902433cbc6286a85f195a766f711dc4 name: libblkid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libcap-2.48-6.el8_9.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 75024 @@ -4262,13 +4441,13 @@ arches: name: libdb-utils evr: 5.3.28-42.el8_4 sourcerpm: libdb-5.3.28-42.el8_4.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libfdisk-2.32.1-47.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libfdisk-2.32.1-48.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 249252 - checksum: sha256:ace74b38dd4fc20e28ac047ac97b895189cfba9f7f6af1fa19ad3883c4a294e4 + size: 249432 + checksum: sha256:e7afee088419dacd15b7213670771daa3fb2943ce7e43f188f18c7cdad17a6b0 name: libfdisk - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libffi-3.1-24.el8.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 36696 @@ -4311,13 +4490,13 @@ arches: name: libmnl evr: 1.0.4-6.el8 sourcerpm: libmnl-1.0.4-6.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libmount-2.32.1-47.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libmount-2.32.1-48.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 233224 - checksum: sha256:8ad944179fb0335b551cc6d7de8da6186b9b6f13f89898c6dbb71103f923776d + size: 233312 + checksum: sha256:f9831477b70439ad68c5dd863291dbbc6c534067735d1cc472f375c288ab7f50 name: libmount - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libnghttp2-1.33.0-6.el8_10.1.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 76440 @@ -4353,13 +4532,13 @@ arches: name: libseccomp evr: 2.5.2-1.el8 sourcerpm: libseccomp-2.5.2-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libselinux-2.9-10.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libselinux-2.9-11.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 167768 - checksum: sha256:172bcf348933501b3cb89a339906c0f847db2ef0a2457732cb6146e74462725d + size: 166832 + checksum: sha256:8a0c1dfb3ee0982f3697eaa4d38b9a3e0196a89e530df428e1951db1aa7f7061 name: libselinux - evr: 2.9-10.el8_10 - sourcerpm: libselinux-2.9-10.el8_10.src.rpm + evr: 2.9-11.el8_10 + sourcerpm: libselinux-2.9-11.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libsemanage-2.9-12.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 168384 @@ -4381,13 +4560,13 @@ arches: name: libsigsegv evr: 2.11-5.el8 sourcerpm: libsigsegv-2.11-5.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libsmartcols-2.32.1-47.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libsmartcols-2.32.1-48.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 178524 - checksum: sha256:f9e67d9af7a2e93b3ff169d4998828956ac51c55b85405282913bcfcb322f501 + size: 178708 + checksum: sha256:05d1310fa27caa5dd4be91f9384ca68cfa4505fcc859408b628fbfe0bc8f9b6d name: libsmartcols - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libssh-0.9.6-16.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 208564 @@ -4437,13 +4616,13 @@ arches: name: libutempter evr: 1.1.6-14.el8 sourcerpm: libutempter-1.1.6-14.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libuuid-2.32.1-47.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libuuid-2.32.1-48.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 100760 - checksum: sha256:187bf3a3f84fcb072e650ad7319304cc266965046f522b010345291b2fa6f551 + size: 100932 + checksum: sha256:7828876cc5878259daf38047c037cf7edd8835f7a571ad570d52bee27fef7fc8 name: libuuid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libverto-0.3.2-2.el8.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 23952 @@ -4465,6 +4644,13 @@ arches: name: libxml2 evr: 2.9.7-21.el8_10.3 sourcerpm: libxml2-2.9.7-21.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libyaml-0.1.7-5.el8.s390x.rpm + repoid: rhel-8-for-s390x-baseos-rpms + size: 56044 + checksum: sha256:998276e153886e014ce37c429a0f22b76f3ca955c1c9ba89999ce3dface1cf10 + name: libyaml + evr: 0.1.7-5.el8 + sourcerpm: libyaml-0.1.7-5.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/l/libzstd-1.4.4-1.el8.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 248556 @@ -4815,13 +5001,13 @@ arches: name: perl-threads-shared evr: 1.58-2.el8 sourcerpm: perl-threads-shared-1.58-2.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/p/platform-python-3.6.8-71.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/p/platform-python-3.6.8-73.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 89660 - checksum: sha256:22867ac3e41db8b68fc13a3400e371c2e2702a76009a5c24c95c1325e5ec6138 + size: 89940 + checksum: sha256:12485aadf13f1673d52be6627004d1c5f1d1d285685847c4c3e033b9bb5433de name: platform-python - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/p/platform-python-pip-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 1633024 @@ -4850,13 +5036,13 @@ arches: name: publicsuffix-list-dafsa evr: 20180723-1.el8 sourcerpm: publicsuffix-list-20180723-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/p/python3-libs-3.6.8-71.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/p/python3-libs-3.6.8-73.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 8057676 - checksum: sha256:eb9bf761561e1d4fe6350953c4a8d87ed1f56d97ac35343d525074d3d359083c + size: 8057576 + checksum: sha256:042e19430d730b7f8cca741667f613413413c32f19b4cfe34e3b6c2478ab4d1c name: python3-libs - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/p/python3-pip-wheel-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 886996 @@ -4906,27 +5092,27 @@ arches: name: rpm-libs evr: 4.14.3-32.el8_10 sourcerpm: rpm-4.14.3-32.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/s390utils-base-2.29.0-3.el8_10.3.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/s390utils-base-2.29.0-3.el8_10.4.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 3143836 - checksum: sha256:038d666cbdaffb99d0f607e97ca34a55bd7b56528341854f7f209280efb36114 + size: 2898220 + checksum: sha256:2484e40a57d488a54f153064429de28d27ed0549600ae3ac0306a39b5d93c888 name: s390utils-base - evr: 2:2.29.0-3.el8_10.3 - sourcerpm: s390utils-2.29.0-3.el8_10.3.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/s390utils-core-2.29.0-3.el8_10.3.s390x.rpm + evr: 2:2.29.0-3.el8_10.4 + sourcerpm: s390utils-2.29.0-3.el8_10.4.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/s390utils-core-2.29.0-3.el8_10.4.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 491788 - checksum: sha256:c8d7d1382d16a13e6952c08ed6b62dcc354f16bb12d0adb1657473cebcde7cf7 + size: 491716 + checksum: sha256:84d6c7217e1a8facc69ce53919a3923ac27d7722faad42928f63d84d96fb02bd name: s390utils-core - evr: 2:2.29.0-3.el8_10.3 - sourcerpm: s390utils-2.29.0-3.el8_10.3.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/s390utils-se-data-2.29.0-3.el8_10.3.noarch.rpm + evr: 2:2.29.0-3.el8_10.4 + sourcerpm: s390utils-2.29.0-3.el8_10.4.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/s390utils-se-data-2.29.0-3.el8_10.4.noarch.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 56388 - checksum: sha256:05e7e8241d1cb0955239bb2570c6294c9d6583ea03e2695ad681cc67c905d9cb + size: 56500 + checksum: sha256:3aab1edba221352f8fcdcfc95671590b04af317b9952ff2451e615f9cbd59b6d name: s390utils-se-data - evr: 2:2.29.0-3.el8_10.3 - sourcerpm: s390utils-2.29.0-3.el8_10.3.src.rpm + evr: 2:2.29.0-3.el8_10.4 + sourcerpm: s390utils-2.29.0-3.el8_10.4.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/sed-4.5-5.el8.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 304464 @@ -4976,27 +5162,27 @@ arches: name: sqlite-libs evr: 3.26.0-20.el8_10 sourcerpm: sqlite-3.26.0-20.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/systemd-239-82.el8_10.8.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/systemd-239-82.el8_10.13.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 3520204 - checksum: sha256:dd8d041a9dc0c0657ba446245f36e2aef4dfe36821d7678df431cc91e1389a44 + size: 3522640 + checksum: sha256:719d568c6145a738905efddd2aae97cf295f4217995871e97ebd314f3258ff8b name: systemd - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/systemd-libs-239-82.el8_10.8.s390x.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/systemd-libs-239-82.el8_10.13.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 1065440 - checksum: sha256:233b13eae1aa0000b2deafd6d1e95e6dfa352887833a710794ad9ce62f4aa027 + size: 1067400 + checksum: sha256:a2e67d8e9a6c1cc3a02c3fce2923b0c918a6d0cb612fda63f375162404f489c8 name: systemd-libs - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/systemd-pam-239-82.el8_10.8.s390x.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/s/systemd-pam-239-82.el8_10.13.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 487296 - checksum: sha256:0ef21f20d6154582fc178ecb94e9a326b53357ccd54e3c16eaa8d4dbad8cef34 + size: 488896 + checksum: sha256:5438bba37b2ab629d5c7bfb9c4f99a48e28c0bdc7edb2e058f59ed07118accc1 name: systemd-pam - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/t/tar-1.30-11.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 852716 @@ -5025,13 +5211,13 @@ arches: name: tzdata evr: 2025c-1.el8 sourcerpm: tzdata-2025c-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/u/util-linux-2.32.1-47.el8_10.s390x.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/u/util-linux-2.32.1-48.el8_10.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms - size: 2497388 - checksum: sha256:b3adf172d10ca587a37806ba7f0ae4a65caaee9836014498b998a2a214e24d6b + size: 2498196 + checksum: sha256:fcd7fa1b6fcc7e68831ad1fa49b14cd5f908fc5d47d0e80bb7dcf1ca38c5ea86 name: util-linux - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/os/Packages/x/xz-libs-5.2.4-4.el8_6.s390x.rpm repoid: rhel-8-for-s390x-baseos-rpms size: 95736 @@ -5059,6 +5245,12 @@ arches: checksum: sha256:ca72f33bbbdd245bf1d2385e5f934d36b0ebdc9854b242fce7be0bb56bfa8255 name: libxkbcommon evr: 0.9.1-1.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/m/mpdecimal-2.5.1-3.el8.src.rpm + repoid: rhel-8-for-s390x-appstream-source-rpms + size: 3333112 + checksum: sha256:36811086e6cf10de04a5cfcbc3599228e073a44e032fac74d72857c970f06cae + name: mpdecimal + evr: 2.5.1-3.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/o/oniguruma-6.8.2-3.el8.src.rpm repoid: rhel-8-for-s390x-appstream-source-rpms size: 982385 @@ -5113,12 +5305,30 @@ arches: checksum: sha256:dc91b0b1230e700b03f6bf9b67e7e1888a40fb3cba04407be800ebe03b3f6632 name: perl-libnet evr: 3.11-3.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm repoid: rhel-8-for-s390x-appstream-source-rpms - size: 53572917 - checksum: sha256:4a2c66b6b48cbf761ed5d454022f80fd6e63f89a84f095dac2683663960e9272 + size: 45654458 + checksum: sha256:30795de4ed7a01becc64ee50796e7c76b9195ff1eed0a341b279aeb3e4b15527 name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/p/python3.12-3.12.12-2.el8_10.src.rpm + repoid: rhel-8-for-s390x-appstream-source-rpms + size: 20872264 + checksum: sha256:351a9a7709a0e1f8c6c80c39d6c47f7e5f8b4a52a1e0eb86eaa023661fe385fa + name: python3.12 + evr: 3.12.12-2.el8_10 + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/p/python3.12-pip-23.2.1-4.el8.src.rpm + repoid: rhel-8-for-s390x-appstream-source-rpms + size: 9393232 + checksum: sha256:5661eadc28225da228c8a053fe6606cd2159238a469bc9a55fce9dbebb5e2232 + name: python3.12-pip + evr: 23.2.1-4.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/p/python3.12-pyyaml-6.0.1-2.el8.src.rpm + repoid: rhel-8-for-s390x-appstream-source-rpms + size: 131090 + checksum: sha256:4254452a01f54622981f2716889690c281d1a5352ec07dbc919c96c3724ff7dc + name: python3.12-pyyaml + evr: 6.0.1-2.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/source/SRPMS/Packages/x/xkeyboard-config-2.28-1.el8.src.rpm repoid: rhel-8-for-s390x-appstream-source-rpms size: 1699339 @@ -5155,12 +5365,12 @@ arches: checksum: sha256:f0e4182affffe350e5dbd55e410baed663d514cd6832108b83899ac8d1524830 name: bash evr: 4.4.20-6.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/b/brotli-1.0.6-3.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/b/brotli-1.0.6-4.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 23835509 - checksum: sha256:d269796bbd35c8ef524e4070d347f8b74cf1f10caa1bd4b19c30d69f24761f2a + size: 23845976 + checksum: sha256:87db48ae61691c6d457824c9391839cff50a576d03f17fe710f745e93050b826 name: brotli - evr: 1.0.6-3.el8 + evr: 1.0.6-4.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/b/bzip2-1.0.6-28.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 807250 @@ -5293,12 +5503,12 @@ arches: checksum: sha256:e91abeb46538fc264936c0eed825c28eab9eef47288c9eb1d2d4d078bccad5d1 name: gdbm evr: 1:1.18-2.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/g/glib2-2.56.4-167.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/g/glib2-2.56.4-168.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 7164394 - checksum: sha256:80ee50b39aa478e1503dbd18626df91a023d30e3f9b6fb588fa82e6ce2b5972e + size: 7169961 + checksum: sha256:6b67584ae03d06c58331b29141f63b0b86e256ddef78ec9c48f80bdfcdb76890 name: glib2 - evr: 2.56.4-167.el8_10 + evr: 2.56.4-168.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/g/glibc-2.28-251.el8_10.27.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 18525139 @@ -5443,12 +5653,12 @@ arches: checksum: sha256:322f0b9e2a909001e5e688b8ad52a5e6361ab350fa4fced3f446a6d1a3f2074a name: libseccomp evr: 2.5.2-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/libselinux-2.9-10.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/libselinux-2.9-11.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 355220 - checksum: sha256:2f61feb51798629d4f7b78130e68eb2516463da41d6e7b64d82d28d17355b3f1 + size: 355013 + checksum: sha256:47297c6a5ffa7556e1a19ac8f65b593f0cbb403cc743fde89e3c9a0424b1b0fc name: libselinux - evr: 2.9-10.el8_10 + evr: 2.9-11.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/libsemanage-2.9-12.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 268557 @@ -5515,18 +5725,24 @@ arches: checksum: sha256:a236b9807436c13e06c88926d7d3b25c2746f5b7fb12fadc41462a00d448a1f7 name: libxml2 evr: 2.9.7-21.el8_10.3 + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/libyaml-0.1.7-5.el8.src.rpm + repoid: rhel-8-for-s390x-baseos-source-rpms + size: 540142 + checksum: sha256:5053fdb2c1384f513795f67c997eef3bc41290958ed8da17cf19edebc3dfdc83 + name: libyaml + evr: 0.1.7-5.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/lua-5.3.4-12.el8.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 437265 checksum: sha256:764fa61f3a6678bf93d94351468e49863176420688ab4e8c1aa6a5eb84ecf23d name: lua evr: 5.3.4-12.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.2.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.3.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 3185875 - checksum: sha256:c464de2287071dd2c498af02ce271d6153a354bfbce16b271c7131f98a55f8c8 + size: 3196004 + checksum: sha256:350e26dbc6f830fdb3548319013264cb2049858907c093a90b84a5945f6a4835 name: lvm2 - evr: 8:2.03.14-15.el8_10.2 + evr: 8:2.03.14-15.el8_10.3 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/l/lz4-1.8.3-5.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 347074 @@ -5797,12 +6013,12 @@ arches: checksum: sha256:31ae9c84f36f7d4e51b0e945e5d12210594defd3ea16cf5645c21d42fd6332fa name: python-setuptools evr: 39.2.0-9.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/p/python3-3.6.8-71.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/p/python3-3.6.8-73.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 19241145 - checksum: sha256:e7012ea23f3816772d64357f7db534f83c55279bcbefdecaefe2573d4734c6a3 + size: 19249994 + checksum: sha256:a4ffe561e7b271c2c78df1a1689e853315c6359c98c85f89e1dd067e634c0b51 name: python3 - evr: 3.6.8-71.el8_10 + evr: 3.6.8-73.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/r/readline-7.0-10.el8.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 2937518 @@ -5821,12 +6037,12 @@ arches: checksum: sha256:b43436849f8b9fa3dfe8e42e87e814906f0cae191f9d159ea24ec9732d379d58 name: rpm evr: 4.14.3-32.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/s/s390utils-2.29.0-3.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/s/s390utils-2.29.0-3.el8_10.4.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 27795142 - checksum: sha256:ee27d86404b429c452229c5e70454c4d603efd184f73ee5b4b4ad14cc78e0975 + size: 27796762 + checksum: sha256:c523f6478162307d458dea9c5880fe9be30a99ca65f201b9b466d70962823edb name: s390utils - evr: 2:2.29.0-3.el8_10.3 + evr: 2:2.29.0-3.el8_10.4 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/s/sed-4.5-5.el8.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 1358944 @@ -5863,12 +6079,12 @@ arches: checksum: sha256:26dc49ea369dc145166e0a3959cc132f45e3345b99a75420c8932af24f44668c name: sqlite evr: 3.26.0-20.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.13.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 9188443 - checksum: sha256:a3ade60f73bb3137b94ac38205c321511b70e2bf61b79e2a25e31015fb415844 + size: 9204931 + checksum: sha256:6176d1736de4a4ff55021f7ad56e8cf5fdb459514f2ac45422c41bbfd5957a7b name: systemd - evr: 239-82.el8_10.8 + evr: 239-82.el8_10.13 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/t/tar-1.30-11.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 2173356 @@ -5893,12 +6109,12 @@ arches: checksum: sha256:c9798a08b98344921713d3183bda98727df494d83f96924604b6b755ddc30f61 name: tzdata evr: 2025c-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-47.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-48.el8_10.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms - size: 4817466 - checksum: sha256:e10e379f1386bdd6315e20cf735616747690c137ada562f47da85ca90ea966ee + size: 4820524 + checksum: sha256:c3ef99808b2afcaf8a5cf2dfef379980779bc1bee42688006fa22b5806b3471d name: util-linux - evr: 2.32.1-47.el8_10 + evr: 2.32.1-48.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/baseos/source/SRPMS/Packages/x/xz-5.2.4-4.el8_6.src.rpm repoid: rhel-8-for-s390x-baseos-source-rpms size: 1077113 @@ -5918,10 +6134,10 @@ arches: name: zstd evr: 1.4.4-1.el8 module_metadata: - - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/repodata/2aab1f5f2b7b1ae8a7f1106bb2ffc435b97804e418e7c63776b5dc8dca03888b-modules.yaml.gz + - url: https://cdn.redhat.com/content/dist/rhel8/8/s390x/appstream/os/repodata/d5f03c5acc6abbbeca6427f759aa0959efb8f9f3e4f48f594e1b0e35eae01b85-modules.yaml.gz repoid: rhel-8-for-s390x-appstream-rpms - size: 755049 - checksum: sha256:2aab1f5f2b7b1ae8a7f1106bb2ffc435b97804e418e7c63776b5dc8dca03888b + size: 763388 + checksum: sha256:d5f03c5acc6abbbeca6427f759aa0959efb8f9f3e4f48f594e1b0e35eae01b85 - arch: x86_64 packages: - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/j/jq-1.6-11.el8_10.x86_64.rpm @@ -5938,6 +6154,13 @@ arches: name: libxkbcommon evr: 0.9.1-1.el8 sourcerpm: libxkbcommon-0.9.1-1.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/m/mpdecimal-2.5.1-3.el8.x86_64.rpm + repoid: rhel-8-for-x86_64-appstream-rpms + size: 95204 + checksum: sha256:fd75319ca80fbfbf4ef5abe886033586aed718ed10e56ec42a345f56c1ca72b6 + name: mpdecimal + evr: 2.5.1-3.el8 + sourcerpm: mpdecimal-2.5.1-3.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/o/oniguruma-6.8.2-3.el8.x86_64.rpm repoid: rhel-8-for-x86_64-appstream-rpms size: 192632 @@ -5945,20 +6168,48 @@ arches: name: oniguruma evr: 6.8.2-3.el8 sourcerpm: oniguruma-6.8.2-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.x86_64.rpm repoid: rhel-8-for-x86_64-appstream-rpms - size: 1813083 - checksum: sha256:c2cf4c01ed074e4516957fb5f846e667b47a5743d99897713906f0d45290477f + size: 1825339 + checksum: sha256:f2a10392b2b79daaa1d16f10792f51abe4d1a2bbb1478827fd96a2d70b943d52 name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/postgresql-private-libs-15.14-1.module+el8.10.0+23423+5a199198.x86_64.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/postgresql-private-libs-15.15-1.module+el8.10.0+23782+2d6b2a31.x86_64.rpm repoid: rhel-8-for-x86_64-appstream-rpms - size: 135811 - checksum: sha256:81a9c927ccdca57c8087daebdda3727b4324089c86da2f748b567d200b4b17a4 + size: 136383 + checksum: sha256:895d79b877c063d33ef9806403e5a70815e7c5720556dd93b1aa3d041b1703e8 name: postgresql-private-libs - evr: 15.14-1.module+el8.10.0+23423+5a199198 - sourcerpm: postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + sourcerpm: postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/python3.12-3.12.12-2.el8_10.x86_64.rpm + repoid: rhel-8-for-x86_64-appstream-rpms + size: 31060 + checksum: sha256:b458899e3d6e996a40eb3cf6a2a22ba94409c6e2dcfd1869906ab64693ef89fd + name: python3.12 + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/python3.12-libs-3.12.12-2.el8_10.x86_64.rpm + repoid: rhel-8-for-x86_64-appstream-rpms + size: 10505652 + checksum: sha256:2255595029fd10fca1f7f2964e92f2211df2c835ea168b0d17019dddf00c918c + name: python3.12-libs + evr: 3.12.12-2.el8_10 + sourcerpm: python3.12-3.12.12-2.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/python3.12-pip-wheel-23.2.1-4.el8.noarch.rpm + repoid: rhel-8-for-x86_64-appstream-rpms + size: 1539820 + checksum: sha256:c5daaf3d7ef6c52f178ec6c20e49fa9ddb4506f1b0ee5cd1688046c28eb5e1cb + name: python3.12-pip-wheel + evr: 23.2.1-4.el8 + sourcerpm: python3.12-pip-23.2.1-4.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/p/python3.12-pyyaml-6.0.1-2.el8.x86_64.rpm + repoid: rhel-8-for-x86_64-appstream-rpms + size: 208020 + checksum: sha256:9ccc9476927eba0e14c39897bb0a7b5e4b3d5fc95586871b579cdb39341c3cc8 + name: python3.12-pyyaml + evr: 6.0.1-2.el8 + sourcerpm: python3.12-pyyaml-6.0.1-2.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/Packages/x/xkeyboard-config-2.28-1.el8.noarch.rpm repoid: rhel-8-for-x86_64-appstream-rpms size: 801000 @@ -5994,13 +6245,13 @@ arches: name: bash evr: 4.4.20-6.el8_10 sourcerpm: bash-4.4.20-6.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/b/brotli-1.0.6-3.el8.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/b/brotli-1.0.6-4.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 330860 - checksum: sha256:267858a95e543459a0cd683e641955d7c04c13bcda830c5f7db5a0529077428a + size: 329804 + checksum: sha256:b63f101a1601c54f8cc953e6251c1481ff05088bf788c5697e75711a6b5f8716 name: brotli - evr: 1.0.6-3.el8 - sourcerpm: brotli-1.0.6-3.el8.src.rpm + evr: 1.0.6-4.el8_10 + sourcerpm: brotli-1.0.6-4.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/b/bzip2-libs-1.0.6-28.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 49384 @@ -6127,20 +6378,20 @@ arches: name: dbus-tools evr: 1:1.12.8-27.el8_10 sourcerpm: dbus-1.12.8-27.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.2.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/d/device-mapper-1.02.181-15.el8_10.3.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 388312 - checksum: sha256:27d2bc6fa33c8b98a37e29161a78ed505c27ecc7daaa10517cdcacc2f99ebbbf + size: 387384 + checksum: sha256:05cb08497da4dbfb3074826936eabb3ef0eee0f8908021efa2a88157951de82b name: device-mapper - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.2.x86_64.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/d/device-mapper-libs-1.02.181-15.el8_10.3.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 421472 - checksum: sha256:87b14770a42ae859889e69bd29b9d368e080e0635b86d6d651d84aa0949255d5 + size: 420456 + checksum: sha256:c47db9dc78ddb13dae0be22de6ea1d5df56c2f0754d99c5b45e6642717ed3508 name: device-mapper-libs - evr: 8:1.02.181-15.el8_10.2 - sourcerpm: lvm2-2.03.14-15.el8_10.2.src.rpm + evr: 8:1.02.181-15.el8_10.3 + sourcerpm: lvm2-2.03.14-15.el8_10.3.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/d/diffutils-3.6-6.el8.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 367420 @@ -6253,13 +6504,13 @@ arches: name: gettext-libs evr: 0.19.8.1-17.el8 sourcerpm: gettext-0.19.8.1-17.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/g/glib2-2.56.4-167.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/g/glib2-2.56.4-168.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 2614852 - checksum: sha256:c3f59a03d02b1ee00cca137485a66b63842e395eca465f0663426ac6933bd6ff + size: 2615096 + checksum: sha256:5cf4e3858b66203dab484bb768c4e59c7c5c5061dd9d635c60406e9369f9a7d3 name: glib2 - evr: 2.56.4-167.el8_10 - sourcerpm: glib2-2.56.4-167.el8_10.src.rpm + evr: 2.56.4-168.el8_10 + sourcerpm: glib2-2.56.4-168.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/g/glibc-2.28-251.el8_10.27.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 2307356 @@ -6442,13 +6693,13 @@ arches: name: libattr evr: 2.4.48-3.el8 sourcerpm: attr-2.4.48-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libblkid-2.32.1-47.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libblkid-2.32.1-48.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 225348 - checksum: sha256:d20de50e05c6c7a6a3232c57ba69a2e62d0aebe4ebe5540f6b4776eb762465a8 + size: 225512 + checksum: sha256:1ea002cffcfbccaa258fffebb05bee62ec92b6ca6c3204b2eece0d3142122912 name: libblkid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libcap-2.48-6.el8_9.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 76264 @@ -6498,13 +6749,13 @@ arches: name: libdb-utils evr: 5.3.28-42.el8_4 sourcerpm: libdb-5.3.28-42.el8_4.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libfdisk-2.32.1-47.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libfdisk-2.32.1-48.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 259176 - checksum: sha256:93d94607b800a70cffe242fdaf13ebcf9a62eb77aa98564bab7087f86a8e0832 + size: 259376 + checksum: sha256:59733655dc4a424ab2314895e5c2f7e274180bb092b65167cbf23e5634662a0a name: libfdisk - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libffi-3.1-24.el8.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 38584 @@ -6561,13 +6812,13 @@ arches: name: libkcapi-hmaccalc evr: 1.4.0-2.el8 sourcerpm: libkcapi-1.4.0-2.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libmount-2.32.1-47.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libmount-2.32.1-48.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 241732 - checksum: sha256:c92289f2e195e15fece08617be1d675abfd513109a0bd14c5cf45fcd68fb84a9 + size: 241976 + checksum: sha256:41bf9c5ca51eee9e986e5abf81d10fa3e5abe93b0a11d1cd9e0ca4f59f6d7322 name: libmount - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libnghttp2-1.33.0-6.el8_10.1.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 80224 @@ -6603,13 +6854,13 @@ arches: name: libseccomp evr: 2.5.2-1.el8 sourcerpm: libseccomp-2.5.2-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libselinux-2.9-10.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libselinux-2.9-11.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 170016 - checksum: sha256:41c31dde6e5e6928f66f5541586a2ed32bb088e8e5585dd6ce1d60c04e1d667f + size: 169076 + checksum: sha256:25684acd2c63eefb918c076f2fe1f12597edbc620aacd63987d4211dc1c788fa name: libselinux - evr: 2.9-10.el8_10 - sourcerpm: libselinux-2.9-10.el8_10.src.rpm + evr: 2.9-11.el8_10 + sourcerpm: libselinux-2.9-11.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libsemanage-2.9-12.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 173008 @@ -6631,13 +6882,13 @@ arches: name: libsigsegv evr: 2.11-5.el8 sourcerpm: libsigsegv-2.11-5.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libsmartcols-2.32.1-47.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libsmartcols-2.32.1-48.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 183072 - checksum: sha256:7203046a7bbf0c72965933901614a682a220800c43f69748f8a4cb209193061c + size: 183356 + checksum: sha256:c33ea3acbc4eaeb7b5b9d72e683769665931e8839d13e9ccb0da4dcfaa1a3e16 name: libsmartcols - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libssh-0.9.6-16.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 224400 @@ -6687,13 +6938,13 @@ arches: name: libutempter evr: 1.1.6-14.el8 sourcerpm: libutempter-1.1.6-14.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libuuid-2.32.1-47.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libuuid-2.32.1-48.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 100768 - checksum: sha256:9ba65072e9949c2c6dfa85b8daa36292264f4c3e6a35a515b6ef572d3405aaba + size: 100956 + checksum: sha256:111e2fa9fc01063230326f03b6fc810ad1f01353b8102ab470b828102a535c0c name: libuuid - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libverto-0.3.2-2.el8.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 24636 @@ -6715,6 +6966,13 @@ arches: name: libxml2 evr: 2.9.7-21.el8_10.3 sourcerpm: libxml2-2.9.7-21.el8_10.3.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libyaml-0.1.7-5.el8.x86_64.rpm + repoid: rhel-8-for-x86_64-baseos-rpms + size: 62872 + checksum: sha256:018409b1eda8be48a11a5b76b95e82ff1d9002569e0644291532d8424dc31edf + name: libyaml + evr: 0.1.7-5.el8 + sourcerpm: libyaml-0.1.7-5.el8.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/l/libzstd-1.4.4-1.el8.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 272364 @@ -6806,13 +7064,13 @@ arches: name: openssl-pkcs11 evr: 0.4.10-3.el8 sourcerpm: openssl-pkcs11-0.4.10-3.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/o/os-prober-1.74-9.el8.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/o/os-prober-1.74-11.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 52600 - checksum: sha256:2711faf7ba62de2e1b8254f1787be9be2e1354cc43a64af2744f32f16877ebfd + size: 52056 + checksum: sha256:e39e4cd7ded77fdb9832d05884a5c8cd911493613ca51788f58bfc2f87951241 name: os-prober - evr: 1.74-9.el8 - sourcerpm: os-prober-1.74-9.el8.src.rpm + evr: 1.74-11.el8_10 + sourcerpm: os-prober-1.74-11.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/p/p11-kit-0.23.22-2.el8.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 334852 @@ -6855,13 +7113,13 @@ arches: name: pigz evr: 2.4-4.el8 sourcerpm: pigz-2.4-4.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/p/platform-python-3.6.8-71.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/p/platform-python-3.6.8-73.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 89788 - checksum: sha256:225f9e81e7ff60618c43bdb2fd9d46b43c1ec7d195faf7704dacead5f6bbffe4 + size: 90076 + checksum: sha256:01e3c8ed4a6879438fd11806643824c65883cfd90f9562ef10f82d31ee57bfcf name: platform-python - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/p/platform-python-pip-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 1633024 @@ -6897,13 +7155,13 @@ arches: name: publicsuffix-list-dafsa evr: 20180723-1.el8 sourcerpm: publicsuffix-list-20180723-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/p/python3-libs-3.6.8-71.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/p/python3-libs-3.6.8-73.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 8250824 - checksum: sha256:b80ef80e565941803678ce69506358c269cb2d02a862642199a5b22d20ca52a4 + size: 8252760 + checksum: sha256:6e343ede74cd599cc8bc8674260e4c7b4b3d1686256522c8c154a771ec0c5314 name: python3-libs - evr: 3.6.8-71.el8_10 - sourcerpm: python3-3.6.8-71.el8_10.src.rpm + evr: 3.6.8-73.el8_10 + sourcerpm: python3-3.6.8-73.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/p/python3-pip-wheel-9.0.3-24.el8.noarch.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 886996 @@ -6988,34 +7246,34 @@ arches: name: sqlite-libs evr: 3.26.0-20.el8_10 sourcerpm: sqlite-3.26.0-20.el8_10.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-239-82.el8_10.8.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-239-82.el8_10.13.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 3828188 - checksum: sha256:f4610daaffe36789deafdead6dfb621e1e722b151541bf259bffcaf892ce9bb2 + size: 3830800 + checksum: sha256:30e7904ba7d991dd821d4be6cfee6dc6db5a65a8bd6e482502e6d2d6e71c58e9 name: systemd - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-libs-239-82.el8_10.8.x86_64.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-libs-239-82.el8_10.13.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 1197600 - checksum: sha256:d77b012f317bb7736f25e2b03bc912f983bb265c4447890eb41a009ce3f5fa56 + size: 1199360 + checksum: sha256:af1bc1cd605f1e08f6e7a3e073338565f8608b2a74232be9892a047f88524128 name: systemd-libs - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-pam-239-82.el8_10.8.x86_64.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-pam-239-82.el8_10.13.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 527476 - checksum: sha256:41a9be02b2a65f87bdf1546a3a034c5cd5aea85e187e9e1bc45efbe30897b3ee + size: 529240 + checksum: sha256:b1d738e31d1db8c3759f5e9913fcc7ec7b1fbfd90a2f271d18f8a30ca050e57a name: systemd-pam - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-udev-239-82.el8_10.8.x86_64.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/s/systemd-udev-239-82.el8_10.13.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 1665148 - checksum: sha256:c6b70e68144dc63475ef6bc43eb1483dd9b06b56929d1d22f660ebfe871f487b + size: 1666576 + checksum: sha256:c0a90b3e83143b2160a1e850502e54299986fe29e0382c297f7d0121e1aed4f7 name: systemd-udev - evr: 239-82.el8_10.8 - sourcerpm: systemd-239-82.el8_10.8.src.rpm + evr: 239-82.el8_10.13 + sourcerpm: systemd-239-82.el8_10.13.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/t/trousers-0.3.15-2.el8.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 156324 @@ -7037,13 +7295,13 @@ arches: name: tzdata evr: 2025c-1.el8 sourcerpm: tzdata-2025c-1.el8.src.rpm - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/u/util-linux-2.32.1-47.el8_10.x86_64.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/u/util-linux-2.32.1-48.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms - size: 2596592 - checksum: sha256:4861ff37cf00bd0bab78a81004dfed1e7b0ee5355403510b9e78e2a90fc7226c + size: 2597936 + checksum: sha256:16f51c38ab76c0a1bfb1c9da94d48946a48d94367096ef855343db11574f5aca name: util-linux - evr: 2.32.1-47.el8_10 - sourcerpm: util-linux-2.32.1-47.el8_10.src.rpm + evr: 2.32.1-48.el8_10 + sourcerpm: util-linux-2.32.1-48.el8_10.src.rpm - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/Packages/w/which-2.21-21.el8_10.x86_64.rpm repoid: rhel-8-for-x86_64-baseos-rpms size: 51220 @@ -7085,18 +7343,42 @@ arches: checksum: sha256:ca72f33bbbdd245bf1d2385e5f934d36b0ebdc9854b242fce7be0bb56bfa8255 name: libxkbcommon evr: 0.9.1-1.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/m/mpdecimal-2.5.1-3.el8.src.rpm + repoid: rhel-8-for-x86_64-appstream-source-rpms + size: 3333112 + checksum: sha256:36811086e6cf10de04a5cfcbc3599228e073a44e032fac74d72857c970f06cae + name: mpdecimal + evr: 2.5.1-3.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/o/oniguruma-6.8.2-3.el8.src.rpm repoid: rhel-8-for-x86_64-appstream-source-rpms size: 982385 checksum: sha256:31cd372131f6eb404ce90285210fd74021914b4eb52e933b2aeebfa955099faa name: oniguruma evr: 6.8.2-3.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/p/postgresql-15.14-1.module+el8.10.0+23423+5a199198.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/p/postgresql-15.15-1.module+el8.10.0+23782+2d6b2a31.src.rpm repoid: rhel-8-for-x86_64-appstream-source-rpms - size: 53572917 - checksum: sha256:4a2c66b6b48cbf761ed5d454022f80fd6e63f89a84f095dac2683663960e9272 + size: 45654458 + checksum: sha256:30795de4ed7a01becc64ee50796e7c76b9195ff1eed0a341b279aeb3e4b15527 name: postgresql - evr: 15.14-1.module+el8.10.0+23423+5a199198 + evr: 15.15-1.module+el8.10.0+23782+2d6b2a31 + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/p/python3.12-3.12.12-2.el8_10.src.rpm + repoid: rhel-8-for-x86_64-appstream-source-rpms + size: 20872264 + checksum: sha256:351a9a7709a0e1f8c6c80c39d6c47f7e5f8b4a52a1e0eb86eaa023661fe385fa + name: python3.12 + evr: 3.12.12-2.el8_10 + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/p/python3.12-pip-23.2.1-4.el8.src.rpm + repoid: rhel-8-for-x86_64-appstream-source-rpms + size: 9393232 + checksum: sha256:5661eadc28225da228c8a053fe6606cd2159238a469bc9a55fce9dbebb5e2232 + name: python3.12-pip + evr: 23.2.1-4.el8 + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/p/python3.12-pyyaml-6.0.1-2.el8.src.rpm + repoid: rhel-8-for-x86_64-appstream-source-rpms + size: 131090 + checksum: sha256:4254452a01f54622981f2716889690c281d1a5352ec07dbc919c96c3724ff7dc + name: python3.12-pyyaml + evr: 6.0.1-2.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/source/SRPMS/Packages/x/xkeyboard-config-2.28-1.el8.src.rpm repoid: rhel-8-for-x86_64-appstream-source-rpms size: 1699339 @@ -7133,12 +7415,12 @@ arches: checksum: sha256:f0e4182affffe350e5dbd55e410baed663d514cd6832108b83899ac8d1524830 name: bash evr: 4.4.20-6.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/b/brotli-1.0.6-3.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/b/brotli-1.0.6-4.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 23835509 - checksum: sha256:d269796bbd35c8ef524e4070d347f8b74cf1f10caa1bd4b19c30d69f24761f2a + size: 23845976 + checksum: sha256:87db48ae61691c6d457824c9391839cff50a576d03f17fe710f745e93050b826 name: brotli - evr: 1.0.6-3.el8 + evr: 1.0.6-4.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/b/bzip2-1.0.6-28.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 807250 @@ -7283,12 +7565,12 @@ arches: checksum: sha256:114be9b072a7726f2ac557fda6b8a86254ae3b7ed984ed14cfa7733bea9005d4 name: gettext evr: 0.19.8.1-17.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/g/glib2-2.56.4-167.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/g/glib2-2.56.4-168.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 7164394 - checksum: sha256:80ee50b39aa478e1503dbd18626df91a023d30e3f9b6fb588fa82e6ce2b5972e + size: 7169961 + checksum: sha256:6b67584ae03d06c58331b29141f63b0b86e256ddef78ec9c48f80bdfcdb76890 name: glib2 - evr: 2.56.4-167.el8_10 + evr: 2.56.4-168.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/g/glibc-2.28-251.el8_10.27.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 18525139 @@ -7451,12 +7733,12 @@ arches: checksum: sha256:322f0b9e2a909001e5e688b8ad52a5e6361ab350fa4fced3f446a6d1a3f2074a name: libseccomp evr: 2.5.2-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/libselinux-2.9-10.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/libselinux-2.9-11.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 355220 - checksum: sha256:2f61feb51798629d4f7b78130e68eb2516463da41d6e7b64d82d28d17355b3f1 + size: 355013 + checksum: sha256:47297c6a5ffa7556e1a19ac8f65b593f0cbb403cc743fde89e3c9a0424b1b0fc name: libselinux - evr: 2.9-10.el8_10 + evr: 2.9-11.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/libsemanage-2.9-12.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 268557 @@ -7523,18 +7805,24 @@ arches: checksum: sha256:a236b9807436c13e06c88926d7d3b25c2746f5b7fb12fadc41462a00d448a1f7 name: libxml2 evr: 2.9.7-21.el8_10.3 + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/libyaml-0.1.7-5.el8.src.rpm + repoid: rhel-8-for-x86_64-baseos-source-rpms + size: 540142 + checksum: sha256:5053fdb2c1384f513795f67c997eef3bc41290958ed8da17cf19edebc3dfdc83 + name: libyaml + evr: 0.1.7-5.el8 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/lua-5.3.4-12.el8.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 437265 checksum: sha256:764fa61f3a6678bf93d94351468e49863176420688ab4e8c1aa6a5eb84ecf23d name: lua evr: 5.3.4-12.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.2.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/lvm2-2.03.14-15.el8_10.3.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 3185875 - checksum: sha256:c464de2287071dd2c498af02ce271d6153a354bfbce16b271c7131f98a55f8c8 + size: 3196004 + checksum: sha256:350e26dbc6f830fdb3548319013264cb2049858907c093a90b84a5945f6a4835 name: lvm2 - evr: 8:2.03.14-15.el8_10.2 + evr: 8:2.03.14-15.el8_10.3 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/l/lz4-1.8.3-5.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 347074 @@ -7589,12 +7877,12 @@ arches: checksum: sha256:a737e7fe890c5f53c1bc0c5925375791d8890f9d51c4a509091b41efa3f92861 name: openssl-pkcs11 evr: 0.4.10-3.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/o/os-prober-1.74-9.el8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/o/os-prober-1.74-11.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 55171 - checksum: sha256:0577008638e1644fed230d55b221b485e6cdc702cda9c27cf74ab7adcb8b8f00 + size: 55952 + checksum: sha256:602a6f146d9b36de4d52f744ad8d4084b87515e16a04c98c7d21368e7351194e name: os-prober - evr: 1.74-9.el8 + evr: 1.74-11.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/p/p11-kit-0.23.22-2.el8.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 909983 @@ -7655,12 +7943,12 @@ arches: checksum: sha256:31ae9c84f36f7d4e51b0e945e5d12210594defd3ea16cf5645c21d42fd6332fa name: python-setuptools evr: 39.2.0-9.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/p/python3-3.6.8-71.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/p/python3-3.6.8-73.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 19241145 - checksum: sha256:e7012ea23f3816772d64357f7db534f83c55279bcbefdecaefe2573d4734c6a3 + size: 19249994 + checksum: sha256:a4ffe561e7b271c2c78df1a1689e853315c6359c98c85f89e1dd067e634c0b51 name: python3 - evr: 3.6.8-71.el8_10 + evr: 3.6.8-73.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/r/readline-7.0-10.el8.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 2937518 @@ -7709,12 +7997,12 @@ arches: checksum: sha256:26dc49ea369dc145166e0a3959cc132f45e3345b99a75420c8932af24f44668c name: sqlite evr: 3.26.0-20.el8_10 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.8.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/s/systemd-239-82.el8_10.13.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 9188443 - checksum: sha256:a3ade60f73bb3137b94ac38205c321511b70e2bf61b79e2a25e31015fb415844 + size: 9204931 + checksum: sha256:6176d1736de4a4ff55021f7ad56e8cf5fdb459514f2ac45422c41bbfd5957a7b name: systemd - evr: 239-82.el8_10.8 + evr: 239-82.el8_10.13 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/t/texinfo-6.5-7.el8.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 4544531 @@ -7733,12 +8021,12 @@ arches: checksum: sha256:c9798a08b98344921713d3183bda98727df494d83f96924604b6b755ddc30f61 name: tzdata evr: 2025c-1.el8 - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-47.el8_10.src.rpm + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/u/util-linux-2.32.1-48.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms - size: 4817466 - checksum: sha256:e10e379f1386bdd6315e20cf735616747690c137ada562f47da85ca90ea966ee + size: 4820524 + checksum: sha256:c3ef99808b2afcaf8a5cf2dfef379980779bc1bee42688006fa22b5806b3471d name: util-linux - evr: 2.32.1-47.el8_10 + evr: 2.32.1-48.el8_10 - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/source/SRPMS/Packages/w/which-2.21-21.el8_10.src.rpm repoid: rhel-8-for-x86_64-baseos-source-rpms size: 171834 @@ -7764,7 +8052,7 @@ arches: name: zstd evr: 1.4.4-1.el8 module_metadata: - - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/repodata/c93f84d60dd3f9517e7fb58a40d7b88b99fca36bfc2b19cfdb461a6b511993d9-modules.yaml.gz + - url: https://cdn.redhat.com/content/dist/rhel8/8/x86_64/appstream/os/repodata/e3966e91019bcda7a7989f7a65f764cb0b88760fc263ffee2fea6d737b3b7d22-modules.yaml.gz repoid: rhel-8-for-x86_64-appstream-rpms - size: 779063 - checksum: sha256:c93f84d60dd3f9517e7fb58a40d7b88b99fca36bfc2b19cfdb461a6b511993d9 + size: 789386 + checksum: sha256:e3966e91019bcda7a7989f7a65f764cb0b88760fc263ffee2fea6d737b3b7d22 diff --git a/scale/signatures/deploy.yaml b/scale/signatures/deploy.yaml index acfe97d1589c1..82f3d2c843833 100644 --- a/scale/signatures/deploy.yaml +++ b/scale/signatures/deploy.yaml @@ -11,7 +11,7 @@ spec: spec: containers: - name: update-signature - image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 + image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 imagePullPolicy: IfNotPresent command: - /bin/bash diff --git a/scanner/image/db/konflux.Dockerfile b/scanner/image/db/konflux.Dockerfile index 20e9af6d20e25..d424e68aaa314 100644 --- a/scanner/image/db/konflux.Dockerfile +++ b/scanner/image/db/konflux.Dockerfile @@ -1,4 +1,4 @@ -FROM registry.redhat.io/rhel8/postgresql-15:latest@sha256:042f6efe0f16e94ffb2d0a3bede852bb026b6dce661ac5b339e6f63846467b9d +FROM registry.redhat.io/rhel8/postgresql-15:latest@sha256:94182920a14a5175523d40c1bdf1168eaabbb6b494eda0519d3a87916ba937d6 ARG BUILD_TAG RUN if [[ "$BUILD_TAG" == "" ]]; then >&2 echo "error: required BUILD_TAG arg is unset"; exit 6; fi diff --git a/scanner/image/scanner/konflux.Dockerfile b/scanner/image/scanner/konflux.Dockerfile index b0c4519d56dbd..2f7e183c28239 100644 --- a/scanner/image/scanner/konflux.Dockerfile +++ b/scanner/image/scanner/konflux.Dockerfile @@ -1,4 +1,4 @@ -FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:527782f4a0270f786192281f68d0374f4a21b3ab759643eee4bfcafb6f539468 AS builder +FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_8_golang_1.25@sha256:aa03597ee8c7594ffecef5cbb6a0f059d362259d2a41225617b27ec912a3d0d3 AS builder ARG BUILD_TAG RUN if [[ "$BUILD_TAG" == "" ]]; then >&2 echo "error: required BUILD_TAG arg is unset"; exit 6; fi @@ -17,7 +17,7 @@ WORKDIR /src RUN make -C scanner NODEPS=1 CGO_ENABLED=1 image/scanner/bin/scanner copy-scripts -FROM registry.access.redhat.com/ubi8-minimal:latest@sha256:a670c5b613280e17a666c858c9263a50aafe1a023a8d5730c7a83cb53771487b +FROM registry.access.redhat.com/ubi8-minimal:latest@sha256:48adecc91f276734fa51987bc2203a31db9ba87a512c436c0a3fcac53135378d ARG BUILD_TAG diff --git a/scripts/ci/bats/lib_release_version_test.bats b/scripts/ci/bats/lib_release_version_test.bats index 7cb57a68b2da3..07a602fb32faa 100644 --- a/scripts/ci/bats/lib_release_version_test.bats +++ b/scripts/ci/bats/lib_release_version_test.bats @@ -111,6 +111,26 @@ function make() { assert_success } +@test "spots fact tag is a master commit" { + declare -A tags=( [fact-tag]="0.2.x-23-g8a2e05d0ec") + run check_fact_version + assert_failure + assert_output --partial 'Fact tag does not look like a release tag' +} + +@test "spots fact tag is a release candidate" { + declare -A tags=( [fact-tag]="0.2.1-rc.1") + run check_fact_version + assert_failure + assert_output --partial 'Fact tag does not look like a release tag' +} + +@test "spots fact tag is a release" { + declare -A tags=( [fact-tag]="0.2.1") + run check_fact_version + assert_success +} + @test "spots scanner tag is a master commit" { declare -A tags=( [scanner-tag]="3.45.x-12-g8a2e05d0ec") run check_scanner_version diff --git a/scripts/ci/lib.sh b/scripts/ci/lib.sh index c4bb6682f913e..e78a02e488513 100755 --- a/scripts/ci/lib.sh +++ b/scripts/ci/lib.sh @@ -254,8 +254,8 @@ push_image_manifest_lists() { fi done - # Push manifest lists for scanner and collector for amd64 only - local amd64_image_set=("scanner" "scanner-db" "scanner-slim" "scanner-db-slim" "collector") + # Push manifest lists for scanner, fact and collector for amd64 only + local amd64_image_set=("scanner" "scanner-db" "scanner-slim" "scanner-db-slim" "collector" "fact") for image in "${amd64_image_set[@]}"; do retry 5 true \ "$SCRIPTS_ROOT/scripts/ci/push-as-multiarch-manifest-list.sh" "${registry}/${image}:${tag}" "amd64" | cat @@ -366,6 +366,13 @@ push_operator_image() { docker tag "${registry}/stackrox-operator:${tag}" "${registry}/stackrox-operator:latest-${arch}" _push_operator_image "$registry" "latest" "$arch" fi + + if [[ $tag =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + # For release builds, also push a major.minor tag, see operator/install/README.md + local major_minor="${tag%.*}" + docker tag "${registry}/stackrox-operator:${tag}" "${registry}/stackrox-operator:${major_minor}-${arch}" + _push_operator_image "$registry" "$major_minor" "$arch" + fi } push_scanner_image_manifest_lists() { @@ -453,6 +460,12 @@ push_operator_manifest_lists() { retry 5 true \ "$SCRIPTS_ROOT/scripts/ci/push-as-multiarch-manifest-list.sh" "${registry}/stackrox-operator:latest" "$architectures" | cat fi + if [[ $tag =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + # For release builds, also push a major.minor tag, see operator/install/README.md + local major_minor="${tag%.*}" + retry 5 true \ + "$SCRIPTS_ROOT/scripts/ci/push-as-multiarch-manifest-list.sh" "${registry}/stackrox-operator:${major_minor}" "$architectures" | cat + fi } registry_rw_login() { @@ -530,6 +543,8 @@ push_matching_collector_scanner_images() { scanner_version="$(make --quiet --no-print-directory scanner-tag)" local collector_version collector_version="$(make --quiet --no-print-directory collector-tag)" + local fact_version + fact_version="$(make --quiet --no-print-directory fact-tag)" registry_rw_login "${registry}" @@ -539,6 +554,8 @@ push_matching_collector_scanner_images() { _retag "${registry}/scanner-db-slim:${scanner_version}" "${registry}/scanner-db-slim:${main_tag}-${arch}" _retag "${registry}/collector:${collector_version}" "${registry}/collector:${main_tag}-${arch}" + + _retag "${registry}/fact:${fact_version}" "${registry}/fact:${main_tag}-${arch}" } poll_for_system_test_images() { @@ -1042,6 +1059,13 @@ check_collector_version() { fi } +check_fact_version() { + if ! is_release_version "$(make --quiet --no-print-directory fact-tag)"; then + echo "::error::Fact tag does not look like a release tag. Please update FACT_VERSION file before releasing." + exit 1 + fi +} + publish_cli() { if [[ "$#" -ne 1 ]]; then die "missing arg. usage: publish_cli " diff --git a/sensor/common/centralcabundle/central_ca_bundle.go b/sensor/common/centralcabundle/central_ca_bundle.go new file mode 100644 index 0000000000000..e0a9d025cb46a --- /dev/null +++ b/sensor/common/centralcabundle/central_ca_bundle.go @@ -0,0 +1,41 @@ +// Package centralcabundle provides a global cache for Central CA certificates obtained via TLSChallenge. +// +// Used by Scanner V4 client to trust both CAs during CA rotation. Global state is used because +// storing secondary-ca.pem in tls-cert-* secrets wouldn't work for Helm deployments (pods don't +// restart to pick up CA changes). +// +// This could be replaced by loading certs from secrets if ROX-29506 (certificate hot reloading) +// is implemented, or if Helm-managed Secured Clusters are deprecated. +package centralcabundle + +import ( + "crypto/x509" + + "github.com/stackrox/rox/pkg/logging" + "github.com/stackrox/rox/pkg/sync" +) + +var ( + log = logging.LoggerForModule() + + caCerts []*x509.Certificate + caCertsMutex sync.RWMutex +) + +// Set stores the Central CA certificates. +func Set(cas []*x509.Certificate) { + caCertsMutex.Lock() + defer caCertsMutex.Unlock() + caCerts = append([]*x509.Certificate(nil), cas...) + if len(cas) > 0 { + log.Infof("Stored %d Central CA certificate(s)", len(cas)) + } +} + +// Get returns a copy of the stored Central CA certificates. +// Returns nil if no CAs have been stored. +func Get() []*x509.Certificate { + caCertsMutex.RLock() + defer caCertsMutex.RUnlock() + return append([]*x509.Certificate(nil), caCerts...) +} diff --git a/sensor/common/centralcabundle/central_ca_bundle_test.go b/sensor/common/centralcabundle/central_ca_bundle_test.go new file mode 100644 index 0000000000000..489232ff222ff --- /dev/null +++ b/sensor/common/centralcabundle/central_ca_bundle_test.go @@ -0,0 +1,38 @@ +package centralcabundle + +import ( + "crypto/x509" + "crypto/x509/pkix" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSetAndGet(t *testing.T) { + Set(nil) + + result := Get() + assert.Empty(t, result) + + certs := []*x509.Certificate{ + {Subject: pkix.Name{CommonName: "CA1"}}, + {Subject: pkix.Name{CommonName: "CA2"}}, + } + Set(certs) + + result = Get() + assert.Len(t, result, 2) + assert.Equal(t, "CA1", result[0].Subject.CommonName) + assert.Equal(t, "CA2", result[1].Subject.CommonName) +} + +func TestSetNilClearsStore(t *testing.T) { + Set([]*x509.Certificate{ + {Subject: pkix.Name{CommonName: "CA1"}}, + }) + + assert.Len(t, Get(), 1) + Set(nil) + + assert.Empty(t, Get()) +} diff --git a/sensor/common/scannerclient/grpc_client.go b/sensor/common/scannerclient/grpc_client.go index 44491ceacb14e..1dd8853914d86 100644 --- a/sensor/common/scannerclient/grpc_client.go +++ b/sensor/common/scannerclient/grpc_client.go @@ -17,6 +17,7 @@ import ( "github.com/stackrox/rox/pkg/registries/types" pkgscanner "github.com/stackrox/rox/pkg/scannerv4" "github.com/stackrox/rox/pkg/scannerv4/client" + "github.com/stackrox/rox/sensor/common/centralcabundle" scannerV1 "github.com/stackrox/scanner/generated/scanner/api/v1" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -156,7 +157,15 @@ func dialV2() (ScannerClient, error) { // dialV4 connect to scanner V4 gRPC and return a new ScannerClient. func dialV4() (ScannerClient, error) { ctx := context.Background() - c, err := client.NewGRPCScanner(ctx, client.WithIndexerAddress(env.ScannerV4IndexerEndpoint.Setting())) + opts := []client.Option{client.WithIndexerAddress(env.ScannerV4IndexerEndpoint.Setting())} + + // Make sure the Scanner V4 client trusts all internal CAs. + if cas := centralcabundle.Get(); len(cas) > 0 { + log.Infof("Adding %d Central CA certificate(s) to Scanner V4 client", len(cas)) + opts = append(opts, client.WithRootCAs(cas...)) + } + + c, err := client.NewGRPCScanner(ctx, opts...) if err != nil { return nil, errors.Wrap(err, "dialing scanner V4 gRPC client") } diff --git a/sensor/common/sensor/central_communication_impl.go b/sensor/common/sensor/central_communication_impl.go index c49af2110af25..103dd15b99776 100644 --- a/sensor/common/sensor/central_communication_impl.go +++ b/sensor/common/sensor/central_communication_impl.go @@ -209,39 +209,35 @@ func (s *centralCommunicationImpl) sendEvents(client central.SensorServiceClient log.Info("Communication with central ended.") } -func (s *centralCommunicationImpl) initialSync(ctx context.Context, stream central.SensorService_CommunicateClient, - hello *central.SensorHello, configHandler config.Handler, detector detector.Detector, -) error { +func (s *centralCommunicationImpl) hello(stream central.SensorService_CommunicateClient, hello *central.SensorHello) error { rawHdr, err := stream.Header() if err != nil { return errors.Wrap(err, "receiving headers from central") } - var centralHello *central.CentralHello + if metautils.MD(rawHdr).Get(centralsensor.SensorHelloMetadataKey) != "true" { + return errors.New("central did not acknowledge SensorHello," + + " likely due to a networking or TLS configuration issue" + + " (e.g., re-encrypt routes or TLS termination)" + + " preventing central from receiving sensor's TLS certificate") + } - hdr := metautils.MD(rawHdr) - if hdr.Get(centralsensor.SensorHelloMetadataKey) == "true" { - // Yay, central supports the "sensor hello" protocol! - err := stream.Send(¢ral.MsgFromSensor{Msg: ¢ral.MsgFromSensor_Hello{Hello: hello}}) - if err != nil { - return errors.Wrap(err, "sending SensorHello message to central") - } + var centralHello *central.CentralHello + err = stream.Send(¢ral.MsgFromSensor{Msg: ¢ral.MsgFromSensor_Hello{Hello: hello}}) + if err != nil { + return errors.Wrap(err, "sending SensorHello message to central") + } - firstMsg, err := stream.Recv() - if err != nil { - return errors.Wrap(err, "receiving first message from central") - } - centralHello = firstMsg.GetHello() - if centralHello == nil { - return errors.Errorf("first message received from central was not CentralHello but of type %T", firstMsg.GetMsg()) - } - } else { - // No sensor hello :( - log.Warn("Central is running a legacy version that might not support all current features") + firstMsg, err := stream.Recv() + if err != nil { + return errors.Wrap(err, "receiving first message from central") + } + centralHello = firstMsg.GetHello() + if centralHello == nil { + return errors.Errorf("first message received from central was not CentralHello but of type %T", firstMsg.GetMsg()) } - clusterID := centralHello.GetClusterId() - s.clusterID.Set(clusterID) + s.clusterID.Set(centralHello.GetClusterId()) if centralHello.GetManagedCentral() { log.Info("Central is managed") @@ -263,10 +259,19 @@ func (s *centralCommunicationImpl) initialSync(ctx context.Context, stream centr strconv.FormatBool(centralHello.GetSendDeduperState())) if hello.GetHelmManagedConfigInit() != nil { - if err := helmconfig.StoreCachedClusterID(clusterID); err != nil { + if err := helmconfig.StoreCachedClusterID(s.clusterID.GetNoWait()); err != nil { log.Warnf("Could not cache cluster ID: %v", err) } } + return nil +} + +func (s *centralCommunicationImpl) initialSync(ctx context.Context, stream central.SensorService_CommunicateClient, + hello *central.SensorHello, configHandler config.Handler, detector detector.Detector, +) error { + if err := s.hello(stream, hello); err != nil { + return errors.Wrap(err, "error while executing the sensor hello protocol") + } // DO NOT CHANGE THE ORDER. Please refer to `Run()` at `central/sensor/service/connection/connection_impl.go` if err := s.initialConfigSync(ctx, stream, configHandler); err != nil { diff --git a/sensor/kubernetes/certrefresh/tls_challenge_cert_loader.go b/sensor/kubernetes/certrefresh/tls_challenge_cert_loader.go index 2b9843a7627f9..ab5d32df71966 100644 --- a/sensor/kubernetes/certrefresh/tls_challenge_cert_loader.go +++ b/sensor/kubernetes/certrefresh/tls_challenge_cert_loader.go @@ -6,6 +6,7 @@ import ( "os" "github.com/stackrox/rox/pkg/pods" + "github.com/stackrox/rox/sensor/common/centralcabundle" "github.com/stackrox/rox/sensor/common/centralclient" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" @@ -13,7 +14,8 @@ import ( // TLSChallengeCertLoader returns a centralclient.CertLoader that: // - performs the TLS challenge with Central and retrieves its trusted certificates -// - ceates/updates CA bundle ConfigMap for Admission Control's ValidatingWebhookConfiguration +// - creates/updates CA bundle ConfigMap for Admission Control's ValidatingWebhookConfiguration +// - stores Central CAs for use by the Scanner V4 client (Scanner V4 might be using a different CA than the one used by Sensor) // This is used for Operator managed clusters to enable CA rotation. func TLSChallengeCertLoader(centralClient *centralclient.Client, k8sClient kubernetes.Interface) centralclient.CertLoader { return func() []*x509.Certificate { @@ -27,6 +29,7 @@ func TLSChallengeCertLoader(centralClient *centralclient.Client, k8sClient kuber } else if len(centralCAs) > 0 { log.Debug("Updating TLS CA bundle ConfigMap from TLSChallenge") handleCABundleConfigMapUpdate(ctx, centralCAs, k8sClient) + centralcabundle.Set(centralCAs) } return certs } diff --git a/tests/e2e/lib.sh b/tests/e2e/lib.sh index 2b088a5689dd4..c6b79a62e01d8 100755 --- a/tests/e2e/lib.sh +++ b/tests/e2e/lib.sh @@ -414,7 +414,7 @@ deploy_sensor_via_operator() { local central_namespace=${2:-stackrox} local validate=${3:-true} local scanner_component_setting="Disabled" - local sfa_agent_setting="Disabled" + local fam_mode_setting="Disabled" local central_endpoint="central.${central_namespace}.svc:443" info "Deploying sensor using operator into namespace ${sensor_namespace} (central is expected in namespace ${central_namespace})" @@ -442,13 +442,13 @@ deploy_sensor_via_operator() { fi if [[ "${SFA_AGENT:-}" == "Enabled" ]]; then - echo "Enabling SFA agent due to SFA_AGENT variable: ${SFA_AGENT}" - sfa_agent_setting="Enabled" + echo "Enabling File Activity Monitoring due to SFA_AGENT variable: ${SFA_AGENT}" + fam_mode_setting="Enabled" fi env - \ scanner_component_setting="$scanner_component_setting" \ - sfa_agent_setting="$sfa_agent_setting" \ + fam_mode_setting="$fam_mode_setting" \ central_endpoint="$central_endpoint" \ "${envsubst}" \ < "${secured_cluster_yaml_path}" | kubectl apply -n "${sensor_namespace}" --validate="${validate}" -f - diff --git a/tests/e2e/run-e2e-tests.sh b/tests/e2e/run-e2e-tests.sh index b03d0b0cd6e67..68006502afcf3 100755 --- a/tests/e2e/run-e2e-tests.sh +++ b/tests/e2e/run-e2e-tests.sh @@ -148,7 +148,7 @@ if [[ ! -f "/i-am-rox-ci-image" ]]; then --platform linux/amd64 \ --rm -it \ --entrypoint="$0" \ - quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.1 "$@" + quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.2 "$@" exit 0 fi diff --git a/tests/e2e/yaml/secured-cluster-cr.envsubst.yaml b/tests/e2e/yaml/secured-cluster-cr.envsubst.yaml index ee74e9daf64fe..51067bcc83ef5 100644 --- a/tests/e2e/yaml/secured-cluster-cr.envsubst.yaml +++ b/tests/e2e/yaml/secured-cluster-cr.envsubst.yaml @@ -6,8 +6,8 @@ spec: centralEndpoint: $central_endpoint clusterName: remote perNode: - sfa: - agent: $sfa_agent_setting + fileActivityMonitoring: + mode: $fam_mode_setting scanner: scannerComponent: $scanner_component_setting analyzer: diff --git a/ui/apps/platform/package-lock.json b/ui/apps/platform/package-lock.json index 577436a9fe529..2ead5ea6a3958 100644 --- a/ui/apps/platform/package-lock.json +++ b/ui/apps/platform/package-lock.json @@ -42,7 +42,7 @@ "html2canvas": "1.0.0-rc.7", "initials": "^3.1.2", "js-base64": "^3.7.2", - "jspdf": "^4.0.0", + "jspdf": "^4.1.0", "jspdf-autotable": "^5.0.7", "lodash": "^4.17.23", "mobx": "^6.13.7", @@ -8063,9 +8063,10 @@ } }, "node_modules/dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -11799,9 +11800,9 @@ } }, "node_modules/jspdf": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-4.0.0.tgz", - "integrity": "sha512-w12U97Z6edKd2tXDn3LzTLg7C7QLJlx0BPfM3ecjK2BckUl9/81vZ+r5gK4/3KQdhAcEZhENUxRhtgYBj75MqQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-4.1.0.tgz", + "integrity": "sha512-xd1d/XRkwqnsq6FP3zH1Q+Ejqn2ULIJeDZ+FTKpaabVpZREjsJKRJwuokTNgdqOU+fl55KgbvgZ1pRTSWCP2kQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.4", @@ -11811,7 +11812,7 @@ "optionalDependencies": { "canvg": "^3.0.11", "core-js": "^3.6.0", - "dompurify": "^3.2.4", + "dompurify": "^3.3.1", "html2canvas": "^1.0.0-rc.5" } }, diff --git a/ui/apps/platform/package.json b/ui/apps/platform/package.json index d430234ac968b..f801c57a1051d 100644 --- a/ui/apps/platform/package.json +++ b/ui/apps/platform/package.json @@ -45,7 +45,7 @@ "html2canvas": "1.0.0-rc.7", "initials": "^3.1.2", "js-base64": "^3.7.2", - "jspdf": "^4.0.0", + "jspdf": "^4.1.0", "jspdf-autotable": "^5.0.7", "lodash": "^4.17.23", "mobx": "^6.13.7",