Files
archy/scripts/tests/qualify_runtime_service.py

83 lines
4.8 KiB
Python

#!/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)