#!/usr/bin/env python3 """Build an isolated EROFS boot fixture using the exported s6 graph unchanged.""" import io from pathlib import Path import subprocess import sys import tarfile project = Path(__file__).resolve().parents[1] if len(sys.argv) != 2: sys.exit('Usage: tools/make-stage0-vm EMPTY_WORK_DIRECTORY') work = Path(sys.argv[1]).resolve(strict=True) if not work.is_dir() or any(work.iterdir()): sys.exit('ERROR: expected an existing empty work directory') stage2 = 'etc/s6-linux-init/current/scripts/rc.init' wrapper = (f'#!/bin/bash\nset -euo pipefail\n/{stage2}.fds-base "$@"\n' 'export FDS_TEST_ROOT_TYPE=erofs\n' '/usr/libexec/fds/m4-guest\n' 'exec /usr/libexec/fds/m2-guest\n').encode() found = False with tarfile.open(project/'out/rootfs-cli.tar') as source, tarfile.open(work/'test-rootfs.tar', 'w', format=tarfile.PAX_FORMAT) as output: for member in source: if member.name == stage2: member.name += '.fds-base' found = True output.addfile(member, source.extractfile(member) if member.isfile() else None) if not found: sys.exit('ERROR: native stage-2 script missing') hook = tarfile.TarInfo(stage2) hook.mode = 0o755 hook.size = len(wrapper) output.addfile(hook, io.BytesIO(wrapper)) def root_owned(info): info.uid = info.gid = 0 info.uname = info.gname = '' return info for name in ('m2-guest', 'm4-guest'): output.add(project/'tests/integration'/name, arcname='usr/libexec/fds/'+name, filter=root_owned) (work/'system').mkdir() subprocess.run([str(project/'image/build-system-cartridge'), '--rootfs', str(work/'test-rootfs.tar'), '--output-directory', str(work/'system')], check=True) print(f'PASS: stage0 VM fixture created at {work}')