From a070c7d02570599c7054ba943ea91db3760d5dff Mon Sep 17 00:00:00 2001 From: Gregory Giguashvili Date: Thu, 25 Jun 2026 21:01:47 +0300 Subject: [PATCH] Implement automatic LVMS rebase on the latest z-stream --- docs/contributor/rebase.md | 12 +- .../{lvms_assets.yaml => assets_lvms.yaml} | 0 .../{ossm_assets.yaml => assets_ossm.yaml} | 0 scripts/auto-rebase/last_lvms_rebase.sh | 2 - scripts/auto-rebase/last_rebase_lvms.sh | 2 + scripts/auto-rebase/presubmit.py | 4 +- scripts/auto-rebase/rebase_gateway_api.sh | 2 +- scripts/auto-rebase/rebase_job_entrypoint.sh | 45 +------ .../{rebase-lvms.sh => rebase_lvms.sh} | 110 ++++++++++++------ 9 files changed, 92 insertions(+), 85 deletions(-) rename scripts/auto-rebase/{lvms_assets.yaml => assets_lvms.yaml} (100%) rename scripts/auto-rebase/{ossm_assets.yaml => assets_ossm.yaml} (100%) delete mode 100755 scripts/auto-rebase/last_lvms_rebase.sh create mode 100755 scripts/auto-rebase/last_rebase_lvms.sh rename scripts/auto-rebase/{rebase-lvms.sh => rebase_lvms.sh} (84%) diff --git a/docs/contributor/rebase.md b/docs/contributor/rebase.md index 5ef5855edb..d1fad16339 100644 --- a/docs/contributor/rebase.md +++ b/docs/contributor/rebase.md @@ -169,7 +169,7 @@ git commit -m "update buildfiles" Since LVMS is part of the delivery of MicroShift default functionality, we cannot rely on OLM to use a ClusterServiceVersion to install LVMS as we would in a normal OpenShift cluster. -To workaround this issue, there is a dedicated script in `scripts/auto-rebase/rebase-lvms.sh` to update the LVMS component images and manifests based on (naive but straight-forward) reverse-engineering the Operator Bundle image of LVMS. +To workaround this issue, there is a dedicated script in `scripts/auto-rebase/rebase_lvms.sh` to update the LVMS component images and manifests based on (naive but straight-forward) reverse-engineering the Operator Bundle image of LVMS. The script employs `yq` extensively for manipulating YAML files coming from the bundle, such as extracting and updating image references in the LVMS operator bundle manifest. @@ -193,13 +193,13 @@ The following command attempts a fully automatic rebase to a given target LVMS r for a release candidate in CPaaS (Red Hat Internal Build System): ```shell -./scripts/auto-rebase/rebase-lvms.sh to "quay.io/lvms_dev/lvms4-lvms-operator-bundle:[TAG || DIGEST]" +./scripts/auto-rebase/rebase_lvms.sh to "quay.io/lvms_dev/lvms4-lvms-operator-bundle:[TAG || DIGEST]" ``` for a public release: ```shell -./scripts/auto-rebase/rebase-lvms.sh to "registry.redhat.io/lvms4/lvms-operator-bundle:[TAG || DIGEST]" +./scripts/auto-rebase/rebase_lvms.sh to "registry.redhat.io/lvms4/lvms-operator-bundle:[TAG || DIGEST]" ``` #### Manual Update of LVMS @@ -209,7 +209,7 @@ for a public release: Run the following to download the LVMS release to update to, specifying the multi-arch target release image, e.g.: ```shell -./scripts/auto-rebase/rebase-lvms.sh download "registry.redhat.io/lvms4/lvms-operator-bundle:[TAG || DIGEST]" +./scripts/auto-rebase/rebase_lvms.sh download "registry.redhat.io/lvms4/lvms-operator-bundle:[TAG || DIGEST]" ``` This will create a directory `_output/staging`, download the operator bundle for the specified LVMS release. @@ -219,7 +219,7 @@ This will create a directory `_output/staging`, download the operator bundle for To update the image references for LVMS, run: ```shell -./scripts/auto-rebase/rebase-lvms.sh images +./scripts/auto-rebase/rebase_lvms.sh images git add pkg/release git commit -m "update LVMS images" ``` @@ -229,7 +229,7 @@ git commit -m "update LVMS images" To update the manifests for LVMS, run: ```shell -./scripts/auto-rebase/rebase-lvms.sh manifests +./scripts/auto-rebase/rebase_lvms.sh manifests git add assets git commit -m "update LVMS manifests" ``` diff --git a/scripts/auto-rebase/lvms_assets.yaml b/scripts/auto-rebase/assets_lvms.yaml similarity index 100% rename from scripts/auto-rebase/lvms_assets.yaml rename to scripts/auto-rebase/assets_lvms.yaml diff --git a/scripts/auto-rebase/ossm_assets.yaml b/scripts/auto-rebase/assets_ossm.yaml similarity index 100% rename from scripts/auto-rebase/ossm_assets.yaml rename to scripts/auto-rebase/assets_ossm.yaml diff --git a/scripts/auto-rebase/last_lvms_rebase.sh b/scripts/auto-rebase/last_lvms_rebase.sh deleted file mode 100755 index 8856ac691f..0000000000 --- a/scripts/auto-rebase/last_lvms_rebase.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -x -./scripts/auto-rebase/rebase-lvms.sh to "registry.redhat.io/lvms4/lvms-operator-bundle:v4.21.0" diff --git a/scripts/auto-rebase/last_rebase_lvms.sh b/scripts/auto-rebase/last_rebase_lvms.sh new file mode 100755 index 0000000000..8c35468714 --- /dev/null +++ b/scripts/auto-rebase/last_rebase_lvms.sh @@ -0,0 +1,2 @@ +#!/bin/bash -x +./scripts/auto-rebase/rebase_lvms.sh to "registry.redhat.io/lvms4/lvms-operator-bundle:v4.21.0" diff --git a/scripts/auto-rebase/presubmit.py b/scripts/auto-rebase/presubmit.py index 5e90ed4639..c941392857 100755 --- a/scripts/auto-rebase/presubmit.py +++ b/scripts/auto-rebase/presubmit.py @@ -24,8 +24,8 @@ STAGING_DIR = "_output/staging/" RECIPE_FILEPATHS = [ "./scripts/auto-rebase/assets.yaml", - "./scripts/auto-rebase/lvms_assets.yaml", - "./scripts/auto-rebase/ossm_assets.yaml", + "./scripts/auto-rebase/assets_lvms.yaml", + "./scripts/auto-rebase/assets_ossm.yaml", "./scripts/auto-rebase/assets_ai_model_serving.yaml", "./scripts/auto-rebase/assets_cert_manager.yaml", "./scripts/auto-rebase/assets_sriov.yaml", diff --git a/scripts/auto-rebase/rebase_gateway_api.sh b/scripts/auto-rebase/rebase_gateway_api.sh index 2692019d0a..4a8267f2dc 100755 --- a/scripts/auto-rebase/rebase_gateway_api.sh +++ b/scripts/auto-rebase/rebase_gateway_api.sh @@ -221,7 +221,7 @@ update_ossm_manifests() { >&2 echo 'ossm staging dir not found, aborting asset update' return 1 } - "${REPOROOT}/scripts/auto-rebase/handle_assets.py" ./scripts/auto-rebase/ossm_assets.yaml + "${REPOROOT}/scripts/auto-rebase/handle_assets.py" ./scripts/auto-rebase/assets_ossm.yaml } update_last_ossm_rebase() { diff --git a/scripts/auto-rebase/rebase_job_entrypoint.sh b/scripts/auto-rebase/rebase_job_entrypoint.sh index 0ee366a222..052a46de09 100755 --- a/scripts/auto-rebase/rebase_job_entrypoint.sh +++ b/scripts/auto-rebase/rebase_job_entrypoint.sh @@ -5,27 +5,11 @@ set -o errexit set -o pipefail set -x -check_semver_no_suffix() { - local version=$1 - - # Check if the version is not empty - if [[ -z "$version" ]]; then - return 0 - fi - - # Check if the version string contains a numeric suffix of the form -xx - if [[ $version =~ -[0-9]+$ ]]; then - return 1 - else - return 0 - fi -} - echo "Environment:" printenv -if [[ "$JOB_NAME" == rehearse* ]]; then +if [[ "${JOB_NAME:-}" == rehearse* ]]; then echo "INFO: \$JOB_NAME starts with rehearse - running in DRY RUN mode" export DRY_RUN=y fi @@ -104,29 +88,10 @@ SRIOV_RELEASE=${sriov_release} \ OPM_RELEASE=${opm_release} \ ./scripts/auto-rebase/rebase.py -# LVMS is not tracked in the OCP release image. Instead, rely on the -# latest X.Y stream as the release image. LVMS also does not cut -# nightly releases where ocp-release does. This means that latest -# ocp-releases' y-stream can increment independently from LVMS, and -# will usually be 1 y-stream ahead of LVMS in-between OCP releases. -# For example, ocp-release at 4.13 will more often than not -# correspond to 4.12 LVMS, until the official 4.13 release when both -# components will be 4.13. -release_lvms="v4.21.0" - -# Since LVMS is not part of the release payload, it is not kept in -# CI. Use the latest z-stream that coincides with the release -# payload's X.Y version -pullspec_release_lvms="registry.redhat.io/lvms4/lvms-operator-bundle:${release_lvms}" -# A unreleased candidate doesnt exist in the official registry, so fallback to the lvms_dev namespace, which contains -# the latest lvms release candidate replicated from CPaaS into quay -pullspec_release_lvms_fallback="quay.io/lvms_dev/lvms4-lvms-operator-bundle:${release_lvms}" - -if check_semver_no_suffix "${release_lvms}"; then - ./scripts/auto-rebase/rebase-lvms.sh to "${pullspec_release_lvms}" -else - ./scripts/auto-rebase/rebase-lvms.sh to "${pullspec_release_lvms_fallback}" -fi +# LVMS is not tracked in the OCP release image. Instead, rely on the +# latest z-stream for a given X.Y version. Only the X.Y needs manual +# updating between releases. +./scripts/auto-rebase/rebase_lvms.sh latest "registry.redhat.io/lvms4/lvms-operator-bundle" "4.21" if [[ "${JOB_TYPE}" == "presubmit" ]]; then # Verify the assets after the rebase to make sure diff --git a/scripts/auto-rebase/rebase-lvms.sh b/scripts/auto-rebase/rebase_lvms.sh similarity index 84% rename from scripts/auto-rebase/rebase-lvms.sh rename to scripts/auto-rebase/rebase_lvms.sh index 487efcef14..3cc7178eba 100755 --- a/scripts/auto-rebase/rebase-lvms.sh +++ b/scripts/auto-rebase/rebase_lvms.sh @@ -20,6 +20,63 @@ title() { echo -e "\E[34m$1\E[00m"; } +# catalog_list_tags REPOSITORY +# Lists all tags for a container image using the Red Hat container catalog API. +# No authentication required. The repository should be the path portion +# (e.g. "lvms4/lvms-operator-bundle"). +catalog_list_tags() { + local repo="$1" + local api_url="https://catalog.redhat.com/api/containers/v1/repositories/registry/registry.access.redhat.com/repository" + local encoded_repo="${repo/\//%2F}" + + curl -s --fail --max-time 60 --retry 3 --retry-delay 5 \ + "${api_url}/${encoded_repo}/images?page_size=500" \ + | jq -r '[.data[].repositories[].tags[].name] | unique[]' +} + +# resolve_latest_z_tag IMAGE_URL XY_VERSION +# Queries the Red Hat container catalog for tags and returns the latest +# clean semver tag (vX.Y.Z) matching the given X.Y stream. +# Returns 1 if no matching tag is found. +resolve_latest_z_tag() { + local image_url="$1" + local xy_version="$2" + + # Extract repository path from full image URL + # e.g. "registry.redhat.io/lvms4/lvms-operator-bundle" -> "lvms4/lvms-operator-bundle" + local repo="${image_url#*/}" + + local tags + tags=$(catalog_list_tags "${repo}") || return 1 + + local xy_escaped="${xy_version//./\\.}" + + local latest + latest=$(echo "${tags}" | grep -E "^v${xy_escaped}\.[0-9]+$" | sort -V | tail -1) + if [[ -n "${latest}" ]]; then + echo "${latest}" + return 0 + fi + + return 1 +} + +# Resolves the latest z-stream for the given X.Y version and rebases to it. +rebase_lvms_latest() { + local registry="$1" + local xy_version="$2" + + title "# Resolving latest LVMS tag for stream ${xy_version}" + local tag + tag=$(resolve_latest_z_tag "${registry}" "${xy_version}") || true + if [[ -z "${tag}" ]]; then + echo "ERROR: Could not find any LVMS tag for stream ${xy_version} in ${registry}" + exit 1 + fi + title "# Resolved LVMS version ${tag}" + rebase_lvms_to "${registry}:${tag}" +} + check_preconditions() { if ! hash yq; then title "Installing yq" @@ -50,8 +107,7 @@ rebase_lvms_to() { git branch -D "${rebase_branch}" || true git checkout -b "${rebase_branch}" - update_last_lvms_rebase "${lvms_operator_bundle_manifest}" - update_rebase_job_entrypoint "${lvms_operator_bundle_manifest}" + update_last_rebase_lvms "${lvms_operator_bundle_manifest}" update_lvms_images if [[ -n "$(git status -s pkg/release)" ]]; then @@ -228,49 +284,30 @@ update_lvms_manifests() { >&2 echo 'lvms staging dir not found, aborting asset update' return 1 } - "${REPOROOT}/scripts/auto-rebase/handle_assets.py" ./scripts/auto-rebase/lvms_assets.yaml + "${REPOROOT}/scripts/auto-rebase/handle_assets.py" ./scripts/auto-rebase/assets_lvms.yaml yq -i '.spec.template.spec.containers[0].image = "{{ .ReleaseImage.lvms_operator }}"' "${REPOROOT}/assets/components/lvms/lvms-operator_apps_v1_deployment.yaml" } -update_last_lvms_rebase() { +update_last_rebase_lvms() { local lvms_operator_bundle_manifest="$1" - title "## Updating last_lvms_rebase.sh" + title "## Updating last_rebase_lvms.sh" - local last_rebase_script="${REPOROOT}/scripts/auto-rebase/last_lvms_rebase.sh" + local last_rebase_script="${REPOROOT}/scripts/auto-rebase/last_rebase_lvms.sh" rm -f "${last_rebase_script}" cat - >"${last_rebase_script}" <