#!/usr/bin/python3 """New private receipt per attempt; no compiler/native build or installed state.""" import argparse import hashlib import json import os from pathlib import Path import subprocess import shutil import time repo = Path(__file__).resolve().parents[2] base = Path('/home/archipelago/Reports/opencode-full-release-20261029') parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('label', help='unused alphanumeric receipt label') parser.add_argument('stop', nargs='?', default='revoke', choices=('revoke', 'stall')) parser.add_argument('--terminal-tests', type=Path, help='already rebuilt archipelago backend test binary; never builds here') args = parser.parse_args() assert args.label.isalnum(), 'supply an unused alphanumeric attempt label' stop_case = args.stop lane = base / ('c01-runtime-service-' + args.label) lane.mkdir(mode=0o700, exist_ok=False) source_paths = [repo / 'scripts' / name for name in ('runtime_owner.py', 'c01_runtime.py', 'c01_runtime_groups.py', 'c01_runtime_view.py')] source_paths += list((repo / 'scripts/tests').glob('*runtime*.py')) source_paths += list((repo / 'image-recipe/configs').glob('*runtime*')) frozen = [repo / 'scripts' / name for name in ('c01_supervisor.py', 'c01_children.py', 'c01_views.py', 'c01_nts.py', 'c01_recovery.py', 'c01_host_watch.py')] frozen += [repo / 'core/runtime-proxy.c'] frozen += [repo / 'core/archipelago/src/api/handler/terminal.rs', repo / 'tests/regression/c01-supervisor.py', repo / 'tests/regression/terminal-workspace-sandbox.py'] def hashes(paths): return {str(path.relative_to(repo)): hashlib.sha256(path.read_bytes()).hexdigest() for path in paths} before = hashes(source_paths) frozen_before = hashes(frozen) (lane / 'source.json').write_text(json.dumps(before, indent=2)) (lane / 'frozen.json').write_text(json.dumps(frozen_before, indent=2)) oci = base / 'indee-frontend-oci-r1/indeehub-frontend-56ad62d0535b-linux-amd64.oci.tar' assert oci.is_file() proxy_source = base / 'isolation-build-target/debug/build/archipelago-47fc6b7c7bb86b2b/out/archipelago-runtime-proxy' proxy = lane / 'archipelago-runtime-proxy' shutil.copyfile(proxy_source, proxy) proxy.chmod(0o755) (lane / 'proxy.json').write_text(json.dumps({'source': str(proxy_source), 'sha256': hashlib.sha256(proxy.read_bytes()).hexdigest(), 'rebuilt_here': False}, indent=2)) terminal_bind = '' if args.terminal_tests is not None: source = args.terminal_tests.resolve(strict=True) assert source.is_file() terminal = lane / 'runtime-terminal-tests' shutil.copyfile(source, terminal) terminal.chmod(0o755) (lane / 'terminal-tests.json').write_text(json.dumps({'source': str(source), 'sha256': hashlib.sha256(terminal.read_bytes()).hexdigest(), 'rebuilt_here': False}, indent=2)) terminal_bind = f' {terminal}:/opt/runtime-terminal-tests' unit = 'c01-runtime-fixture-' + args.label + '-' + str(os.getpid()) command = ['sudo', '-n', 'systemd-run', '--quiet', '--wait', '--pipe', '--collect', '--unit=' + unit, '-p', 'Delegate=yes', '-p', 'PrivateMounts=yes', '-p', 'PrivateNetwork=yes', '-p', 'ProtectSystem=strict', '-p', 'NoNewPrivileges=no', '-p', 'TemporaryFileSystem=/run /home /root /var/lib /tmp /var/tmp /opt', '-p', f'BindReadOnlyPaths={repo}:/opt/source {oci}:/run/public.oci.tar {proxy}:/opt/archipelago-runtime-proxy{terminal_bind}', '-p', 'CPUAffinity=2 3', '-p', 'AllowedCPUs=2-3', '-p', 'CPUQuota=200%', '-p', 'MemoryMax=2G', '-p', 'MemorySwapMax=0', '-p', 'TasksMax=512', '-p', 'RuntimeMaxSec=240', '-p', 'TimeoutStopSec=10', '--setenv=ARCHY_RUNTIME_FIXTURE=1', '--setenv=PYTHONDONTWRITEBYTECODE=1', '--setenv=ARCHY_RUNTIME_STOP=' + stop_case, '/usr/bin/python3', '-B', '/opt/source/scripts/tests/runtime_service_fixture.py'] (lane / 'command.json').write_text(json.dumps(command, indent=2)) start = time.monotonic() with (lane / 'stdout.log').open('wb') as out, (lane / 'stderr.log').open('wb') as err: try: result = subprocess.run(command, stdout=out, stderr=err, timeout=270) code = result.returncode except subprocess.TimeoutExpired: code = 124 subprocess.run(['sudo', '-n', 'systemctl', 'stop', unit], timeout=20, check=False) receipt = {'exit_code': code, 'seconds': time.monotonic() - start, 'source_unchanged': hashes(source_paths) == before, 'frozen_unchanged': hashes(frozen) == frozen_before, 'compiler_run': False, 'installed_acceptance': False, 'native_terminal_fixture_requested': args.terminal_tests is not None, 'system_manager_dropin_qualification': False} (lane / 'result.json').write_text(json.dumps(receipt, indent=2)) print(lane, json.dumps(receipt), flush=True) raise SystemExit(code)