#!/usr/bin/env python3 """Freeze normal-start source, package a non-libtest build, and record drift. Only repository source and explicitly selected distro ELF dependencies are copied. No runtime homes, container stores, credentials or host mounts are inputs. """ import argparse import hashlib import gzip import io import json import os from pathlib import Path import stat import struct import shutil import subprocess import tarfile def sha(path): return hashlib.file_digest(path.open('rb'), 'sha256').hexdigest() def record(path, value): path.write_text(json.dumps(value, indent=2, sort_keys=True) + '\n') def inventory(root): names = subprocess.check_output([ 'git', '-C', str(root), 'ls-files', '-z', '--cached', '--others', '--exclude-standard', '--', 'core', 'scripts', 'image-recipe/configs', 'tests', 'apps'], text=True).split('\0') return sorted(set(n for n in names if n and (root / n).is_file())) def freeze(root, out): out.mkdir(mode=0o700) destination = out / 'source' destination.mkdir() manifest = {} for name in inventory(root): source = root / name if source.is_symlink(): raise RuntimeError('source alias requires review: ' + name) data = source.read_bytes() target = destination / name target.parent.mkdir(parents=True, exist_ok=True) target.write_bytes(data) target.chmod(0o555 if source.stat().st_mode & 0o111 else 0o444) manifest[name] = hashlib.sha256(data).hexdigest() record(out / 'source-sha256.json', manifest) changed = [n for n in manifest if not (root / n).is_file() or sha(root / n) != manifest[n]] changed += sorted(set(inventory(root)) - set(manifest)) record(out / 'freeze-check.json', {'changed_during_copy': changed}) if changed: raise RuntimeError('source changed during freeze; retain attempt and retry') record(out / 'source-identity.json', { 'repository': str(root), 'head': subprocess.check_output(['git', '-C', str(root), 'rev-parse', 'HEAD'], text=True).strip(), 'branch': subprocess.check_output(['git', '-C', str(root), 'branch', '--show-current'], text=True).strip(), 'manifest_sha256': sha(out / 'source-sha256.json')}) (out / 'containers.conf').write_text('[containers]\nkeyring=false\n') record(out / 'accommodations.json', { 'outer_keyring': 'disabled for exhausted rootless kernel key quota; not keyring isolation qualification', 'outer_proc': 'unmask=ALL for nested rootless proc mounting', 'nested_runtime': 'historical fixture uses vfs, network none, no ping sysctl, seccomp unconfined', 'tmux': 'copied public distro ELF and loader; exact package manifest retained'}) with tarfile.open(out / 'source.tar', 'x') as archive: for name in manifest: archive.add(destination / name, arcname=name, recursive=False) with (out/'source.tar').open('rb') as source,(out/'source.tar.gz').open('xb') as destination: with gzip.GzipFile(filename='',fileobj=destination,mode='wb',mtime=0) as compressed: shutil.copyfileobj(source,compressed) def artifact(binary, out): # The runner builds --bin archipelago, never cargo test / a guarded entry. target = out / 'normal-elf' subprocess.run(['strip', '--strip-unneeded', '-o', str(target), str(binary)], check=True) def allocated(path): data=path.read_bytes() assert data[:6]==b'\x7fELF\x02\x01', 'reviewed ELF64 little-endian artifact required' header=struct.unpack_from('<16sHHIQQQIHHHHHH',data) section_offset,section_size,count,names_index=header[6],header[11],header[12],header[13] sections=[struct.unpack_from('