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",