#!/usr/bin/env python3 """Actual-archive packaging/import fixture; NOT full candidate or live D09 UAT. Run under release-heavy.lock and a CPU2/8G scope. Only a fresh explicit VFS root/runroot/config/network/tmp are used. No containers are started. """ import argparse import importlib.util import json import os from pathlib import Path import shutil import subprocess import sys SCRIPTS = Path(__file__).resolve().parents[1] sys.path.insert(0, str(SCRIPTS)) import uat_oci def load(name): spec = importlib.util.spec_from_file_location(name, SCRIPTS / (name + '.py')) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--evidence', type=Path, required=True) parser.add_argument('--output', type=Path, required=True) args = parser.parse_args() out = args.output.resolve() if os.geteuid() == 0 or not out.is_relative_to(Path('/tmp/opencode')): parser.error('non-root fixture under /tmp/opencode required') out.mkdir(exist_ok=False) builder, importer = load('build-iso-uat'), load('import-uat-oci') staged = out / 'staged' staged.mkdir() for source, target in [('lnd-tor-20261101-amd64.oci.tar', 'lnd_tor_oci'), ('identity.json', 'lnd_tor_identity'), ('final-source.json', 'lnd_tor_sources')]: shutil.copyfile(args.evidence / source, staged / target) companion = builder.companion_identity(SCRIPTS.parent) # Null source identity explicitly marks this as dirty-tree packaging evidence, # never a qualified candidate receipt or deployable full candidate bundle. bundle = builder.stage_oci(SCRIPTS.parent, staged, {'source_commit': None, 'companion': companion}) proof = uat_oci.bundle(bundle)['oci'] payload = out / 'payload/archipelago/unsigned-uat-oci' shutil.copytree(bundle, payload) count = 0 def command(argv, env=None): nonlocal count count += 1 prefix = out / f'command-{count:02}' prefix.with_suffix('.json').write_text(json.dumps([str(x) for x in argv]) + '\n') process = subprocess.run([str(x) for x in argv], capture_output=True, env=env, timeout=300) prefix.with_suffix('.stdout').write_bytes(process.stdout) prefix.with_suffix('.stderr').write_bytes(process.stderr) if process.returncode: raise RuntimeError(f'fixture command failed ({process.returncode}); see {prefix}') return process.stdout.decode() iso = out / 'NONBOOTABLE-OCI-PACKAGING-FIXTURE.iso' command(['xorriso', '-as', 'mkisofs', '-R', '-o', iso, out / 'payload']) command(['xorriso', '-osirrox', 'on', '-indev', iso, '-extract', '/', out / 'extracted']) extracted = out / 'extracted/archipelago/unsigned-uat-oci' uat_oci.bundle(extracted, uat_oci.sha(bundle / 'BUNDLE.json')) staged_result = importer.stage(extracted, out / 'installed-fixture') for name in ('storage', 'run', 'network', 'tmp', 'home', 'xdg-data', 'xdg-config'): (out / name).mkdir() conf = out / 'storage.conf' storage = {'storage': {'driver': 'vfs', 'graphroot': str(out / 'storage'), 'runroot': str(out / 'run')}} conf.write_text('[storage]\ndriver="vfs"\ngraphroot=' + json.dumps(str(out / 'storage')) + '\nrunroot=' + json.dumps(str(out / 'run')) + '\n') containers = out / 'containers.conf' containers.write_text('[containers]\nkeyring=false\n[engine]\nevents_logger="file"\n') env = dict(os.environ, HOME=str(out / 'home'), XDG_DATA_HOME=str(out / 'xdg-data'), XDG_CONFIG_HOME=str(out / 'xdg-config'), CONTAINERS_STORAGE_CONF=str(conf), CONTAINERS_CONF=str(containers), TMPDIR=str(out / 'tmp')) for key in ('CONTAINER_HOST', 'CONTAINER_CONNECTION', 'CONTAINERS_CONF_OVERRIDE'): env.pop(key, None) prefix = ['/usr/bin/podman', '--root', out / 'storage', '--runroot', out / 'run', '--storage-driver', 'vfs', '--network-config-dir', out / 'network', '--tmpdir', out / 'tmp'] def podman(argv): return command(prefix + argv, env) info = json.loads(podman(['info', '--format', 'json'])) importer.storage_check(info, {'graphroot': str(out / 'storage'), 'runtime_dir': str(out)}, storage, conf) if json.loads(podman(['images', '--format', 'json'])) or json.loads(podman(['ps', '-a', '--format', 'json'])): raise ValueError('fixture store was not empty') imported = importer.import_image(podman, extracted / 'lnd-tor.oci.tar', proof) after = json.loads(podman(['info', '--format', 'json'])) importer.storage_check(after, {'graphroot': str(out / 'storage'), 'runtime_dir': str(out)}, storage, conf) if json.loads(podman(['ps', '-a', '--format', 'json'])): raise ValueError('unexpected fixture container') result = dict(status='actual-archive-packaging-isolated-import-passed', source_qualified=False, full_candidate_built=False, live_d09_import_tested=False, companion=companion, archive=proof, imported=imported, staged=staged_result, fixture_iso_sha256=uat_oci.sha(iso), bundle_sha256=uat_oci.sha(bundle / 'BUNDLE.json'), store=after['store'], runtime_uid=os.geteuid(), containers_created=0) (out / 'result.json').write_text(json.dumps(result, sort_keys=True, indent=2) + '\n') print(json.dumps(result, sort_keys=True)) if __name__ == '__main__': main()