diff --git a/.github/workflows/provisioning-tests.yaml b/.github/workflows/provisioning-tests.yaml index 33225e8d6..9eecfc84c 100644 --- a/.github/workflows/provisioning-tests.yaml +++ b/.github/workflows/provisioning-tests.yaml @@ -14,6 +14,7 @@ jobs: provisioning-test: permissions: contents: read + id-token: write runs-on: - runs-on - spot=false @@ -40,10 +41,19 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: "0" + - name: Retrieve Registry Endpoint + if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/rancher-prime-stg-registry/credentials registry | STAGE_REGISTRY_ENDPOINT; + secret/data/github/repo/${{ github.repository }}/registry-endpoint/credentials token | REGISTRY_ENDPOINT - name: Provisioning Operations tests run: | dapper provisioning-tests env: + LAST_COMMUNITY_RANCHER: v2.10.0-alpha1 + PRIME_AGENT_IMAGE: rancher/rancher-agent:v2.10.10 V2PROV_TEST_DIST: ${{ matrix.dist }} V2PROV_TEST_RUN_REGEX: ${{ matrix.test-regex }} KDM_TEST_K8S_MINOR: ${{ matrix.k8s-minor }} diff --git a/Dockerfile.dapper b/Dockerfile.dapper index 44b7f3e9b..8eca57a78 100644 --- a/Dockerfile.dapper +++ b/Dockerfile.dapper @@ -80,8 +80,8 @@ ENV YQ_VERSION v4.41.1 RUN wget -q https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${ARCH}.tar.gz -O - | tar xz && mv yq_linux_${ARCH} /usr/bin/yq ENV DAPPER_ENV REPO TAG CI \ - PREV_COMMIT_PR_SHA PREV_COMMIT_PUSH_SHA GITHUB_EVENT_NAME GITHUB_RUN_NUMBER GITHUB_REF_TYPE GITHUB_REF_NAME \ - REGISTRY_ENDPOINT REGISTRY_USERNAME REGISTRY_PASSWORD \ + LAST_COMMUNITY_RANCHER PRIME_AGENT_IMAGE PREV_COMMIT_PR_SHA PREV_COMMIT_PUSH_SHA GITHUB_EVENT_NAME GITHUB_RUN_NUMBER GITHUB_REF_TYPE GITHUB_REF_NAME \ + STAGE_REGISTRY_ENDPOINT REGISTRY_ENDPOINT REGISTRY_USERNAME REGISTRY_PASSWORD \ V2PROV_TEST_DIST V2PROV_TEST_RUN_REGEX KDM_TEST_K8S_MINOR DEBUG ENV DAPPER_SOURCE /go/src/github.com/rancher/kontainer-driver-metadata ENV DAPPER_DOCKER_SOCKET true diff --git a/docs/release.md b/docs/release.md index 467d859a2..eec75e37a 100644 --- a/docs/release.md +++ b/docs/release.md @@ -53,7 +53,54 @@ A couple of example PRs to help: - https://github.com/rancher/kontainer-driver-metadata/pull/1104 - https://github.com/rancher/kontainer-driver-metadata/pull/1056 - https://github.com/rancher/kontainer-driver-metadata/pull/1027 -- https://github.com/rancher/kontainer-driver-metadata/pull/1084 +- https://github.com/rancher/kontainer-driver-metadata/pull/1084 + +## Prime configuration variables + +When preparing a new KDM release line (or advancing an existing one), update the prime-related variables used by CI/test scripts to correctly detect prime and select a prime-published agent image: + +```yaml +# .github/workflows/provisioning-tests.yaml +- name: Provisioning Operations tests + run: dapper provisioning-tests + env: + LAST_COMMUNITY_RANCHER: v2.9.0-alpha1 + PRIME_AGENT_IMAGE: rancher/rancher-agent:v2.9.12 + # ...existing env... +``` + +**Scripts behavior:** scripts provide safe defaults only if these variables are not set by the workflow, so local runs still work without extra config. + +**What to update each release:** + +* **`LAST_COMMUNITY_RANCHER`** — Set to the cutoff Rancher server version for *community* builds on this line. This is compared to a channel entry’s `minChannelServerVersion` to decide if a K8s release is **prime-only**. +* **`PRIME_AGENT_IMAGE`** — Set to the **latest prime-published** `rancher/rancher-agent` tag for this release line. This ensures provisioning tests use an agent image available in the prime registry when prime mode is active. + +**Where these are used:** KDM CI/test scripts (e.g., `scripts/prime-route`, `scripts/provisioning-tests`) referenced by Rancher provisioning tests. + +**When creating a new KDM branch:** set `LAST_COMMUNITY_RANCHER` to a high placeholder similar to how `maxChannelServerVersion` is used in `data.json`, for example `v2.X.99`. Replace this placeholder with the agreed cutoff once the prime-only point is defined for the line. + +**When to bump:** + +* At the start of a new release line or when the prime cutoff moves (bump `LAST_COMMUNITY_RANCHER`). +* Whenever a new prime agent is published for this line (bump `PRIME_AGENT_IMAGE`). + +### During prime cutoff: pin distro versions in rancher/rancher + +While a release line is at or near the prime cutoff, CI in **rancher/rancher** should **pin** the Kubernetes versions per distro to avoid unintentionally selecting a prime-only “latest”. Add the per-distro pins in the Rancher workflow’s **Run tests** step: + +```yaml +# rancher/rancher: .github/workflows/provisioning-tests.yml (excerpt) +- name: Run tests + run: ./.dapper provisioning-tests + env: + # per-distro pins used by the provisioning script if SOME_K8S_VERSION is unset + K3S_PINNED_VERSION: "v1.30.14+k3s2" + RKE2_PINNED_VERSION: "v1.30.14+rke2r2" + # ...existing env... +``` + +[Example reference: the change in this commit shows the pins added in the Rancher workflow](https://github.com/rancher/rancher/pull/52176/commits/dcf3704ca888037cdf37513a04eaeb1d07cb3a70#diff-3b900f349b5944ff0314a1b0597aff3c4b531758380e00bd0e3ece5844fead00R57). ## Prime images update diff --git a/scripts/channels-pick-minchan-for-version.awk b/scripts/channels-pick-minchan-for-version.awk new file mode 100755 index 000000000..cef24f78f --- /dev/null +++ b/scripts/channels-pick-minchan-for-version.awk @@ -0,0 +1,31 @@ +#!/usr/bin/awk -f +# Usage: channels-pick-minchan-for-version.awk +# Prints the minChannelServerVersion for that release (if present), returns 2 +# if receives insufficient arguments, else nothing. + +function trim(s){ sub(/^[ \t\r\n]+/,"",s); sub(/[ \t\r\n]+$/,"",s); return s } + +BEGIN { + if (ARGC < 3) exit 2 + target = ARGV[2] + ARGV[2] = "" # prevent awk from treating target as a file + inBlock = 0 + curVer = "" +} + +# Start of a release block: "- version: " +/^[[:space:]]*-[[:space:]]*version:[[:space:]]*/ { + inBlock = 1 + line = $0 + sub(/^[[:space:]]*-[[:space:]]*version:[[:space:]]*/, "", line) + curVer = trim(line) + next +} + +# Capture minChannelServerVersion only if we are in the target block +inBlock && curVer == target && /^[[:space:]]*minChannelServerVersion:[[:space:]]*/ { + line = $0 + sub(/^[[:space:]]*minChannelServerVersion:[[:space:]]*/, "", line) + print trim(line) + exit 0 +} \ No newline at end of file diff --git a/scripts/prime-route b/scripts/prime-route new file mode 100644 index 000000000..4c2a8c6ca --- /dev/null +++ b/scripts/prime-route @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# scripts/prime-route +# Sets PRIME_MODE, PRIME_REGISTRY_ENVIRONMENT, and (optionally) PRIME_REG_HOST/CATTLE_AGENT_IMAGE. +# Detection is independent of whether endpoints are available. +# Inputs: +# CHANNELS_FILE, SOME_K8S_VERSION, LAST_COMMUNITY_RANCHER +# REGISTRY_ENDPOINT, STAGE_REGISTRY_ENDPOINT +# PRIME_AGENT_IMAGE +set -e + +# only set defaults if not provided by the workflow +if [ -z "${LAST_COMMUNITY_RANCHER:-}" ]; then + LAST_COMMUNITY_RANCHER="v2.10.0-alpha1" +fi + +if [ -z "${PRIME_AGENT_IMAGE:-}" ]; then + PRIME_AGENT_IMAGE="rancher/rancher-agent:v2.10.10" +fi + +# Compute minChannelServerVersion for the selected K8s version (may be empty) +MINCHAN="$(scripts/channels-pick-minchan-for-version.awk "${CHANNELS_FILE}" "${SOME_K8S_VERSION}" || true)" + +# Defaults +PRIME_MODE=0 +unset PRIME_REGISTRY_ENVIRONMENT +unset PRIME_REG_HOST + +# Decide Prime mode purely by version comparison: MINCHAN > LAST_COMMUNITY_RANCHER +if [[ -n "${MINCHAN}" ]] && scripts/semver_g.awk "${MINCHAN}" "${LAST_COMMUNITY_RANCHER}"; then + PRIME_MODE=1 + + # --- BEGIN sensitive section (suppress xtrace to avoid printing hosts) --- + _TRACE_WAS_ON=0 + if [[ $- == *x* ]]; then + _TRACE_WAS_ON=1 + set +x + fi + + # Choose staging vs production by "-rc" in SOME_K8S_VERSION (prerelease => staging) + if [[ "${SOME_K8S_VERSION,,}" == *-rc* ]]; then + PRIME_REGISTRY_ENVIRONMENT="staging" + PRIME_REG_HOST="${STAGE_REGISTRY_ENDPOINT:-}" + else + PRIME_REGISTRY_ENVIRONMENT="production" + PRIME_REG_HOST="${REGISTRY_ENDPOINT:-}" + fi + + # Only export PRIME_REG_HOST if it is set + if [[ -n "${PRIME_REG_HOST}" ]]; then + export PRIME_REG_HOST + fi + + # If Prime is on and PRIME_AGENT_IMAGE is set, override CATTLE_AGENT_IMAGE + if [[ -n "${PRIME_AGENT_IMAGE:-}" ]]; then + export CATTLE_AGENT_IMAGE="${PRIME_AGENT_IMAGE}" + fi + + # Restore xtrace if it was enabled + if [[ "${_TRACE_WAS_ON}" == "1" ]]; then + set -x + fi + # --- END sensitive section --- +fi + +# Export non-sensitive flags (safe to print) +export PRIME_MODE PRIME_REGISTRY_ENVIRONMENT \ No newline at end of file diff --git a/scripts/provisioning-tests b/scripts/provisioning-tests index bc79a495f..909adc48e 100755 --- a/scripts/provisioning-tests +++ b/scripts/provisioning-tests @@ -82,6 +82,18 @@ if [ -z "${SOME_K8S_VERSION}" ]; then export SOME_K8S_VERSION fi +source scripts/prime-route + +if [[ "${PRIME_MODE}" == "1" ]]; then + # If Prime/Prime-staging is required but endpoints are unavailable (typical in fork PRs), fail early + if [[ -z "${REGISTRY_ENDPOINT:-}" && -z "${STAGE_REGISTRY_ENDPOINT:-}" ]]; then + echo "Registry URL is not provided; most likely this is due to limitations for accessing secrets from PRs from forks; open this PR from branch in the repo itself instead of a fork" + exit 1 + fi + + echo "Prime mode enabled (registry environment=${PRIME_REGISTRY_ENVIRONMENT:-unknown} rancher-agent=${CATTLE_AGENT_IMAGE:-unknown}); proceeding with provisioning tests." +fi + # Copy rancher provisioning tests, and enter directory they exist source ./scripts/fetch-provisioning-tests diff --git a/scripts/semver_g.awk b/scripts/semver_g.awk new file mode 100755 index 000000000..38f7e9b53 --- /dev/null +++ b/scripts/semver_g.awk @@ -0,0 +1,16 @@ +#!/usr/bin/awk -f +# Exit codes: 0 if A>B by major.minor.patch (ignoring pre-release suffix), 1 if A<=B, 2 if insufficient arguments. +# Usage: scripts/semver_g.awk +function norm(s, n,i,arr) { + gsub(/^v/,"",s); sub(/-.*/,"",s) + n = split(s, arr, ".") + for (i=1; i<=3; i++) if (i>n) arr[i]=0 + return sprintf("%d.%d.%d", arr[1], arr[2], arr[3]) +} +BEGIN { + if (ARGC < 3) exit 2 + as = norm(ARGV[1]); bs = norm(ARGV[2]) + split(as,a,"."); split(bs,b,".") + if (a[1]>b[1] || (a[1]==b[1] && (a[2]>b[2] || (a[2]==b[2] && a[3]>b[3])))) exit 0 + exit 1 +} \ No newline at end of file