2026-02-05 18:05:06 -05:00

82 lines
2.4 KiB
Python

"""Chroot environment preparation."""
import shutil
from pathlib import Path
from .utils import info, success, warn, run, is_mounted
def prepare_chroot(mount_root: Path | None = None) -> None:
"""Prepare chroot environment with bind mounts."""
if mount_root is None:
mount_root = Path("/mnt/gentoo")
info("=== Preparing Chroot Environment ===")
# Check if already prepared (idempotency)
if is_mounted(mount_root / "proc"):
info("Chroot already prepared (skipping)")
return
# Copy DNS configuration
info("Copying DNS configuration...")
resolv_src = Path("/etc/resolv.conf")
resolv_dst = mount_root / "etc/resolv.conf"
if resolv_src.exists():
# Use --dereference to copy the actual file if it's a symlink
shutil.copy2(resolv_src.resolve(), resolv_dst)
success("Copied resolv.conf")
# Bind mount pseudo-filesystems
mounts = [
("proc", "/proc", ["--rbind"]),
("sys", "/sys", ["--rbind"]),
("dev", "/dev", ["--rbind"]),
("run", "/run", ["--rbind"]),
]
for name, source, flags in mounts:
target = mount_root / name.lstrip("/")
target.mkdir(parents=True, exist_ok=True)
run("mount", *flags, source, str(target))
run("mount", "--make-rslave", str(target))
success(f"Mounted {source}")
print()
success("=== Chroot environment ready ===")
print()
info("To enter chroot:")
print(f" chroot {mount_root} /bin/bash")
print(" source /etc/profile")
print(" export PS1=\"(chroot) $PS1\"")
def enter_chroot(mount_root: Path | None = None) -> None:
"""Enter the chroot environment."""
if mount_root is None:
mount_root = Path("/mnt/gentoo")
import os
os.execvp("chroot", ["chroot", str(mount_root), "/bin/bash", "--login"])
def cleanup_chroot(mount_root: Path | None = None) -> None:
"""Unmount chroot bind mounts."""
if mount_root is None:
mount_root = Path("/mnt/gentoo")
info("Cleaning up chroot mounts...")
# Unmount in reverse order
for name in ["run", "dev", "sys", "proc"]:
target = mount_root / name
result = run("umount", "-R", str(target), check=False)
if not result.ok:
# Try lazy unmount as fallback
warn(f"Normal unmount failed for {target}, trying lazy unmount...")
run("umount", "-Rl", str(target), check=False)
success("Chroot mounts cleaned up.")