feat: add chroot container initialization and entry
This commit is contained in:
parent
d0b9191c42
commit
74d8372386
@ -4,6 +4,14 @@
|
||||
|
||||
|
||||
|
||||
|
||||
## Version 0.4.0 - 2025-11-05
|
||||
|
||||
Testing has been added to verify the HTTP functionality. This improves the reliability and quality of the HTTP features.
|
||||
|
||||
**Changes:** 1 files, 8 lines
|
||||
**Languages:** Markdown (8 lines)
|
||||
|
||||
## Version 0.3.0 - 2025-11-05
|
||||
|
||||
We've added tests to verify the HTTP functionality. This improves the reliability of the HTTP implementation for both users and developers.
|
||||
|
||||
110
chroot.py
Normal file
110
chroot.py
Normal file
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
CHROOT_DIRECTORY = "/srv/chroot/ubuntu"
|
||||
UBUNTU_RELEASE = "noble"
|
||||
UBUNTU_MIRROR = "http://archive.ubuntu.com/ubuntu"
|
||||
|
||||
def execute_command(command, check=True, shell=False):
|
||||
if shell:
|
||||
return subprocess.run(command, shell=True, check=check)
|
||||
return subprocess.run(command, check=check)
|
||||
|
||||
def initialize_chroot():
|
||||
chroot_path = Path(CHROOT_DIRECTORY)
|
||||
if chroot_path.exists() and list(chroot_path.iterdir()):
|
||||
print(f"Chroot directory {CHROOT_DIRECTORY} already exists and is not empty.")
|
||||
response = input("Reinitialize? This will delete everything. (yes/no): ")
|
||||
if response.lower() != "yes":
|
||||
print("Aborting.")
|
||||
sys.exit(0)
|
||||
shutil.rmtree(CHROOT_DIRECTORY)
|
||||
|
||||
if not shutil.which("debootstrap"):
|
||||
print("Installing debootstrap...")
|
||||
execute_command(["apt", "update"])
|
||||
execute_command(["apt", "install", "-y", "debootstrap"])
|
||||
|
||||
if not shutil.which("systemd-nspawn"):
|
||||
print("Installing systemd-container...")
|
||||
execute_command(["apt", "update"])
|
||||
execute_command(["apt", "install", "-y", "systemd-container"])
|
||||
|
||||
print(f"Creating chroot directory: {CHROOT_DIRECTORY}")
|
||||
chroot_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"Running debootstrap for {UBUNTU_RELEASE}...")
|
||||
execute_command([
|
||||
"debootstrap",
|
||||
"--variant=minbase",
|
||||
UBUNTU_RELEASE,
|
||||
CHROOT_DIRECTORY,
|
||||
UBUNTU_MIRROR
|
||||
])
|
||||
|
||||
print("Configuring APT sources...")
|
||||
sources_content = f"""deb {UBUNTU_MIRROR} {UBUNTU_RELEASE} main restricted universe multiverse
|
||||
deb {UBUNTU_MIRROR} {UBUNTU_RELEASE}-updates main restricted universe multiverse
|
||||
deb http://security.ubuntu.com/ubuntu {UBUNTU_RELEASE}-security main restricted universe multiverse
|
||||
"""
|
||||
(chroot_path / "etc/apt/sources.list").write_text(sources_content)
|
||||
|
||||
print("Setting hostname...")
|
||||
(chroot_path / "etc/hostname").write_text("ubuntu-container\n")
|
||||
|
||||
print("Updating APT inside container...")
|
||||
execute_command([
|
||||
"systemd-nspawn",
|
||||
"-D", CHROOT_DIRECTORY,
|
||||
"--pipe",
|
||||
"bash", "-c",
|
||||
"export DEBIAN_FRONTEND=noninteractive && apt update"
|
||||
])
|
||||
|
||||
print(f"\nContainer initialized successfully at {CHROOT_DIRECTORY}")
|
||||
print(f"To enter: sudo python3 {sys.argv[0]}")
|
||||
|
||||
def enter_chroot():
|
||||
chroot_path = Path(CHROOT_DIRECTORY)
|
||||
if not chroot_path.exists() or not list(chroot_path.iterdir()):
|
||||
print(f"Container not initialized. Run: sudo python3 {sys.argv[0]} init")
|
||||
sys.exit(1)
|
||||
|
||||
if not shutil.which("systemd-nspawn"):
|
||||
print("systemd-nspawn not found. Installing systemd-container...")
|
||||
execute_command(["apt", "update"])
|
||||
execute_command(["apt", "install", "-y", "systemd-container"])
|
||||
|
||||
print(f"Entering container at {CHROOT_DIRECTORY}...")
|
||||
os.execvp("/usr/bin/systemd-nspawn", [
|
||||
"systemd-nspawn",
|
||||
"-D", CHROOT_DIRECTORY,
|
||||
"--resolv-conf=bind-host",
|
||||
"--private-users=pick",
|
||||
"--drop-capability=CAP_SYS_MODULE,CAP_SYS_TIME,CAP_SYS_BOOT",
|
||||
"--setenv=DEBIAN_FRONTEND=noninteractive"
|
||||
])
|
||||
|
||||
def main():
|
||||
if os.geteuid() != 0:
|
||||
print("This script must be run as root (use sudo)")
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
enter_chroot()
|
||||
elif len(sys.argv) > 1:
|
||||
match sys.argv[1]:
|
||||
case "init":
|
||||
initialize_chroot()
|
||||
case _:
|
||||
print(f"Unknown command: {sys.argv[1]}")
|
||||
print(f"Usage: {sys.argv[0]} [init]")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user