Unmount with plain umount and a lazy fallback, cover the chroot API #1

Merged
marcos-mendez merged 4 commits from fix/umount-in-lxc into master 2026-09-26 05:49:25 -03:00
marcos-mendez commented 2026-09-26 05:46:06 -03:00 (Migrated from github.com)

Problem: inside an LXC container (TKLDev as a Proxmox CT) every fab-chroot raised MountError at the end of the build and left proc and dev/pts mounted under build/root.patched; the next stage ran mksquashfs over the tree, descended into the host's /proc and hung indefinitely.

Diagnosis: MagicMounts.umount() ran umount --force, which the container kernel refuses for proc ("block devices are not permitted on filesystem"). The flag only matters for unreachable network filesystems, which these never are.

Fix: plain umount, retry with --lazy when that fails (busy mount), MountError only when both fail. The tests gained the mount loop (--type and --bind profiles, already-mounted skips, both MountError paths), the devpts before dev ordering on umount, del, both repr methods, Chroot.system and Chroot.run argv construction, the environ defaults and the log level read from the environment. Everything runs with subprocess.run patched: no root, no real mounts. The 95 percent coverage threshold and the test commands are committed (pyproject.toml, README.md).

Tests: 40 pytest, 100 percent lines and branches with coverage run --branch --source=chroot, coverage report --fail-under=95 passes. Behaviour checked in an LXC container (was: MountError and 2 mounts left; now clean, 0 left) and on a KVM virtual machine (unchanged: clean).

Serves BRIEF section 4 (the build host runs as an LXC container) and section 10 (system containers only).

Problem: inside an LXC container (TKLDev as a Proxmox CT) every fab-chroot raised MountError at the end of the build and left proc and dev/pts mounted under build/root.patched; the next stage ran mksquashfs over the tree, descended into the host's /proc and hung indefinitely. Diagnosis: MagicMounts.umount() ran `umount --force`, which the container kernel refuses for proc ("block devices are not permitted on filesystem"). The flag only matters for unreachable network filesystems, which these never are. Fix: plain `umount`, retry with `--lazy` when that fails (busy mount), MountError only when both fail. The tests gained the mount loop (--type and --bind profiles, already-mounted skips, both MountError paths), the devpts before dev ordering on umount, __del__, both __repr__ methods, Chroot.system and Chroot.run argv construction, the environ defaults and the log level read from the environment. Everything runs with subprocess.run patched: no root, no real mounts. The 95 percent coverage threshold and the test commands are committed (pyproject.toml, README.md). Tests: 40 pytest, 100 percent lines and branches with `coverage run --branch --source=chroot`, `coverage report --fail-under=95` passes. Behaviour checked in an LXC container (was: MountError and 2 mounts left; now clean, 0 left) and on a KVM virtual machine (unchanged: clean). Serves BRIEF section 4 (the build host runs as an LXC container) and section 10 (system containers only).
Sign in to join this conversation.
No description provided.