#!/usr/bin/env python3 """Disposable regression for the ISO rootfs archive's traversable root.""" from pathlib import Path import os import subprocess import tempfile import unittest BUILDER = Path(__file__).resolve().parents[2] / "image-recipe/_archived/build-auto-installer-iso.sh" def archive_root(root: Path, archive: Path) -> None: subprocess.run( ["tar", "--numeric-owner", "-cf", str(archive), "-C", str(root), "."], check=True, ) def root_mode(archive: Path) -> str: listing = subprocess.run( ["tar", "-tvf", str(archive), "."], check=True, capture_output=True, text=True, ).stdout return listing.splitlines()[0].split()[0] def production_guard(source: str) -> str: start = source.index('if [ "$(tar --occurrence=1 -tvf "$ROOTFS_TAR" . | awk') end = source.index("\nfi", start) + len("\nfi") return source[start:end] class IsoRootModeTest(unittest.TestCase): def test_old_archive_is_rejected_and_corrected_archive_passes(self) -> None: source = BUILDER.read_text() guard = production_guard(source) with tempfile.TemporaryDirectory() as scratch: root = Path(scratch) / "root" root.mkdir(mode=0o700) archive = Path(scratch) / "rootfs.tar" archive_root(root, archive) self.assertEqual(root_mode(archive), "drwx------") invalid = subprocess.run( ["bash", "-eu", "-c", guard], env={**os.environ, "ROOTFS_TAR": str(archive)}, capture_output=True, text=True, ) self.assertNotEqual(invalid.returncode, 0) self.assertIn("must be mode 0755", invalid.stderr) root.chmod(0o755) archive_root(root, archive) self.assertEqual(root_mode(archive), "drwxr-xr-x") valid = subprocess.run( ["bash", "-eu", "-c", guard], env={**os.environ, "ROOTFS_TAR": str(archive)}, capture_output=True, text=True, ) self.assertEqual(valid.returncode, 0, valid.stderr) def test_guard_covers_cached_archive_and_installed_root(self) -> None: source = BUILDER.read_text() guard = production_guard(source) self.assertLess(source.index("Using cached root filesystem"), source.index(guard)) self.assertLess(source.index(guard), source.index('if [ -n "$UAT_KERNEL" ]', source.index(guard))) self.assertLess(source.index('run tar -xf "$ROOTFS_TAR" -C /mnt/target'), source.index('run chmod 755 /mnt/target')) self.assertLess(source.index('run chmod 755 /mnt/target'), source.index('step "Encrypting data partition"')) def test_builder_shell_syntax(self) -> None: subprocess.run(["bash", "-n", str(BUILDER)], check=True) if __name__ == "__main__": unittest.main()