From 5c28dd545188445e884b677170cc6b97f8dbc44c Mon Sep 17 00:00:00 2001 From: chen21019 <19357113+chen21019@users.noreply.github.com> Date: Thu, 15 Oct 2026 21:15:55 +0800 Subject: [PATCH] feat: prepare Server537 archive and restore release --- COMPATIBILITY.md | 33 ++++++ README.md | 20 ++-- docs/README.md | 4 + docs/performance/README.md | 14 +-- docs/releases/server-1.6.537.md | 102 ++++++++++++++++++ scripts/check-server-api-explorer-patch.sh | 62 +++++------ .../test-current-server-packaging-contract.py | 74 ++++++------- scripts/test-published-install-gate.py | 36 +++---- server/Dockerfile.web-compose-release | 26 ++--- server/build-api-explorer-patch-image.sh | 18 ++-- server/build-component-candidate.sh | 6 +- server/security/openvex.json | 6 +- server/security/vendor-pending.json | 4 +- 13 files changed, 277 insertions(+), 128 deletions(-) create mode 100644 docs/releases/server-1.6.537.md diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index b4d141cbe6..f4bd36b2d2 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -1,5 +1,38 @@ # Compatibility Contract +## Server v1.6.537 prepared, not published + +This candidate targets Web Console `1.6.190` and Engine `v0.183.350`. +Component producer commits and artifact SHA-256 values are pinned in the recipe. +Server producer, final image identity and official release checks remain pending. See the +[candidate note](docs/releases/server-1.6.537.md). No Server537 publication or +deployment is claimed; the Server536 identities below remain historical facts. + +Stack and Service `archived` is a persisted boolean with missing values treated +as false. Archive requires stopped services and instances, rejects system/driver +resources, and has no start/stop/delete or storage lifecycle side effect. Empty +Stacks may be archived. Parent and child flags remain independent; restore does +not clear separately archived children. Archived resources must be restored +before starting or adding/moving children into them. Archive/restore uses the +existing update authorization and native v1/v2-beta APIs, not a new role grant. +Older Engines do not implement archive enforcement; code rollback does not +promise retained archive behavior and archive never replaces data backups. + +The console's personal, per-environment archive switch changes only visibility. +Read-only users may include archived resources without gaining write controls; +the effective schema and update capability remain authoritative. Older Engines +without a readable/updatable boolean field do not offer the action. The modal +warns that mounts and volumes are retained and require operator backups. + +Reviewed pre-release isolated evidence covers focused tests, native role/Key +archive/restore, thirteen-locale layouts, owner-read Key audit, and separate +physical workload/mount preservation and first-host checks. It does not establish +the final537 image or future published190/350 artifact identities. Existing API +Key policy, authentication/OIDC/MFA, three-volume persistence, CLI defaults, +performance overrides and firewall contracts are not changed by this feature. +Security document release IDs advance only; VEX statements, vendor findings and +their review deadlines are preserved pending the new final-image security gate. + ## Server v1.6.536 published Immutable Server producer `b8cefb51db7f5e88341fdf231f6ae43d773fb9c7` passed the original official workflow [38681298101](https://github.com/PastureStack/server/actions/runs/38681298101) and anonymous release readback. Manifest: `sha256:84b701244ccd83abc313cfad47c52edf9c58fa49cdd5c2da129cdac0c81d8094`. Distinct OCI config: `sha256:4b56a5f4f58edf2ff08414fde91cc70da440562d7b6264ec62aaca133c256237`. Artifact identity (not an installation command): `ghcr.io/pasturestack/server:v1.6.536@sha256:84b701244ccd83abc313cfad47c52edf9c58fa49cdd5c2da129cdac0c81d8094`. Documentation commits do not replace the producer. Numeric installation tags remain required. diff --git a/README.md b/README.md index b2f8d29ca4..80bfe55db9 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,15 @@ upstream history, authorship, licenses, and notices. -## Current release +## Current source candidate -Server [`v1.6.536`](https://github.com/PastureStack/server/releases/tag/v1.6.536) packages unchanged Web Console `1.6.189` and Engine `v0.183.349`, with maintained external CLI `v0.6.18` download defaults. Explicit saved URLs and operator overrides remain authoritative. See the [release note](docs/releases/server-1.6.536.md) for immutable identities, native command evidence and remaining acceptance boundaries. Existing API authorization, OIDC/MFA, registration and performance contracts remain unchanged. +Server `v1.6.537` is a prepared source candidate, not a published image. +It targets Web Console `1.6.190` and Engine `v0.183.350` for persistent +Stack/Service archive and restore. See the [candidate note](docs/releases/server-1.6.537.md) +for the behavior, isolated acceptance scope, pinned component identities and +remaining Server publication gates. +The latest published release remains [Server `v1.6.536`](https://github.com/PastureStack/server/releases/tag/v1.6.536); +its [release note](docs/releases/server-1.6.536.md) retains the official artifact evidence. Personal API Keys remain available without an accessible environment. See the [Host guide](docs/hosts/README.md) before enrolling a host. @@ -39,15 +45,17 @@ Maintained CLI `0.6.18` propagates rejected requests as nonzero errors. Legacy ` ## Quick start -Public GHCR downloads do not require a registry login. Use the released numeric -tag below and keep all three named volumes: +Public GHCR downloads do not require a registry login. Keep all three named volumes. +The examples below target the prepared numeric `v1.6.537` tag; run them only after its official release. +This candidate is not yet available from GHCR. Until publication, use the latest +published release identified above. ```sh docker run -d --name pasturestack-server --restart unless-stopped -p 8080:8080 \ -v pasturestack-cattle:/var/lib/cattle \ -v pasturestack-mysql:/var/lib/mysql \ -v pasturestack-mysqllog:/var/log/mysql \ - ghcr.io/pasturestack/server:v1.6.536 + ghcr.io/pasturestack/server:v1.6.537 ``` For HTTPS termination at a reverse proxy, set the exact public origin: @@ -55,7 +63,7 @@ For HTTPS termination at a reverse proxy, set the exact public origin: ```yaml services: pasturestack-server: - image: ghcr.io/pasturestack/server:v1.6.536 + image: ghcr.io/pasturestack/server:v1.6.537 restart: unless-stopped ports: - "8080:8080" diff --git a/docs/README.md b/docs/README.md index 183cfd19ca..7211e6e771 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,6 +7,10 @@ runtime gates have passed. ## Release notes +- [Server v1.6.537 candidate](releases/server-1.6.537.md) — prepared for Web + Console `1.6.190` and Engine `v0.183.350` archive/restore. Component identities + are pinned; official Server image/publication gates remain pending. + - [Server v1.6.529](releases/server-1.6.529.md) — published with Engine `0.183.347` and Web Console `1.6.184` for subscription terminal audit and its translated target label. Official publication and immutable readback passed; diff --git a/docs/performance/README.md b/docs/performance/README.md index 6d23106fbc..7214375e6a 100644 --- a/docs/performance/README.md +++ b/docs/performance/README.md @@ -8,18 +8,20 @@ The following example is appropriate as a starting point for a dedicated 16-vCPU host with about 32 GiB of RAM. It is not a universal performance profile; measure the real workload before increasing it further. -The example uses published Server `v1.6.536`, packaging Web Console `1.6.189` -and Engine `v0.183.349`. See the [release note](../releases/server-1.6.536.md) -for immutable identities and acceptance limits. +The example targets prepared Server `v1.6.537`, Web Console `1.6.190` and Engine +`v0.183.350`; run it only after its official release and image have been published and read back. +This candidate is not yet available from GHCR. See the +[candidate note](../releases/server-1.6.537.md) for pinned component identities +and the bounded pre-release acceptance evidence. This release retains the same performance-setting contract. Existing runtime -overrides and volumes must be preserved on upgrade or code rollback. The CLI download-default update does not establish a performance improvement -or complete broader acceptance. +overrides and volumes must be preserved on upgrade or code rollback. Archive and +restore do not establish a performance improvement or complete broader acceptance. ```yaml services: pasturestack-server: - image: ghcr.io/pasturestack/server:v1.6.536 + image: ghcr.io/pasturestack/server:v1.6.537 restart: unless-stopped ports: - "8080:8080" diff --git a/docs/releases/server-1.6.537.md b/docs/releases/server-1.6.537.md new file mode 100644 index 0000000000..7b46bfd5f5 --- /dev/null +++ b/docs/releases/server-1.6.537.md @@ -0,0 +1,102 @@ +# Server v1.6.537 candidate + +Prepared source only; no Server image or release has been published. + +This candidate targets Web Console `1.6.190` and Engine `v0.183.350` for +Stack/Service archive and restore. It retains the pinned Server460 build base, +the other component producers, maintained CLI `v0.6.18` defaults, authentication, +performance settings and the three-volume persistence contract. + +## Behavior + +`archived` is a server-persisted boolean; missing values mean false. Archive +requires fully stopped services and associated instances, including sidekicks; +an empty Stack is allowed. System/infrastructure and driver resources cannot be +archived. Archive/restore only updates the flag: it does not stop, start, remove +or recreate containers, mounts or data volumes. Back up retained data separately. +Parent and child archive flags remain independent. Restore does not clear an +independently archived child. Restore archived resources before starting them or +adding/moving children into them; ordinary stop/delete behavior is unchanged. +New-resource clones omit the archive flag. + +The console switch next to sorting is a personal, per-environment visibility +preference, not a bulk archive command. Counts, archived badges, direct details, +cross-tab updates, keyboard access, RTL and reduced-motion behavior remain +explicit. The effective schema and update capability govern write controls; +older Engines without the field do not offer archive. Native v1/v2-beta writes +retain the original role and API Key `update` authorization, including live +owner RBAC and scope limits. Archive writes send only `archived`. + +## Reviewed isolated candidate evidence + +The following local acceptance receipts concern pre-release feature inputs, +not the final537 image or the future published190/350 artifact identities: + +- `backend-tests.json`: 63 unique focused tests, zero failures/errors/skips. +- `frontend-tests.json`: 37 unique focused tests; 36 unaffected results are + carried forward and the actual compiled RTL stylesheet case was rerun once. +- `isolated-test.json` and `isolated-adjacent.json`: 31 core native checks plus + three adjacent fresh-default/system guards, not a whole-platform suite. +- `archive-auth-matrix-results.json`: 88 native archive/restore pairs across + v1/v2-beta, five roles, two projects and six Key modes; all passed. Separate + `archive-role-browser-results.json` covers five actual role views. +- `archive-browser-results.json`: seven browser interactions and 52 layout + groups (13 locales, light/dark, desktop/narrow), including keyboard, preferences, + direct details and cross-tab updates. The banner fixture is explicitly an + injected HTTP422, not a claim that the same UI test caused a real backend refusal. +- `archive-audit-only-results.json`: six native appendix checks plus four UI + checks distinguish ALLOW/SUCCEEDED/200, DENY/DENIED/403 and ALLOW/FAILED/422. + The minting owner reads its personal Key audit. Earlier admin reads of a + foreign personal Key correctly returned403 and are not counted as audit PASS. +- `archive-physical-results.json`: six bounded real-host checks cover first-host + registration/default infrastructure, CNI DNS/egress/health, running-service + refusal, stopped Service/Stack archive/restore with unchanged runtime/mount + fingerprints and bind/named-volume data hashes, and native reactivation of the + same instance. `archive-host-lease-restore.json` records restoration of the + original host state; no original VM data or volumes were deleted. + +These checks do not claim a full preserved-database upgrade, distributed +multi-node race test, unrelated OIDC/MFA rerun or final release-image validation. +Formal image health/restart, security scan/SBOM, anonymous asset readback and +publication remain separate gates. Do not turn these local receipt names into +published asset claims without attaching their reviewed immutable evidence. + +## Component identities and remaining release gates + +The recipe pins the following reviewed packager outputs, not previous189/349 +identities. Official component publication/readback must complete before Server +assembly; the pins alone do not establish a published Server image. + +| Input | Pinned value | Locations | +| --- | --- | --- | +| `web-console-1.6.190.tar.gz` SHA-256 | `b06612812113fb4b54cf0f2b4754af077406306fd72407e04b17f2ad9f4dc927` | Dockerfile/build defaults, source gate and packaging-test `WEB_SHA` | +| Web190 producer commit | `9ff823c2233e2041c2f00bb56a91d147a7feaa1d` | Dockerfile/build defaults, source gate and packaging-test `WEB_SOURCE` | +| Engine350 `cattle.jar` SHA-256 | `637ddaa42cd93c019b4d0813d7053b71dc42797a7f3ac2aa4b10fcc7e304cb31` | Dockerfile/build defaults, source gate and packaging-test `ENGINE_SHA` | +| Engine350 producer commit | `9c884710e5ea3d4136d80a870d9de9485674f3c3` | Dockerfile/build defaults, source gate and packaging-test `ENGINE_SOURCE` | + +The files are `server/Dockerfile.web-compose-release`, +`server/build-api-explorer-patch-image.sh`, +`scripts/check-server-api-explorer-patch.sh` and +`scripts/test-current-server-packaging-contract.py`. The local350 `cattle.jar` +was independently read back at 87,906,638 bytes with the exact SHA-256 above. +Its `WEB-INF/lib/cattle-resources-0.183.350.jar` contains `schema/v1/readonly.ser` +(340,159 bytes, SHA-256 `7f274219e8dd9c6d750a408a6edec1448b564f4b16ba2204c425c5b45cec2233`) +and `schema/v1/restricted.ser` (355,023 bytes, SHA-256 +`f854ba99260f29e324ab7446a8592996946038920ac9bcf17689d98d1ebc5e51`). +These actual reads confirm the retained frozen-schema pins for this artifact. +Server537 producer commit, manifest/config digests, workflow and publication +readback are also pending and must be recorded from the actual final outputs. + +The existing coordinate predicates continue to reject placeholders. OpenVEX and +vendor tracking advance their release IDs only: the 69 VEX statements, 11 +vendor-pending CVEs/22 package rows, severities, fix policy and 2026-10-20 review +deadline are unchanged. This metadata update is not a new scan or remediation; +the new final-image security gate must still verify the exact current findings. + +## Install and rollback boundary + +Operational examples use only `ghcr.io/pasturestack/server:v1.6.537`, never a +digest-qualified or SHA-only installation tag. Run them only after official +publication and readback. Preserve all three existing named volumes, runtime +overrides and a working rollback container; do not restore old policy/revocation +or database state merely to roll back code. See the [upgrade guide](../upgrades/README.md). diff --git a/scripts/check-server-api-explorer-patch.sh b/scripts/check-server-api-explorer-patch.sh index 67166b2243..cb06e6fb5d 100755 --- a/scripts/check-server-api-explorer-patch.sh +++ b/scripts/check-server-api-explorer-patch.sh @@ -323,7 +323,7 @@ check_server497_published_docs # Install examples must follow the highest actually published numeric release; # Install commands use numeric tags; digest identity stays in publication evidence. -# An explicitly guarded522 source candidate may show numeric examples, not claim publication. +# An explicitly guarded537 source candidate may show numeric examples, not claim publication. python3 - <<'PY' import pathlib import re @@ -347,7 +347,7 @@ if len(references) != 2 or references[0] != references[1] or not re.fullmatch(in raise SystemExit('SERVER_LATEST_PUBLISHED_QUICK_START_MISMATCH') image = references[0] notes_path = 'docs/releases/server-' + tag[1:] + '.md' -expected_install_tag = 'v1.6.522' if candidate else tag +expected_install_tag = 'v1.6.537' if candidate else tag if image != 'ghcr.io/pasturestack/server:' + expected_install_tag or '(' + notes_path + ')' not in context[1]: raise SystemExit('SERVER_LATEST_PUBLISHED_QUICK_START_MISMATCH') performance = pathlib.Path('docs/performance/README.md').read_text(encoding='utf-8') @@ -355,10 +355,10 @@ performance_references = re.findall(r'ghcr\.io/pasturestack/server:[^\s`"<>]+', if performance_references != [image]: raise SystemExit('SERVER_LATEST_PUBLISHED_PERFORMANCE_MISMATCH') if candidate: - candidate_path = 'docs/releases/server-1.6.522.md' + candidate_path = 'docs/releases/server-1.6.537.md' candidate_notes = pathlib.Path(candidate_path).read_text(encoding='utf-8') required = ( - 'Server `v1.6.522` is a prepared source candidate, not a published image.', + 'Server `v1.6.537` is a prepared source candidate, not a published image.', '(' + candidate_path + ')', ) if '' not in readme or \ @@ -370,9 +370,9 @@ if candidate: if not all(marker in normalized_performance for marker in ( 'run it only after its official release and image have been published and read back.', 'is not yet available from GHCR', - '(../releases/server-1.6.522.md)')): + '(../releases/server-1.6.537.md)')): raise SystemExit('SERVER_SOURCE_CANDIDATE_PERFORMANCE_DISCLOSURE_MISSING') - if not re.search(r'(?m)^# Server v1\.6\.522 candidate[ \t]*$', candidate_notes) or \ + if not re.search(r'(?m)^# Server v1\.6\.537 candidate[ \t]*$', candidate_notes) or \ 'Prepared source only; no Server image or release has been published.' not in candidate_notes: raise SystemExit('SERVER_SOURCE_CANDIDATE_NOTES_MISMATCH') notes = pathlib.Path(notes_path).read_text(encoding='utf-8') @@ -385,8 +385,8 @@ latest_tag = max((reference.split('@')[0].rsplit(':', 1)[1] for reference in pub key=lambda value: tuple(map(int, value[1:].split('.')))) if candidate: if tuple(map(int, expected_install_tag[1:].split('.'))) <= tuple(map(int, latest_tag[1:].split('.'))) or \ - '## Server v1.6.522 prepared, not published' not in compat or \ - 'ghcr.io/pasturestack/server:v1.6.522@' in readme + performance + compat + candidate_notes: + '## Server v1.6.537 prepared, not published' not in compat or \ + 'ghcr.io/pasturestack/server:v1.6.537@' in readme + performance + compat + candidate_notes: raise SystemExit('SERVER_SOURCE_CANDIDATE_PUBLICATION_MISMATCH') if tag != latest_tag or not re.search(r'(?m)^# Server ' + re.escape(tag) + r'[ \t]*$', notes): raise SystemExit('SERVER_LATEST_PUBLISHED_QUICK_START_MISMATCH') @@ -527,7 +527,7 @@ require_marker "$release_dockerfile" \ 'ARG BASE_IMAGE=ghcr.io/pasturestack/server:v1.6.460@sha256:c855af8aea232dacc5bb6df68e2271d482c68b53c43ab0c108ec19118f5ab403' \ SERVER_INCREMENTAL_RELEASE_BASE_MISSING require_marker "$release_dockerfile" \ - 'ARG SERVER_RELEASE_TAG=v1.6.536' \ + 'ARG SERVER_RELEASE_TAG=v1.6.537' \ SERVER_INCREMENTAL_RELEASE_DEFAULT_MISSING require_marker "$release_dockerfile" \ 'org.opencontainers.image.version="${SERVER_RELEASE_TAG}"' \ @@ -572,16 +572,16 @@ require_marker "$publish_workflow" \ 'bash source/server/artifacts/verify-host-api-package.sh' \ SERVER_HOST_API_PRODUCER_RELEASE_CHECK_MISSING require_marker "$release_dockerfile" \ - 'ARG WEB_CONSOLE_RELEASE_TAG=1.6.189' \ + 'ARG WEB_CONSOLE_RELEASE_TAG=1.6.190' \ SERVER_INCREMENTAL_WEB_CONSOLE_VERSION_MISSING require_marker "$release_dockerfile" \ - 'ARG WEB_CONSOLE_ARTIFACT=web-console-1.6.189.tar.gz' \ + 'ARG WEB_CONSOLE_ARTIFACT=web-console-1.6.190.tar.gz' \ SERVER_INCREMENTAL_WEB_CONSOLE_ARTIFACT_MISSING require_marker "$release_dockerfile" \ - 'ARG WEB_CONSOLE_ARTIFACT_SHA256=1c90e273b7db8ebf9d851a0ae1ec49dc59067b5ee1099ea3886919c1a79ccdfc' \ + 'ARG WEB_CONSOLE_ARTIFACT_SHA256=b06612812113fb4b54cf0f2b4754af077406306fd72407e04b17f2ad9f4dc927' \ SERVER_INCREMENTAL_WEB_CONSOLE_HASH_MISSING require_marker "$release_dockerfile" \ - 'ARG WEB_CONSOLE_COMMIT=f30f5e81dd9ee25878c3aff681eed5bb61883453' \ + 'ARG WEB_CONSOLE_COMMIT=9ff823c2233e2041c2f00bb56a91d147a7feaa1d' \ SERVER_INCREMENTAL_WEB_CONSOLE_COMMIT_MISSING require_marker "$release_dockerfile" \ "grep -aF 'hostsPage.permissionDenied'" \ @@ -590,16 +590,16 @@ require_marker "$release_dockerfile" \ '"hostsPage.permissionDenied":"您沒有權限在此環境中新增主機。"' \ SERVER_INCREMENTAL_WEB_CONSOLE_ZH_TW_PERMISSION_MESSAGE_MISSING require_marker "$build_script" \ - 'web_console_commit=${WEB_CONSOLE_COMMIT:-f30f5e81dd9ee25878c3aff681eed5bb61883453}' \ + 'web_console_commit=${WEB_CONSOLE_COMMIT:-9ff823c2233e2041c2f00bb56a91d147a7feaa1d}' \ SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_COMMIT_MISSING require_marker "$build_script" \ - 'web_console_release_tag=${WEB_CONSOLE_RELEASE_TAG:-1.6.189}' \ + 'web_console_release_tag=${WEB_CONSOLE_RELEASE_TAG:-1.6.190}' \ SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_VERSION_MISSING require_marker "$build_script" \ - 'web_console_artifact=${WEB_CONSOLE_ARTIFACT:-web-console-1.6.189.tar.gz}' \ + 'web_console_artifact=${WEB_CONSOLE_ARTIFACT:-web-console-1.6.190.tar.gz}' \ SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_ARTIFACT_MISSING require_marker "$build_script" \ - 'web_console_artifact_sha256=${WEB_CONSOLE_ARTIFACT_SHA256:-1c90e273b7db8ebf9d851a0ae1ec49dc59067b5ee1099ea3886919c1a79ccdfc}' \ + 'web_console_artifact_sha256=${WEB_CONSOLE_ARTIFACT_SHA256:-b06612812113fb4b54cf0f2b4754af077406306fd72407e04b17f2ad9f4dc927}' \ SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_HASH_MISSING require_marker "$release_dockerfile" \ 'ARG CATALOG_SERVICE_VERSION=0.20.13' \ @@ -1064,21 +1064,21 @@ require_marker "$build_script" \ '--file server/Dockerfile.web-compose-release' \ SERVER_INCREMENTAL_RELEASE_BUILD_PATH_MISSING require_marker "$build_script" \ - 'image=${IMAGE:-pasturestack-validation/server:v1.6.536}' \ + 'image=${IMAGE:-pasturestack-validation/server:v1.6.537}' \ SERVER_INCREMENTAL_RELEASE_BUILD_VERSION_MISSING require_marker "$build_script" \ - 'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.536}' \ + 'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.537}' \ SERVER_INCREMENTAL_RELEASE_BUILD_DEFAULT_MISSING require_marker "$build_script" \ 'CATTLE_RANCHER_SERVER_VERSION="${server_release_tag}"' \ SERVER_INCREMENTAL_RELEASE_BUILD_RUNTIME_VERSION_MISSING for release_engine_marker in \ - 'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.349' \ + 'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.350' \ 'ARG ORCHESTRATION_ENGINE_ARTIFACT=cattle.jar' \ - 'ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04' \ - 'ARG ORCHESTRATION_ENGINE_COMMIT=0733430fac11892a17ba53749fe02d99d26b1f52' \ + 'ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=637ddaa42cd93c019b4d0813d7053b71dc42797a7f3ac2aa4b10fcc7e304cb31' \ + 'ARG ORCHESTRATION_ENGINE_COMMIT=9c884710e5ea3d4136d80a870d9de9485674f3c3' \ 'COPY --from=release_artifacts /out/orchestration-engine.jar /tmp/orchestration-engine.jar' \ - 'ARG ORCHESTRATION_ENGINE_VERSION=0.183.349' \ + 'ARG ORCHESTRATION_ENGINE_VERSION=0.183.350' \ 'grep -Fx "Implementation-Version: ${ORCHESTRATION_ENGINE_VERSION}"' \ 'cattle-resources-${ORCHESTRATION_ENGINE_VERSION}.jar' \ 'cattle-app-config-${ORCHESTRATION_ENGINE_VERSION}.jar' \ @@ -1099,10 +1099,10 @@ for release_engine_marker in \ SERVER_INCREMENTAL_ENGINE_REPLACEMENT_MISSING done for release_engine_build_marker in \ - 'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.349}' \ + 'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.350}' \ 'orchestration_engine_artifact=${ORCHESTRATION_ENGINE_ARTIFACT:-cattle.jar}' \ - 'orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04}' \ - 'orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-0733430fac11892a17ba53749fe02d99d26b1f52}' \ + 'orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-637ddaa42cd93c019b4d0813d7053b71dc42797a7f3ac2aa4b10fcc7e304cb31}' \ + 'orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-9c884710e5ea3d4136d80a870d9de9485674f3c3}' \ 'CATTLE_CATTLE_VERSION="${orchestration_engine_release_tag}"' \ 'cattle-resources-${ORCHESTRATION_ENGINE_VERSION}.jar' \ 'test "${hazelcast_entry}" = "WEB-INF/lib/hazelcast-5.7.5.jar"'; do @@ -1565,10 +1565,10 @@ fi if grep -Fxq '## Current source candidate' README.md; then for candidate_readme_marker in \ '' \ - 'Server `v1.6.522` is a prepared source candidate, not a published image.' \ + 'Server `v1.6.537` is a prepared source candidate, not a published image.' \ 'run them only after its official release' \ 'This candidate is not yet available' \ - 'ghcr.io/pasturestack/server:v1.6.522'; do + 'ghcr.io/pasturestack/server:v1.6.537'; do require_marker README.md "$candidate_readme_marker" \ SERVER_CURRENT_CANDIDATE_README_MISSING done @@ -2163,7 +2163,7 @@ done jq -e ' ["CVE-2026-107928","CVE-2026-107929","CVE-2026-86409","CVE-2026-86410","CVE-2026-86412","CVE-2026-86414","CVE-2026-87862","CVE-2026-87863","CVE-2026-87864","CVE-2026-87865","CVE-2026-92386","CVE-2026-92387","CVE-2026-92388","CVE-2026-92389","CVE-2026-92390","CVE-2026-92391","CVE-2026-92392","CVE-2026-94266"] as $curl_fixed_cves | .["@context"] == "https://openvex.dev/ns/v0.2.0" - and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.536" + and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.537" and (.statements | length) == 69 and ([.statements[].vulnerability.name] | length == (unique | length)) and ([.statements[] | select(.status == "fixed") | .vulnerability.name] | sort) @@ -2201,7 +2201,7 @@ jq -r ' | @tsv ' "$runtime_vendor_pending" | LC_ALL=C sort -u >"$vendor_pending_fixture" bash "$vendor_pending_validator" "$runtime_vendor_pending" \ - "$vendor_pending_fixture" v1.6.536 >/dev/null + "$vendor_pending_fixture" v1.6.537 >/dev/null bash scripts/test-vendor-pending-findings.sh >/dev/null rm -f "$vendor_pending_fixture" trap - EXIT @@ -2290,4 +2290,4 @@ for release_readback_contract in \ fi done -printf 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.536 base=v1.6.460 engine=0.183.349 web_console=1.6.189 catalog_service=0.20.13 webhook_automation_service=0.10.4 authentication_service=0.4.43 curl=8.18.0-1ubuntu2.8 freemarker=2.3.35 artifact_scan=required vendor_pending=exact-set role_matrix=qa-required locale_layout=qa-required\n' +printf 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.537 base=v1.6.460 engine=0.183.350 web_console=1.6.190 catalog_service=0.20.13 webhook_automation_service=0.10.4 authentication_service=0.4.43 curl=8.18.0-1ubuntu2.8 freemarker=2.3.35 artifact_scan=required vendor_pending=exact-set role_matrix=qa-required locale_layout=qa-required\n' diff --git a/scripts/test-current-server-packaging-contract.py b/scripts/test-current-server-packaging-contract.py index 963e0c9b6e..944b246a92 100644 --- a/scripts/test-current-server-packaging-contract.py +++ b/scripts/test-current-server-packaging-contract.py @@ -17,21 +17,21 @@ PUBLISHED_508 = 'Server `v1.6.508` 已正式發布,封裝 Web Console `1.6.171`。' STALE_508_CANDIDATE = 'Server `v1.6.508` candidate packages Web Console `1.6.171`' COMPATIBILITY_CODE = 'SERVER_CREATE_RESPONSE_ORDER_COMPATIBILITY_MISSING' -WEB_SHA = '1c90e273b7db8ebf9d851a0ae1ec49dc59067b5ee1099ea3886919c1a79ccdfc' -WEB_SOURCE = 'f30f5e81dd9ee25878c3aff681eed5bb61883453' +WEB_SHA = 'b06612812113fb4b54cf0f2b4754af077406306fd72407e04b17f2ad9f4dc927' +WEB_SOURCE = '9ff823c2233e2041c2f00bb56a91d147a7feaa1d' CATALOG_COMMIT = 'b6b658888fce50d3ec217eb4eba0f26ab0113baf' -ENGINE_SHA = '6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04' -ENGINE_SOURCE = '0733430fac11892a17ba53749fe02d99d26b1f52' +ENGINE_SHA = '637ddaa42cd93c019b4d0813d7053b71dc42797a7f3ac2aa4b10fcc7e304cb31' +ENGINE_SOURCE = '9c884710e5ea3d4136d80a870d9de9485674f3c3' OLD_COORDINATES = { - 'v1.6.536': 'v1.6.521', - '1.6.189': '1.6.181', + 'v1.6.537': 'v1.6.521', + '1.6.190': '1.6.181', WEB_SHA: '9199681f2c4311f3fbe8727fcf0f6fa136c9bafe9fbe9d13878c55df442a7a03', WEB_SOURCE: '7f2bdad0c90a3241693c2ddd4475202ababba550', CATALOG_COMMIT: '7670ffd81d5f0b5570197fb03c7e55b46da45bf3', } -# Engine349 and Web189 use the reviewed component input identities. +# Engine350 and Web190 use the reviewed component input identities. # Published521 component values remain mutation controls. -# Component coordinates do not establish Server536 artifact/runtime PASS. +# Component coordinates do not establish Server537 artifact/runtime PASS. CATALOG_FIELDS = ( ('VERSION', 'version', '0.20.13'), ('COMMIT', 'commit', '4c39c73a8131ba06e9ff0aaec3b95cc27e049324'), @@ -41,25 +41,25 @@ ('LICENSE_SHA256', 'license_sha256', '0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594'), ) LEGACY_ENGINE_COORDINATES = { - '0.183.349': '0.183.337', + '0.183.350': '0.183.337', ENGINE_SHA: '7e45189f2b57097efc7929c04ddf7767aebbe027d1b9f90023aa6711522c5c80', ENGINE_SOURCE: 'ba041fe312dfe97fc1e5144af576ddcf1b573d8e', } EXPECTED = { COMPATIBILITY_CODE: (COMPATIBILITY, PUBLISHED_508), - 'SERVER_INCREMENTAL_RELEASE_DEFAULT_MISSING': (DOCKER, 'ARG SERVER_RELEASE_TAG=v1.6.536'), + 'SERVER_INCREMENTAL_RELEASE_DEFAULT_MISSING': (DOCKER, 'ARG SERVER_RELEASE_TAG=v1.6.537'), 'SERVER_INCREMENTAL_RELEASE_VERSION_MISSING': (DOCKER, 'org.opencontainers.image.version="${SERVER_RELEASE_TAG}"'), 'SERVER_INCREMENTAL_RELEASE_RUNTIME_VERSION_MISSING': (DOCKER, 'ENV CATTLE_RANCHER_SERVER_VERSION=${SERVER_RELEASE_TAG}'), - 'SERVER_INCREMENTAL_WEB_CONSOLE_VERSION_MISSING': (DOCKER, 'ARG WEB_CONSOLE_RELEASE_TAG=1.6.189'), - 'SERVER_INCREMENTAL_WEB_CONSOLE_ARTIFACT_MISSING': (DOCKER, 'ARG WEB_CONSOLE_ARTIFACT=web-console-1.6.189.tar.gz'), + 'SERVER_INCREMENTAL_WEB_CONSOLE_VERSION_MISSING': (DOCKER, 'ARG WEB_CONSOLE_RELEASE_TAG=1.6.190'), + 'SERVER_INCREMENTAL_WEB_CONSOLE_ARTIFACT_MISSING': (DOCKER, 'ARG WEB_CONSOLE_ARTIFACT=web-console-1.6.190.tar.gz'), 'SERVER_INCREMENTAL_WEB_CONSOLE_HASH_MISSING': (DOCKER, 'ARG WEB_CONSOLE_ARTIFACT_SHA256=' + WEB_SHA), 'SERVER_INCREMENTAL_WEB_CONSOLE_COMMIT_MISSING': (DOCKER, 'ARG WEB_CONSOLE_COMMIT=' + WEB_SOURCE), 'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_COMMIT_MISSING': (BUILD, 'web_console_commit=${WEB_CONSOLE_COMMIT:-' + WEB_SOURCE + '}'), - 'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_VERSION_MISSING': (BUILD, 'web_console_release_tag=${WEB_CONSOLE_RELEASE_TAG:-1.6.189}'), - 'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_ARTIFACT_MISSING': (BUILD, 'web_console_artifact=${WEB_CONSOLE_ARTIFACT:-web-console-1.6.189.tar.gz}'), + 'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_VERSION_MISSING': (BUILD, 'web_console_release_tag=${WEB_CONSOLE_RELEASE_TAG:-1.6.190}'), + 'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_ARTIFACT_MISSING': (BUILD, 'web_console_artifact=${WEB_CONSOLE_ARTIFACT:-web-console-1.6.190.tar.gz}'), 'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_HASH_MISSING': (BUILD, 'web_console_artifact_sha256=${WEB_CONSOLE_ARTIFACT_SHA256:-' + WEB_SHA + '}'), - 'SERVER_INCREMENTAL_RELEASE_BUILD_VERSION_MISSING': (BUILD, 'image=${IMAGE:-pasturestack-validation/server:v1.6.536}'), - 'SERVER_INCREMENTAL_RELEASE_BUILD_DEFAULT_MISSING': (BUILD, 'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.536}'), + 'SERVER_INCREMENTAL_RELEASE_BUILD_VERSION_MISSING': (BUILD, 'image=${IMAGE:-pasturestack-validation/server:v1.6.537}'), + 'SERVER_INCREMENTAL_RELEASE_BUILD_DEFAULT_MISSING': (BUILD, 'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.537}'), 'SERVER_INCREMENTAL_RELEASE_BUILD_RUNTIME_VERSION_MISSING': (BUILD, 'CATTLE_RANCHER_SERVER_VERSION="${server_release_tag}"'), 'SERVER_WEB_CONSOLE_RUNTIME_VERSION_GATE_MISSING': (BUILD, 'test "$(cat "${web_root}/VERSION.txt")" = "${WEB_CONSOLE_RELEASE_TAG}"'), 'SERVER_VOLUME_NATIVE_READ_ONLY_BUILD_GATE_MISSING': (DOCKER, 'grep -F \'"volume.isNative" : "r"\' >/dev/null'), @@ -80,18 +80,18 @@ CREATE_RESPONSE_CODES = ['SERVER_WEB_CREATE_IDENTITY_BUILD_GATE_MISSING','SERVER_WEB_CANONICAL_RECORD_BUILD_GATE_MISSING','SERVER_WEB_CREATE_IDENTITY_RUNTIME_GATE_MISSING','SERVER_WEB_CANONICAL_RECORD_RUNTIME_GATE_MISSING'] ENGINE_EXPECTED = { 'SERVER_INCREMENTAL_ENGINE_REPLACEMENT_MISSING': (DOCKER, 'release_engine_marker', ( - 'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.349', + 'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.350', 'ARG ORCHESTRATION_ENGINE_ARTIFACT=cattle.jar', 'ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=' + ENGINE_SHA, 'ARG ORCHESTRATION_ENGINE_COMMIT=' + ENGINE_SOURCE, - 'ARG ORCHESTRATION_ENGINE_VERSION=0.183.349', + 'ARG ORCHESTRATION_ENGINE_VERSION=0.183.350', 'grep -Fx "Implementation-Version: ${ORCHESTRATION_ENGINE_VERSION}"', 'cattle-resources-${ORCHESTRATION_ENGINE_VERSION}.jar', 'cattle-app-config-${ORCHESTRATION_ENGINE_VERSION}.jar', 'ENV CATTLE_CATTLE_VERSION=${ORCHESTRATION_ENGINE_RELEASE_TAG}', )), 'SERVER_INCREMENTAL_ENGINE_BUILD_COORDINATE_MISSING': (BUILD, 'release_engine_build_marker', ( - 'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.349}', + 'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.350}', 'orchestration_engine_artifact=${ORCHESTRATION_ENGINE_ARTIFACT:-cattle.jar}', 'orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-' + ENGINE_SHA + '}', 'orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-' + ENGINE_SOURCE + '}', @@ -470,15 +470,15 @@ def verify(files, gate=GATE): pipeline = r'(?:^|[;\n])\s*' + re.escape(marker) + r'(?=\s*(?:;|\n|$))' if len(re.findall(pipeline, source)) != 1: raise AssertionError('CURRENT_CATALOG_HASH_BYPASS') - if 'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.536"' not in gate: + if 'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.537"' not in gate: raise AssertionError('CURRENT_VEX_GATE_PIN_MISMATCH') - if '"$vendor_pending_fixture" v1.6.536 >/dev/null' not in gate: + if '"$vendor_pending_fixture" v1.6.537 >/dev/null' not in gate: raise AssertionError('CURRENT_VENDOR_GATE_PIN_MISMATCH') - if json.loads(files[VEX]).get('@id') != 'https://github.com/PastureStack/server/security/openvex/v1.6.536': + if json.loads(files[VEX]).get('@id') != 'https://github.com/PastureStack/server/security/openvex/v1.6.537': raise AssertionError('CURRENT_VEX_RELEASE_MISMATCH') - if json.loads(files[VENDOR]).get('release') != 'v1.6.536': + if json.loads(files[VENDOR]).get('release') != 'v1.6.537': raise AssertionError('CURRENT_VENDOR_RELEASE_MISMATCH') - if 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.536 base=v1.6.460 engine=0.183.349 web_console=1.6.189 catalog_service=0.20.13 ' not in gate: + if 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.537 base=v1.6.460 engine=0.183.350 web_console=1.6.190 catalog_service=0.20.13 ' not in gate: raise AssertionError('CURRENT_SUMMARY_MISMATCH') verify_incremental_contract(files, gate) @@ -492,11 +492,11 @@ def previous_gate(gate=GATE): if stale(marker) != marker: replacements["'" + marker + "' "] = "'" + stale(marker) + "' " replacements.update({ - 'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.536"': + 'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.537"': 'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.521"', - '"$vendor_pending_fixture" v1.6.536 >/dev/null': + '"$vendor_pending_fixture" v1.6.537 >/dev/null': '"$vendor_pending_fixture" v1.6.521 >/dev/null', - 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.536 base=v1.6.460 engine=0.183.349 web_console=1.6.189 catalog_service=0.20.13 ': + 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.537 base=v1.6.460 engine=0.183.350 web_console=1.6.190 catalog_service=0.20.13 ': 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.521 base=v1.6.460 engine=0.183.340 web_console=1.6.181 catalog_service=0.20.12 ', }) for marker, stale_marker in replacements.items(): @@ -863,7 +863,7 @@ def test_candidate_coordinates_and_pending_rejection_use_actual_pin_predicates(s self.assertEqual(len(patterns), 2) for variable, pattern in patterns: default = re.search(r'^' + variable + r'=\$\{[^:}]+:-([^}]+)\}$', FILES[BUILD], re.M).group(1) - expected_valid = resolved if variable.endswith('artifact_sha256') else True + expected_valid = resolved if variable.endswith('artifact_sha256') else re.fullmatch(r'[0-9a-f]{40}', WEB_SOURCE) is not None self.assertEqual(re.fullmatch(pattern, default) is not None, expected_valid) self.assertIsNone(re.fullmatch(pattern, 'PENDING_WEB0_ARCHIVE_SHA256')) actual_guard = '[[ "$' + variable + '" =~ ' + pattern + ' ]]' @@ -988,7 +988,7 @@ def test_each_old_engine_coordinate_rejected(self): self.assertGreater(checked, 0) def test_historical_engine340_cannot_be_packaged(self): - old = {'0.183.349': '0.183.340', + old = {'0.183.350': '0.183.340', ENGINE_SHA: '5e5a1b908b43bf3824fc3bb2108bd661cd5199ce9bcfd187e0b18b5608a38cea', ENGINE_SOURCE: 'ff0a41e7676211043eb4f755a306a9e2a19abee1'} checked = 0 @@ -1009,7 +1009,7 @@ def test_historical_engine340_cannot_be_packaged(self): def test_immediately_previous_engine341_cannot_be_packaged(self): - old = {'0.183.349': '0.183.341', + old = {'0.183.350': '0.183.341', ENGINE_SHA: '3ede1ad28b7a7e0754c4c953bd486162f7ffe0b2f76ce384ec485632af6b8e6d', ENGINE_SOURCE: 'b245cf778479445ded0786d3898b03fea153212e'} checked = 0 @@ -1030,7 +1030,7 @@ def test_immediately_previous_engine341_cannot_be_packaged(self): def test_immediately_previous_engine342_cannot_be_packaged(self): - old = {'0.183.349': '0.183.342', + old = {'0.183.350': '0.183.342', ENGINE_SHA: '3533f247392795329c92516a7966510aafbe81a52e3f922e5ec657a2071363b5', ENGINE_SOURCE: 'ddae4bb8e12806f70816f5782cd999eccd0f2ce6'} checked = 0 @@ -1051,7 +1051,7 @@ def test_immediately_previous_engine342_cannot_be_packaged(self): def test_immediately_previous_engine343_cannot_be_packaged(self): - old = {'0.183.349': '0.183.343', + old = {'0.183.350': '0.183.343', ENGINE_SHA: 'b29c0057f96dbae38bfe2c663c63bbe4c8b5c755b3090f39414aa51f9813025f', ENGINE_SOURCE: '5aa9d8978c75a7fe63330453c399a92716d88568'} checked = 0 @@ -1072,7 +1072,7 @@ def test_immediately_previous_engine343_cannot_be_packaged(self): def test_immediately_previous_engine344_cannot_be_packaged(self): - old = {'0.183.349': '0.183.344', + old = {'0.183.350': '0.183.344', ENGINE_SHA: 'ffafa4700156b74ec11bcae1b830738e49943f1a3b8b0565895ed6d7726eebf1', ENGINE_SOURCE: '72c42e6f2000301fe03ffd2442fb9ee89aee120c'} checked = 0 @@ -1092,7 +1092,7 @@ def test_immediately_previous_engine344_cannot_be_packaged(self): self.assertGreater(checked, 0) def test_immediately_previous_engine345_cannot_be_packaged(self): - old = {'0.183.349': '0.183.345', + old = {'0.183.350': '0.183.345', ENGINE_SHA: '780263c4a884527fa80a28b998ad4bda88b9ad6002a687f9f074602ecad46e62', ENGINE_SOURCE: 'd27d4ac73fa05ae43b9ae0c32875780e8a3765b1'} checked = 0 @@ -1112,7 +1112,7 @@ def test_immediately_previous_engine345_cannot_be_packaged(self): self.assertGreater(checked, 0) def test_immediately_previous_engine346_cannot_be_packaged(self): - old = {'0.183.349': '0.183.346', + old = {'0.183.350': '0.183.346', ENGINE_SHA: '9deeda5758b7f04135441a203092dd0308d90b65d25037b62ef4f9361d3cf806', ENGINE_SOURCE: 'e250e4a17958216c30c1f5d0d31f7b6418a968d5'} checked = 0 @@ -1267,7 +1267,7 @@ def test_current_readme_keeps_install_and_upgrade_contract(self): def test_current_readme_status_specific_prose_does_not_block_publication_transition(self): common = GATE.split('for current_readme_marker in ', 1)[1].split('; do', 1)[0] self.assertNotIn('candidate', common) - self.assertNotIn('v1.6.522', common) + self.assertNotIn('v1.6.537', common) self.assertIn("grep -Fqi 'keep all three named volumes' README.md", GATE) status = GATE.split("if grep -Fxq '## Current source candidate' README.md; then", 1)[1] candidate, published = status.split("elif grep -Fxq '## Current release' README.md; then", 1) @@ -1276,7 +1276,7 @@ def test_current_readme_status_specific_prose_does_not_block_publication_transit self.assertIn('This candidate is not yet available', candidate) self.assertIn('SERVER_CURRENT_PUBLISHED_README_MISSING', published) self.assertNotIn('candidate', published) - self.assertNotIn('v1.6.522', published) + self.assertNotIn('v1.6.537', published) if __name__ == '__main__': diff --git a/scripts/test-published-install-gate.py b/scripts/test-published-install-gate.py index dbda06b9a5..bb1a1ed1c1 100644 --- a/scripts/test-published-install-gate.py +++ b/scripts/test-published-install-gate.py @@ -20,24 +20,24 @@ 'COMPATIBILITY.md': 'Server v1.6.499 preparing; no published digest.\nPublished Server v1.6.498\n' + PUBLISHED_IMAGE, 'docs/releases/server-1.6.498.md': '# Server v1.6.498\n\nOfficially published: ' + PUBLISHED_IMAGE, } -CANDIDATE_IMAGE = 'ghcr.io/pasturestack/server:v1.6.522' +CANDIDATE_IMAGE = 'ghcr.io/pasturestack/server:v1.6.537' CANDIDATE_FILES = dict(FILES) intro, quick = FILES['README.md'].split('## Quick start', 1) CANDIDATE_FILES['README.md'] = ( '\n\n' + intro.replace('## Current release', '## Current source candidate') + - 'Server `v1.6.522` is a prepared source candidate, not a published image.\n' - '[candidate note](docs/releases/server-1.6.522.md)\n\n## Quick start\n\n' + 'Server `v1.6.537` is a prepared source candidate, not a published image.\n' + '[candidate note](docs/releases/server-1.6.537.md)\n\n## Quick start\n\n' 'run them only after its official release\nThis candidate is not yet available\n' + quick.replace(INSTALL_IMAGE, CANDIDATE_IMAGE)) CANDIDATE_FILES[PERFORMANCE] = ( 'run it only after its official release and image have been published and read back.\n' - 'is not yet available from GHCR\n[candidate note](../releases/server-1.6.522.md)\n' + + 'is not yet available from GHCR\n[candidate note](../releases/server-1.6.537.md)\n' + FILES[PERFORMANCE].replace(INSTALL_IMAGE, CANDIDATE_IMAGE)) CANDIDATE_FILES['COMPATIBILITY.md'] = ( - '## Server v1.6.522 prepared, not published\n\n' + FILES['COMPATIBILITY.md']) -CANDIDATE_FILES['docs/releases/server-1.6.522.md'] = ( - '# Server v1.6.522 candidate\n\n' + '## Server v1.6.537 prepared, not published\n\n' + FILES['COMPATIBILITY.md']) +CANDIDATE_FILES['docs/releases/server-1.6.537.md'] = ( + '# Server v1.6.537 candidate\n\n' 'Prepared source only; no Server image or release has been published.\n') @@ -62,7 +62,7 @@ def test_checked_out_install_documents_match_actual_latest_publication(self): files[name] = notes.read_text(encoding='utf-8') verify(files) - def test_explicit_522_candidate_keeps_publication_evidence_and_numeric_examples(self): + def test_explicit_537_candidate_keeps_publication_evidence_and_numeric_examples(self): verify(CANDIDATE_FILES) files = dict(CANDIDATE_FILES) files['COMPATIBILITY.md'] = files['COMPATIBILITY.md'].replace(PUBLISHED_IMAGE, '') @@ -75,12 +75,12 @@ def test_candidate_cannot_hide_warning_mismatch_or_fabricate_publication(self): ('README.md', 'run them only after its official release', '', 'DISCLOSURE_MISSING'), (PERFORMANCE, 'is not yet available from GHCR', '', 'DISCLOSURE_MISSING'), (PERFORMANCE, CANDIDATE_IMAGE, INSTALL_IMAGE, 'PERFORMANCE_MISMATCH'), - ('docs/releases/server-1.6.522.md', '# Server v1.6.522 candidate', '# Server v1.6.522', 'NOTES_MISMATCH'), - ('README.md', 'Server `v1.6.522` is a prepared source candidate, not a published image.', - 'Server `v1.6.522` is a prepared source candidate, not a published image.\n' + + ('docs/releases/server-1.6.537.md', '# Server v1.6.537 candidate', '# Server v1.6.537', 'NOTES_MISMATCH'), + ('README.md', 'Server `v1.6.537` is a prepared source candidate, not a published image.', + 'Server `v1.6.537` is a prepared source candidate, not a published image.\n' + CANDIDATE_IMAGE + '@sha256:' + 'a' * 64, 'PUBLICATION_MISMATCH'), - ('COMPATIBILITY.md', '## Server v1.6.522 prepared, not published', - '## Server v1.6.522 published\n' + CANDIDATE_IMAGE + '@sha256:' + 'a' * 64, + ('COMPATIBILITY.md', '## Server v1.6.537 prepared, not published', + '## Server v1.6.537 published\n' + CANDIDATE_IMAGE + '@sha256:' + 'a' * 64, 'PUBLICATION_MISMATCH')): with self.subTest(name=name, old=old): files = dict(CANDIDATE_FILES) @@ -88,15 +88,15 @@ def test_candidate_cannot_hide_warning_mismatch_or_fabricate_publication(self): with self.assertRaisesRegex(SystemExit, error): verify(files) - def test_actual_522_publication_needs_correct_docs_not_a_gate_code_change(self): + def test_actual_537_publication_needs_correct_docs_not_a_gate_code_change(self): files = dict(FILES) - files['README.md'] = files['README.md'].replace('v1.6.498', 'v1.6.522').replace('server-1.6.498.md', 'server-1.6.522.md') - files[PERFORMANCE] = files[PERFORMANCE].replace('v1.6.498', 'v1.6.522') + files['README.md'] = files['README.md'].replace('v1.6.498', 'v1.6.537').replace('server-1.6.498.md', 'server-1.6.537.md') + files[PERFORMANCE] = files[PERFORMANCE].replace('v1.6.498', 'v1.6.537') image = CANDIDATE_IMAGE + '@sha256:' + 'a' * 64 files['COMPATIBILITY.md'] += '\n' + image - files['docs/releases/server-1.6.522.md'] = '# Server v1.6.522\n\nOfficially published: ' + image + files['docs/releases/server-1.6.537.md'] = '# Server v1.6.537\n\nOfficially published: ' + image verify(files) - files['docs/releases/server-1.6.522.md'] = CANDIDATE_FILES['docs/releases/server-1.6.522.md'] + files['docs/releases/server-1.6.537.md'] = CANDIDATE_FILES['docs/releases/server-1.6.537.md'] with self.assertRaisesRegex(SystemExit, 'QUICK_START_MISMATCH'): verify(files) diff --git a/server/Dockerfile.web-compose-release b/server/Dockerfile.web-compose-release index dc86b80b86..5f0da5e9f5 100644 --- a/server/Dockerfile.web-compose-release +++ b/server/Dockerfile.web-compose-release @@ -55,9 +55,9 @@ ARG NODE_AGENT_BINARY_SHA256=ce8342e10da07c50cc414b471cadc67db4dd390e6e2dcb632b3 ARG NODE_AGENT_APPLY_SHA256=dd8cb342518a43e7468cc121db5c4e44b16731f2620b77ea0fd03c02c03766a9 ARG WEB_CONSOLE_RELEASE_BASE_URL=https://github.com/PastureStack/web-console/releases/download -ARG WEB_CONSOLE_RELEASE_TAG=1.6.189 -ARG WEB_CONSOLE_ARTIFACT=web-console-1.6.189.tar.gz -ARG WEB_CONSOLE_ARTIFACT_SHA256=1c90e273b7db8ebf9d851a0ae1ec49dc59067b5ee1099ea3886919c1a79ccdfc +ARG WEB_CONSOLE_RELEASE_TAG=1.6.190 +ARG WEB_CONSOLE_ARTIFACT=web-console-1.6.190.tar.gz +ARG WEB_CONSOLE_ARTIFACT_SHA256=b06612812113fb4b54cf0f2b4754af077406306fd72407e04b17f2ad9f4dc927 ARG CATALOG_SERVICE_RELEASE_BASE_URL=https://github.com/PastureStack/catalog-service/releases/download ARG CATALOG_SERVICE_VERSION=0.20.13 ARG CATALOG_SERVICE_COMMIT=4c39c73a8131ba06e9ff0aaec3b95cc27e049324 @@ -79,9 +79,9 @@ ARG WEBHOOK_AUTOMATION_SERVICE_VERSION=0.10.4 ARG WEBHOOK_AUTOMATION_SERVICE_ARCHIVE_SHA256=49c4579829a04e758045fae02a5a9fca12bb0ba3af0d5e979cf9eb97f23a88a9 ARG WEBHOOK_AUTOMATION_SERVICE_BINARY_SHA256=98c7faea665b7eb95206b8c73a6f47d644c5d2d0eae53f274f6a15faf5205744 ARG ORCHESTRATION_ENGINE_RELEASE_BASE_URL=https://github.com/PastureStack/orchestration-engine/releases/download -ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.349 +ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.350 ARG ORCHESTRATION_ENGINE_ARTIFACT=cattle.jar -ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04 +ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=637ddaa42cd93c019b4d0813d7053b71dc42797a7f3ac2aa4b10fcc7e304cb31 ARG COMPOSE_EXECUTOR_RELEASE_BASE_URL=https://github.com/PastureStack/compose-cli/releases/download ARG COMPOSE_EXECUTOR_VERSION=0.14.37 ARG COMPOSE_EXECUTOR_ARCHIVE_SHA256=5ff465601930218f531885a384f231d969033e4cef794ce33d16bfe24e5c1c81 @@ -574,9 +574,9 @@ FROM ${BASE_IMAGE} ARG SOURCE_DATE_EPOCH ARG PASTURESTACK_SERVER_REVISION -ARG SERVER_RELEASE_TAG=v1.6.536 -ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.349 -ARG ORCHESTRATION_ENGINE_VERSION=0.183.349 +ARG SERVER_RELEASE_TAG=v1.6.537 +ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.350 +ARG ORCHESTRATION_ENGINE_VERSION=0.183.350 ARG ENGINE_READONLY_SCHEMA_SHA256=7f274219e8dd9c6d750a408a6edec1448b564f4b16ba2204c425c5b45cec2233 ARG ENGINE_RESTRICTED_SCHEMA_SHA256=f854ba99260f29e324ab7446a8592996946038920ac9bcf17689d98d1ebc5e51 ARG HOST_API_VERSION=0.38.5 @@ -594,9 +594,9 @@ ARG FREETYPE_PACKAGE_VERSION=2.14.2+dfsg-1ubuntu0.2 ARG LIBPNG_PACKAGE_VERSION=1.6.57-1ubuntu0.1 ARG GLIBC_PACKAGE_VERSION=2.43-2ubuntu2.4 ARG PERL_PACKAGE_VERSION=5.40.1-7ubuntu0.3 -ARG WEB_CONSOLE_RELEASE_TAG=1.6.189 -ARG WEB_CONSOLE_ARTIFACT_SHA256=1c90e273b7db8ebf9d851a0ae1ec49dc59067b5ee1099ea3886919c1a79ccdfc -ARG WEB_CONSOLE_COMMIT=f30f5e81dd9ee25878c3aff681eed5bb61883453 +ARG WEB_CONSOLE_RELEASE_TAG=1.6.190 +ARG WEB_CONSOLE_ARTIFACT_SHA256=b06612812113fb4b54cf0f2b4754af077406306fd72407e04b17f2ad9f4dc927 +ARG WEB_CONSOLE_COMMIT=9ff823c2233e2041c2f00bb56a91d147a7feaa1d ARG CATALOG_SERVICE_VERSION=0.20.13 ARG CATALOG_SERVICE_COMMIT=4c39c73a8131ba06e9ff0aaec3b95cc27e049324 ARG CATALOG_SERVICE_ARCHIVE_SHA256=29626181cb8489b016e5975ffaddc00b2a32d290b1c0066e833d27fa7a5edf83 @@ -615,8 +615,8 @@ ARG WEBHOOK_AUTOMATION_SERVICE_VERSION=0.10.4 ARG WEBHOOK_AUTOMATION_SERVICE_COMMIT=400118b893843d2a7d7c65cc70c3449d76c4a8d8 ARG WEBHOOK_AUTOMATION_SERVICE_ARCHIVE_SHA256=49c4579829a04e758045fae02a5a9fca12bb0ba3af0d5e979cf9eb97f23a88a9 ARG WEBHOOK_AUTOMATION_SERVICE_BINARY_SHA256=98c7faea665b7eb95206b8c73a6f47d644c5d2d0eae53f274f6a15faf5205744 -ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04 -ARG ORCHESTRATION_ENGINE_COMMIT=0733430fac11892a17ba53749fe02d99d26b1f52 +ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=637ddaa42cd93c019b4d0813d7053b71dc42797a7f3ac2aa4b10fcc7e304cb31 +ARG ORCHESTRATION_ENGINE_COMMIT=9c884710e5ea3d4136d80a870d9de9485674f3c3 ARG HOST_PROVISIONER_VERSION=0.39.8 ARG HOST_PROVISIONER_COMMIT=385e5b536c108f17fdfcdec84c01750a5be5ab1c ARG HOST_PROVISIONER_ARCHIVE_SHA256=d775f36a613b1a486a5e60d6ad61fdbd1ebb4bd22422cbb6dcb70fdd7c4abf0c diff --git a/server/build-api-explorer-patch-image.sh b/server/build-api-explorer-patch-image.sh index 4fd050ebed..869e8cecaa 100755 --- a/server/build-api-explorer-patch-image.sh +++ b/server/build-api-explorer-patch-image.sh @@ -14,14 +14,14 @@ if [[ -n "$(git status --porcelain --untracked-files=normal)" ]]; then fi revision=${PASTURESTACK_SERVER_REVISION:-$(git rev-parse HEAD)} -server_release_tag=${SERVER_RELEASE_TAG:-v1.6.536} +server_release_tag=${SERVER_RELEASE_TAG:-v1.6.537} source_date_epoch=${SOURCE_DATE_EPOCH:-$(git show -s --format=%ct HEAD)} base_image=${BASE_IMAGE:-ghcr.io/pasturestack/server:v1.6.460@sha256:c855af8aea232dacc5bb6df68e2271d482c68b53c43ab0c108ec19118f5ab403} orchestration_engine_release_base_url=${ORCHESTRATION_ENGINE_RELEASE_BASE_URL:-https://github.com/PastureStack/orchestration-engine/releases/download} -orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.349} +orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.350} orchestration_engine_artifact=${ORCHESTRATION_ENGINE_ARTIFACT:-cattle.jar} -orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04} -orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-0733430fac11892a17ba53749fe02d99d26b1f52} +orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-637ddaa42cd93c019b4d0813d7053b71dc42797a7f3ac2aa4b10fcc7e304cb31} +orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-9c884710e5ea3d4136d80a870d9de9485674f3c3} orchestration_engine_version=${orchestration_engine_release_tag#v} engine_readonly_schema_sha256=${ENGINE_READONLY_SCHEMA_SHA256:-7f274219e8dd9c6d750a408a6edec1448b564f4b16ba2204c425c5b45cec2233} engine_restricted_schema_sha256=${ENGINE_RESTRICTED_SCHEMA_SHA256:-f854ba99260f29e324ab7446a8592996946038920ac9bcf17689d98d1ebc5e51} @@ -48,10 +48,10 @@ api_explorer_artifact=${API_EXPLORER_ARTIFACT:-api-explorer-1.1.18.tar.gz} api_explorer_artifact_sha256=${API_EXPLORER_ARTIFACT_SHA256:-92b718c46163018ea40c008ac552911f0eb610647377725405f4046dcd411f2c} api_explorer_commit=${API_EXPLORER_COMMIT:-3b1c39e8a116f58649d94233a384a0362c02b43e} web_console_release_base_url=${WEB_CONSOLE_RELEASE_BASE_URL:-https://github.com/PastureStack/web-console/releases/download} -web_console_release_tag=${WEB_CONSOLE_RELEASE_TAG:-1.6.189} -web_console_artifact=${WEB_CONSOLE_ARTIFACT:-web-console-1.6.189.tar.gz} -web_console_artifact_sha256=${WEB_CONSOLE_ARTIFACT_SHA256:-1c90e273b7db8ebf9d851a0ae1ec49dc59067b5ee1099ea3886919c1a79ccdfc} -web_console_commit=${WEB_CONSOLE_COMMIT:-f30f5e81dd9ee25878c3aff681eed5bb61883453} +web_console_release_tag=${WEB_CONSOLE_RELEASE_TAG:-1.6.190} +web_console_artifact=${WEB_CONSOLE_ARTIFACT:-web-console-1.6.190.tar.gz} +web_console_artifact_sha256=${WEB_CONSOLE_ARTIFACT_SHA256:-b06612812113fb4b54cf0f2b4754af077406306fd72407e04b17f2ad9f4dc927} +web_console_commit=${WEB_CONSOLE_COMMIT:-9ff823c2233e2041c2f00bb56a91d147a7feaa1d} catalog_service_release_base_url=${CATALOG_SERVICE_RELEASE_BASE_URL:-https://github.com/PastureStack/catalog-service/releases/download} catalog_service_version=${CATALOG_SERVICE_VERSION:-0.20.13} catalog_service_commit=${CATALOG_SERVICE_COMMIT:-4c39c73a8131ba06e9ff0aaec3b95cc27e049324} @@ -101,7 +101,7 @@ usage_telemetry_agent_archive_sha256=${USAGE_TELEMETRY_AGENT_ARCHIVE_SHA256:-5ce usage_telemetry_agent_binary_sha256=${USAGE_TELEMETRY_AGENT_BINARY_SHA256:-e62a21270142181315293d7e11482288ffe8fc4d91cc8fe07dacc90b461f3709} supported_docker_range='~v1.12.3 || ~v1.13.0 || ~v17.03.0 || ~v17.06.0 || ~v17.09.0 || ~v17.12.0 || ~v18.03.0 || ~v18.06.0 || ~v18.09.0 || ~v19.03.2 || v24.0.9 || >=v29.4.1 <=v29.7.2 || v29.8.0' newest_docker_version=v29.8.0 -image=${IMAGE:-pasturestack-validation/server:v1.6.536} +image=${IMAGE:-pasturestack-validation/server:v1.6.537} build_options=() [[ "$revision" =~ ^[0-9a-f]{40}$ ]] diff --git a/server/build-component-candidate.sh b/server/build-component-candidate.sh index 9ba51218b6..a05cd7f64c 100755 --- a/server/build-component-candidate.sh +++ b/server/build-component-candidate.sh @@ -14,10 +14,10 @@ for name in "${required[@]}"; do case "$name" in *_COMMIT) [[ ${!name} =~ ^[0-9a-f]{40}$ ]] ;; *) [[ ${!name} =~ ^[0-9a-f]{64}$ ]] ;; esac export "$name" done -export SERVER_RELEASE_TAG=${SERVER_RELEASE_TAG:-v1.6.535} -export ORCHESTRATION_ENGINE_RELEASE_TAG=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.349} +export SERVER_RELEASE_TAG=${SERVER_RELEASE_TAG:-v1.6.537} +export ORCHESTRATION_ENGINE_RELEASE_TAG=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.350} export ORCHESTRATION_ENGINE_ARTIFACT=cattle.jar -export WEB_CONSOLE_RELEASE_TAG=${WEB_CONSOLE_RELEASE_TAG:-1.6.189} +export WEB_CONSOLE_RELEASE_TAG=${WEB_CONSOLE_RELEASE_TAG:-1.6.190} export WEB_CONSOLE_ARTIFACT="web-console-${WEB_CONSOLE_RELEASE_TAG}.tar.gz" export WEBSOCKET_PROXY_VERSION=${WEBSOCKET_PROXY_VERSION:-0.23.15} export HOST_API_VERSION=${HOST_API_VERSION:-0.38.5} diff --git a/server/security/openvex.json b/server/security/openvex.json index 67427545aa..c737f88969 100644 --- a/server/security/openvex.json +++ b/server/security/openvex.json @@ -1,9 +1,9 @@ { "@context": "https://openvex.dev/ns/v0.2.0", - "@id": "https://github.com/PastureStack/server/security/openvex/v1.6.536", + "@id": "https://github.com/PastureStack/server/security/openvex/v1.6.537", "author": "PastureStack Security", - "timestamp": "2026-10-15T00:38:08Z", - "version": 56, + "timestamp": "2026-10-15T13:03:57Z", + "version": 57, "statements": [ { "vulnerability": { diff --git a/server/security/vendor-pending.json b/server/security/vendor-pending.json index ab0daf5356..e6fe7fd3f1 100644 --- a/server/security/vendor-pending.json +++ b/server/security/vendor-pending.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, - "release": "v1.6.536", - "generatedAt": "2026-10-15T02:44:00Z", + "release": "v1.6.537", + "generatedAt": "2026-10-15T13:03:57Z", "policy": { "allowedSeverities": [ "LOW",