mirror of
https://github.com/okxlin/release-factory.git
synced 2026-09-22 00:02:16 +00:00
Reject unsafe workstation credentials, fix native ARM64 Java, and remove duplicate extensions, caches and temporary tool layers. Pin OpenCode's baseline and Gemini's source/runtime inputs; refresh maintained browser and OS packages; fix Nginx and vendored ZIP vulnerabilities. Verify real login, default plugins, browser/CDP persistence and isolated OpenClaw sandbox operations. Build each platform once and bind release publication to the tested config and manifest digests. Keep service-specific vulnerability gates and refresh DSH APT stages during PR verification. Validation: all 13 PR verification jobs passed, including native amd64/arm64 workstations and DSH variants, plus both browser variants and OpenClaw on amd64. Publication jobs were skipped for PR verification.
102 lines
5.5 KiB
Python
102 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify the default plugin, authenticated serve mode, persistence and userland scan."""
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import time
|
|
import uuid
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def docker(*args, check=True, timeout=180):
|
|
result = subprocess.run(["docker", *args], capture_output=True, text=True, timeout=timeout)
|
|
if check and result.returncode:
|
|
raise RuntimeError(result.stdout + result.stderr)
|
|
return result
|
|
|
|
|
|
def main(image, report):
|
|
owner = "rf-opencode-" + uuid.uuid4().hex[:12]
|
|
volume = owner + "-home"
|
|
containers = []
|
|
password = "ci-" + uuid.uuid4().hex
|
|
docker("volume", "create", "--label", f"io.release-factory.test={owner}", volume)
|
|
try:
|
|
for phase in ("first", "persisted"):
|
|
name = owner + "-" + phase
|
|
containers.append(name)
|
|
docker("run", "-d", "--name", name, "--label", f"io.release-factory.test={owner}",
|
|
"-e", "OPENCODE_RUNTIME_MODE=serve", "-e", "SERVE_HOST=127.0.0.1",
|
|
"-e", "OPENCODE_SERVER_PASSWORD=" + password, "-v", volume + ":/home/opencode",
|
|
image, "runtime")
|
|
for _ in range(120):
|
|
health = docker("exec", name, "curl", "-fsS", "--max-time", "2", "-u", "opencode:" + password,
|
|
"http://127.0.0.1:4096/global/health", check=False)
|
|
if health.returncode == 0:
|
|
assert json.loads(health.stdout)["healthy"] is True
|
|
break
|
|
state = json.loads(docker("inspect", name).stdout)[0]["State"]
|
|
if not state["Running"]:
|
|
raise RuntimeError("OpenCode exited during bootstrap")
|
|
time.sleep(2)
|
|
else:
|
|
raise RuntimeError("OpenCode serve did not become healthy")
|
|
denied = docker("exec", name, "curl", "-s", "-o", "/dev/null", "-w", "%{http_code}",
|
|
"http://127.0.0.1:4096/config").stdout
|
|
assert denied == "401", "OpenCode accepted an unauthenticated config request"
|
|
config = json.loads(docker("exec", name, "curl", "-fsS", "--max-time", "60", "-u", "opencode:" + password,
|
|
"http://127.0.0.1:4096/config").stdout)
|
|
expected = json.loads(docker("exec", name, "cat", "/opt/opencode/package.json").stdout)
|
|
assert expected["config"]["dcpPackage"] in config["plugin"], "default DCP plugin not loaded"
|
|
if phase == "first":
|
|
assert docker("exec", name, "test", "-e", "/usr/bin/node", check=False).returncode != 0, "unexpected second distro Node runtime"
|
|
docker("exec", name, "tsc", "--version")
|
|
print(docker("exec", name, "/app/scripts/smoke-test.sh", timeout=600).stdout, end="", flush=True)
|
|
docker("exec", name, "sh", "-c", 'printf preserved > "$HOME/.config/smoke-marker"')
|
|
with tempfile.TemporaryDirectory(prefix=owner + "-scan-") as directory:
|
|
snapshot = Path(directory).resolve()
|
|
for path in (".config/opencode", ".cache/opencode", ".local/share/opencode"):
|
|
source = "/home/opencode/" + path
|
|
if docker("exec", name, "test", "-d", source, check=False).returncode:
|
|
continue
|
|
size = docker("exec", name, "du", "-sb", source).stdout.strip()
|
|
target = snapshot / "home/opencode" / path
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
print(f"Userland snapshot: {name}:{source} -> {target}; {size}", flush=True)
|
|
docker("cp", name + ":" + source, str(target))
|
|
packages = list(snapshot.rglob("package.json"))
|
|
assert any(json.loads(path.read_text()).get("name") == "@tarquinen/opencode-dcp"
|
|
for path in packages), "DCP artifacts missing from userland snapshot"
|
|
subprocess.run(["bash", str(ROOT / "scripts/trivy-image-gate.sh"), "--filesystem", str(snapshot),
|
|
"--policy", str(ROOT / "opencode-workstation-builder/configs/trivy-policy.json"),
|
|
"--profile", "workstation", "--output", str(report)], check=True)
|
|
else:
|
|
assert docker("exec", name, "cat", "/home/opencode/.config/smoke-marker").stdout == "preserved"
|
|
print("PASS: default DCP, authenticated OpenCode serve and " + phase + " HOME", flush=True)
|
|
docker("stop", name)
|
|
except BaseException:
|
|
for name in containers:
|
|
logs = docker("logs", "--tail", "60", name, check=False)
|
|
print(logs.stdout + logs.stderr, file=sys.stderr)
|
|
raise
|
|
finally:
|
|
for name in containers:
|
|
label = docker("inspect", "--format", '{{index .Config.Labels "io.release-factory.test"}}', name, check=False)
|
|
if label.stdout.strip() == owner:
|
|
docker("rm", "-f", name)
|
|
label = docker("volume", "inspect", "--format", '{{index .Labels "io.release-factory.test"}}', volume, check=False)
|
|
if label.stdout.strip() == owner:
|
|
docker("volume", "rm", volume)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("image")
|
|
parser.add_argument("--userland-report", required=True, type=Path)
|
|
args = parser.parse_args()
|
|
main(args.image, args.userland_report.resolve())
|