fix: package the qualified UI in release ISOs
This commit is contained in:
@@ -717,3 +717,45 @@ track AIUI changes and pass the checkout revision. Actual image qualification
|
|||||||
and public demo deployment remain pending. The demo/release VPS currently has
|
and public demo deployment remain pending. The demo/release VPS currently has
|
||||||
under1GiB free disk; capacity must be resolved before image/artifact publication.
|
under1GiB free disk; capacity must be resolved before image/artifact publication.
|
||||||
No running container, volume, release or repository was deleted.
|
No running container, volume, release or repository was deleted.
|
||||||
|
|
||||||
|
### Authorized release-storage cleanup — 2026-10-05
|
||||||
|
|
||||||
|
Operator approved removing only the old v1.8.13-alpha and v1.8.15-alpha ISO
|
||||||
|
attachments, then clarified that broader retention changes should be dropped if
|
||||||
|
that suffices. Both local ISO archives were independently hashed against their
|
||||||
|
published checksum files before removal. Gitea API deletion removed attachment
|
||||||
|
IDs219 and226 only; all other assets in both releases were verified unchanged.
|
||||||
|
Public server free space increased from887MiB to5.9GiB. Remaining historical
|
||||||
|
releases, OTA files, registry packages and application data were preserved.
|
||||||
|
Gitea's prior read-only storage doctor found no orphaned archives, attachments or
|
||||||
|
package blobs. No storage-doctor fix or package garbage collection was run.
|
||||||
|
Further removals are not planned; check exact final upload/image sizes first.
|
||||||
|
|
||||||
|
### Corrected binary deployed and restart verified
|
||||||
|
|
||||||
|
Final security backend SHA256
|
||||||
|
`560aa6006cd9ef8be95b1f7831cf3b53854e911622b50022bb4402ce0f8b010a`
|
||||||
|
built from e0b2181a after the complete1,681-test isolated pass. Deployed dev,
|
||||||
|
yaya and Shorty: health200, both embedded helper files match reviewed source,
|
||||||
|
active HTTP/HTTPS defaults are guarded, and all existing container IDs/start
|
||||||
|
times are unchanged. Backup per node: `support/190-guard-560aa6006cd9`.
|
||||||
|
The first dev check incorrectly inspected sites-available rather than the actual
|
||||||
|
regular sites-enabled file; automatic backend rollback ran. Corrected check
|
||||||
|
uses the helper's active-dashboard resolution, and the second deployment passes.
|
||||||
|
This was a qualification-script path error; retain the first failed log.
|
||||||
|
|
||||||
|
Shorty's final backend manager restart passed302 continuous public HTTP/HTTPS
|
||||||
|
RPC denial probes, followed by healthy management. Existing public32-case and
|
||||||
|
read-only Angor acceptance are rerunning against this exact deployed binary.
|
||||||
|
Logs: `/tmp/archy-190-guard-dev-deploy-2.log`,
|
||||||
|
`/tmp/archy-190-guard-yaya-deploy.log`, `/tmp/archy-190-guard-shorty-deploy.log`,
|
||||||
|
`/tmp/archy-190-final-shorty-restart-security.log`.
|
||||||
|
|
||||||
|
ISO release packaging now explicitly selects the qualified dashboard/AIUI
|
||||||
|
payload rather than capturing a live node's cached runtime files or choosing
|
||||||
|
AIUI by timestamp. Three executable builder-branch fixtures pass qualified,
|
||||||
|
missing and partial payloads; missing inputs fail without a live-node fallback.
|
||||||
|
The release wrapper sets this path and the release harness includes the test.
|
||||||
|
Accepted companion54 APK/metadata replace the stale copies in the packaging
|
||||||
|
staging directory; exact SHA remains ceb58a7d…fab1a1. Final ISO and OTA package
|
||||||
|
acceptance/signatures remain pending.
|
||||||
|
|||||||
@@ -1448,7 +1448,19 @@ mkdir -p "$ARCH_DIR/web-ui"
|
|||||||
|
|
||||||
# Try to get from live server first (unless BUILD_FROM_SOURCE=1)
|
# Try to get from live server first (unless BUILD_FROM_SOURCE=1)
|
||||||
WEBUI_CAPTURED=0
|
WEBUI_CAPTURED=0
|
||||||
if [ "$BUILD_FROM_SOURCE" != "1" ]; then
|
if [ -n "${ARCHIPELAGO_WEB_UI:-}" ]; then
|
||||||
|
# Release builds supply the qualified payload explicitly. Never substitute
|
||||||
|
# a running node's cached runtime files or an older installed dashboard.
|
||||||
|
if [ ! -f "$ARCHIPELAGO_WEB_UI/index.html" ] || \
|
||||||
|
[ ! -f "$ARCHIPELAGO_WEB_UI/aiui/index.html" ] || \
|
||||||
|
[ ! -f "$ARCHIPELAGO_WEB_UI/aiui/BUILD-INFO" ]; then
|
||||||
|
echo "ERROR: ARCHIPELAGO_WEB_UI must contain the qualified dashboard and AIUI"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cp -r "$ARCHIPELAGO_WEB_UI/." "$ARCH_DIR/web-ui/"
|
||||||
|
WEBUI_CAPTURED=1
|
||||||
|
fi
|
||||||
|
if [ "$WEBUI_CAPTURED" = "0" ] && [ "$BUILD_FROM_SOURCE" != "1" ]; then
|
||||||
# Direct copy from local filesystem (when running on target with sudo)
|
# Direct copy from local filesystem (when running on target with sudo)
|
||||||
if [ -d "/opt/archipelago/web-ui" ] && [ "$(ls -A /opt/archipelago/web-ui 2>/dev/null)" ]; then
|
if [ -d "/opt/archipelago/web-ui" ] && [ "$(ls -A /opt/archipelago/web-ui 2>/dev/null)" ]; then
|
||||||
cp -r /opt/archipelago/web-ui/* "$ARCH_DIR/web-ui/"
|
cp -r /opt/archipelago/web-ui/* "$ARCH_DIR/web-ui/"
|
||||||
@@ -1504,6 +1516,9 @@ AIUI_INCLUDED=0
|
|||||||
# or yesterday's hashed assets linger next to today's forever.
|
# or yesterday's hashed assets linger next to today's forever.
|
||||||
AIUI_SRC=""
|
AIUI_SRC=""
|
||||||
AIUI_NEWEST=0
|
AIUI_NEWEST=0
|
||||||
|
if [ -n "${ARCHIPELAGO_WEB_UI:-}" ]; then
|
||||||
|
AIUI_SRC="$ARCHIPELAGO_WEB_UI/aiui"
|
||||||
|
else
|
||||||
for AIUI_DIR in \
|
for AIUI_DIR in \
|
||||||
"$SCRIPT_DIR/../../aiui/packages/app/dist" \
|
"$SCRIPT_DIR/../../aiui/packages/app/dist" \
|
||||||
"$SCRIPT_DIR/../../AIUI/packages/app/dist" \
|
"$SCRIPT_DIR/../../AIUI/packages/app/dist" \
|
||||||
@@ -1520,6 +1535,7 @@ for AIUI_DIR in \
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
if [ -n "$AIUI_SRC" ]; then
|
if [ -n "$AIUI_SRC" ]; then
|
||||||
echo " Including AIUI from $AIUI_SRC (newest of the candidates)..."
|
echo " Including AIUI from $AIUI_SRC (newest of the candidates)..."
|
||||||
mkdir -p "$ARCH_DIR/web-ui/aiui"
|
mkdir -p "$ARCH_DIR/web-ui/aiui"
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ build_iso() {
|
|||||||
BUILD_FROM_SOURCE=0
|
BUILD_FROM_SOURCE=0
|
||||||
DEV_SERVER=localhost
|
DEV_SERVER=localhost
|
||||||
ARCHIPELAGO_BIN="$REPO/core/target/release/archipelago"
|
ARCHIPELAGO_BIN="$REPO/core/target/release/archipelago"
|
||||||
|
ARCHIPELAGO_WEB_UI="$REPO/web/dist/neode-ui"
|
||||||
)
|
)
|
||||||
[ -n "$RC_OVERRIDE" ] && env_args+=(RC="$RC_OVERRIDE")
|
[ -n "$RC_OVERRIDE" ] && env_args+=(RC="$RC_OVERRIDE")
|
||||||
sudo -E env "${env_args[@]}" nice -n 5 bash image-recipe/build-debian-iso.sh
|
sudo -E env "${env_args[@]}" nice -n 5 bash image-recipe/build-debian-iso.sh
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Exercise the ISO builder's actual payload-selection branches, without a build."""
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
ROOT = pathlib.Path(__file__).resolve().parents[2]
|
||||||
|
source = (ROOT / 'image-recipe/_archived/build-auto-installer-iso.sh').read_text()
|
||||||
|
capture = source.split('WEBUI_CAPTURED=0', 1)[1].split('# Include AIUI web app', 1)[0]
|
||||||
|
select = source.split('AIUI_SRC=""', 1)[1].split('if [ -n "$AIUI_SRC" ]; then', 1)[0]
|
||||||
|
program = 'set -eu\nWEBUI_CAPTURED=0\n' + capture + '\nAIUI_SRC=""\n' + select + '\nprintf "%s\\n" "$AIUI_SRC"\n'
|
||||||
|
with tempfile.TemporaryDirectory(prefix='archy-iso-qualified-ui-') as tmp:
|
||||||
|
base = pathlib.Path(tmp)
|
||||||
|
qualified = base / 'qualified'
|
||||||
|
(qualified / 'aiui').mkdir(parents=True)
|
||||||
|
(qualified / 'index.html').write_text('qualified-dashboard')
|
||||||
|
(qualified / 'aiui/index.html').write_text('qualified-aiui')
|
||||||
|
(qualified / 'aiui/BUILD-INFO').write_text('commit=fixture')
|
||||||
|
for label, path, success in [('qualified', qualified, True), ('missing', base / 'absent', False), ('partial', base / 'partial', False)]:
|
||||||
|
out = base / 'outputs' / label / 'installer'
|
||||||
|
(out / 'web-ui').mkdir(parents=True)
|
||||||
|
if label == 'partial':
|
||||||
|
path.mkdir(exist_ok=True)
|
||||||
|
(path / 'index.html').write_text('incomplete')
|
||||||
|
result = subprocess.run(['bash', '-c', program], env=os.environ | {
|
||||||
|
'ARCHIPELAGO_WEB_UI': str(path), 'ARCH_DIR': str(out),
|
||||||
|
'BUILD_FROM_SOURCE': '0', 'DEV_SERVER': 'localhost', 'SCRIPT_DIR': str(base),
|
||||||
|
}, capture_output=True, text=True)
|
||||||
|
assert (result.returncode == 0) == success, (label, result.stdout, result.stderr)
|
||||||
|
if success:
|
||||||
|
assert (out / 'web-ui/index.html').read_text() == 'qualified-dashboard'
|
||||||
|
assert (out / 'web-ui/aiui/index.html').read_text() == 'qualified-aiui'
|
||||||
|
assert result.stdout.strip().splitlines()[-1] == str(qualified / 'aiui')
|
||||||
|
assert not (out / 'web-ui/archipelago-runtime').exists()
|
||||||
|
else:
|
||||||
|
assert not list((out / 'web-ui').iterdir()), 'invalid payload silently fell back to a live node'
|
||||||
|
print('PASS ISO payload selection:', label)
|
||||||
@@ -72,6 +72,7 @@ summary() {
|
|||||||
stage "git-diff-check" git diff --check
|
stage "git-diff-check" git diff --check
|
||||||
stage "mirror-gate-regression" python3 scripts/tests/test_git_mirrors.py
|
stage "mirror-gate-regression" python3 scripts/tests/test_git_mirrors.py
|
||||||
stage "iso-boot-runner-regression" python3 scripts/tests/test_iso_qemu_runner.py
|
stage "iso-boot-runner-regression" python3 scripts/tests/test_iso_qemu_runner.py
|
||||||
|
stage "iso-qualified-web-ui" python3 tests/regression/iso-qualified-web-ui.py
|
||||||
stage "demo-rpc-parity" timeout 120 node neode-ui/scripts/mock-rpc-parity.mjs
|
stage "demo-rpc-parity" timeout 120 node neode-ui/scripts/mock-rpc-parity.mjs
|
||||||
stage "demo-resumable-uploads" timeout 120 node --test neode-ui/scripts/demo-upload-test.mjs
|
stage "demo-resumable-uploads" timeout 120 node --test neode-ui/scripts/demo-upload-test.mjs
|
||||||
stage "companion-signature-regression" python3 scripts/tests/test_companion_apk_verification.py
|
stage "companion-signature-regression" python3 scripts/tests/test_companion_apk_verification.py
|
||||||
|
|||||||
Reference in New Issue
Block a user