Add mmdebstrap support. Moved docs into docs
Some checks failed
Generate Treefiles / generate-treefiles (push) Failing after 2s
Some checks failed
Generate Treefiles / generate-treefiles (push) Failing after 2s
This commit is contained in:
parent
47468f0147
commit
6f91ab6ede
11 changed files with 565 additions and 187 deletions
|
|
@ -1,7 +1,20 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Alternative Debian Atomic Solution
|
||||
Uses debootstrap + ostree instead of apt-ostree to create Debian Atomic systems
|
||||
Uses debootstrap/mmdebstrap + ostree instead of apt-ostree to create Debian Atomic systems
|
||||
|
||||
Features:
|
||||
- Automatic detection of mmdebstrap (preferred) or debootstrap (fallback)
|
||||
- mmdebstrap is faster and more reliable than debootstrap
|
||||
- Automatic installation of mmdebstrap if not available
|
||||
- Support for all major Debian desktop environments
|
||||
- OSTree integration for atomic system management
|
||||
|
||||
Usage:
|
||||
python3 create-debian-atomic.py <variant> [work_dir] [options]
|
||||
|
||||
Variants: minimal, gnome, plasma, cosmic, sway, budgie
|
||||
Options: --use-debootstrap, --help, -h
|
||||
"""
|
||||
|
||||
import os
|
||||
|
|
@ -15,12 +28,58 @@ from pathlib import Path
|
|||
from typing import List, Dict, Any
|
||||
|
||||
class DebianAtomicBuilder:
|
||||
"""Build Debian Atomic systems using debootstrap + ostree"""
|
||||
"""Build Debian Atomic systems using debootstrap/mmdebstrap + ostree"""
|
||||
|
||||
def __init__(self, work_dir: str = None):
|
||||
def __init__(self, work_dir: str = None, use_mmdebstrap: bool = True):
|
||||
self.work_dir = Path(work_dir) if work_dir else Path(tempfile.mkdtemp(prefix="debian-atomic-"))
|
||||
self.repo_dir = self.work_dir / "repo"
|
||||
self.rootfs_dir = self.work_dir / "rootfs"
|
||||
self.use_mmdebstrap = use_mmdebstrap
|
||||
|
||||
# Check which bootstrap tool is available
|
||||
self.bootstrap_tool = self._detect_bootstrap_tool()
|
||||
|
||||
def _detect_bootstrap_tool(self) -> str:
|
||||
"""Detect which bootstrap tool is available and preferred"""
|
||||
if self.use_mmdebstrap and self._check_tool_available("mmdebstrap"):
|
||||
print("Using mmdebstrap (faster and more reliable)")
|
||||
return "mmdebstrap"
|
||||
elif self._check_tool_available("debootstrap"):
|
||||
print("Using debootstrap (fallback option)")
|
||||
return "debootstrap"
|
||||
else:
|
||||
print("Warning: No bootstrap tool found, attempting to install mmdebstrap")
|
||||
if self._install_mmdebstrap():
|
||||
return "mmdebstrap"
|
||||
else:
|
||||
raise RuntimeError("No bootstrap tool available and could not install mmdebstrap")
|
||||
|
||||
def _check_tool_available(self, tool: str) -> bool:
|
||||
"""Check if a tool is available in PATH"""
|
||||
try:
|
||||
subprocess.run([tool, "--version"], capture_output=True, check=True)
|
||||
return True
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
return False
|
||||
|
||||
def _install_mmdebstrap(self) -> bool:
|
||||
"""Attempt to install mmdebstrap if not available"""
|
||||
try:
|
||||
print("Attempting to install mmdebstrap...")
|
||||
# Try different package managers
|
||||
install_cmds = [
|
||||
["apt-get", "update", "-y"],
|
||||
["apt-get", "install", "-y", "mmdebstrap"]
|
||||
]
|
||||
|
||||
for cmd in install_cmds:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
print(f"Successfully ran: {' '.join(cmd)}")
|
||||
|
||||
return self._check_tool_available("mmdebstrap")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Failed to install mmdebstrap: {e}")
|
||||
return False
|
||||
|
||||
def create_ostree_repo(self) -> bool:
|
||||
"""Create and initialize OSTree repository"""
|
||||
|
|
@ -46,19 +105,36 @@ class DebianAtomicBuilder:
|
|||
return False
|
||||
|
||||
def create_rootfs(self, variant: str = "minimal") -> bool:
|
||||
"""Create rootfs using debootstrap"""
|
||||
"""Create rootfs using detected bootstrap tool"""
|
||||
try:
|
||||
print(f"Creating rootfs for variant: {variant}")
|
||||
print(f"Creating rootfs for variant: {variant} using {self.bootstrap_tool}")
|
||||
self.rootfs_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Get package list based on variant
|
||||
packages = self.get_packages_for_variant(variant)
|
||||
|
||||
# Create minimal rootfs with debootstrap
|
||||
cmd = [
|
||||
"debootstrap", "--variant=minbase", "--include=" + ",".join(packages),
|
||||
"trixie", str(self.rootfs_dir), "http://deb.debian.org/debian"
|
||||
]
|
||||
if self.bootstrap_tool == "mmdebstrap":
|
||||
# Use mmdebstrap (faster and more reliable)
|
||||
cmd = [
|
||||
"mmdebstrap",
|
||||
"--variant=minbase",
|
||||
"--include=" + ",".join(packages),
|
||||
"--aptopt=Acquire::Check-Valid-Until=false", # Handle expired Release files
|
||||
"--aptopt=Acquire::Check-Date=false", # Disable date checking
|
||||
"trixie",
|
||||
str(self.rootfs_dir),
|
||||
"http://deb.debian.org/debian"
|
||||
]
|
||||
else:
|
||||
# Use debootstrap (fallback)
|
||||
cmd = [
|
||||
"debootstrap",
|
||||
"--variant=minbase",
|
||||
"--include=" + ",".join(packages),
|
||||
"trixie",
|
||||
str(self.rootfs_dir),
|
||||
"http://deb.debian.org/debian"
|
||||
]
|
||||
|
||||
print(f"Running: {' '.join(cmd)}")
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
|
|
@ -236,6 +312,24 @@ class DebianAtomicBuilder:
|
|||
"""List all supported variants"""
|
||||
return ["minimal", "gnome", "plasma", "cosmic", "sway", "budgie"]
|
||||
|
||||
def get_bootstrap_info(self) -> Dict[str, Any]:
|
||||
"""Get information about the bootstrap tool being used"""
|
||||
return {
|
||||
"tool": self.bootstrap_tool,
|
||||
"preferred": self.use_mmdebstrap,
|
||||
"available": self._check_tool_available(self.bootstrap_tool),
|
||||
"version": self._get_tool_version()
|
||||
}
|
||||
|
||||
def _get_tool_version(self) -> str:
|
||||
"""Get version of the bootstrap tool"""
|
||||
try:
|
||||
result = subprocess.run([self.bootstrap_tool, "--version"],
|
||||
capture_output=True, text=True, check=True)
|
||||
return result.stdout.strip().split('\n')[0]
|
||||
except:
|
||||
return "Unknown"
|
||||
|
||||
def cleanup(self):
|
||||
"""Clean up temporary files"""
|
||||
try:
|
||||
|
|
@ -247,15 +341,37 @@ class DebianAtomicBuilder:
|
|||
|
||||
def main():
|
||||
"""Main function"""
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python3 create-debian-atomic.py <variant> [work_dir]")
|
||||
print("Variants:", ", ".join(DebianAtomicBuilder().list_variants()))
|
||||
sys.exit(1)
|
||||
if len(sys.argv) < 2 or "--help" in sys.argv or "-h" in sys.argv:
|
||||
print("Alternative Debian Atomic Builder")
|
||||
print("=================================")
|
||||
print("Usage: python3 create-debian-atomic.py <variant> [work_dir] [options]")
|
||||
print("\nVariants:")
|
||||
for variant in DebianAtomicBuilder().list_variants():
|
||||
print(f" {variant}")
|
||||
print("\nOptions:")
|
||||
print(" --use-debootstrap Force use of debootstrap instead of mmdebstrap")
|
||||
print(" --help, -h Show this help message")
|
||||
print("\nExamples:")
|
||||
print(" python3 create-debian-atomic.py minimal")
|
||||
print(" python3 create-debian-atomic.py gnome /tmp/my-work-dir")
|
||||
print(" python3 create-debian-atomic.py plasma --use-debootstrap")
|
||||
sys.exit(0)
|
||||
|
||||
variant = sys.argv[1]
|
||||
work_dir = sys.argv[2] if len(sys.argv) > 2 else None
|
||||
work_dir = None
|
||||
use_mmdebstrap = True
|
||||
|
||||
builder = DebianAtomicBuilder()
|
||||
# Parse arguments
|
||||
for i, arg in enumerate(sys.argv[2:], 2):
|
||||
if arg == "--use-debootstrap":
|
||||
use_mmdebstrap = False
|
||||
elif arg in ["--help", "-h"]:
|
||||
continue # Already handled above
|
||||
elif not arg.startswith("--"):
|
||||
work_dir = arg
|
||||
break
|
||||
|
||||
builder = DebianAtomicBuilder(work_dir=work_dir, use_mmdebstrap=use_mmdebstrap)
|
||||
supported_variants = builder.list_variants()
|
||||
|
||||
if variant not in supported_variants:
|
||||
|
|
@ -264,6 +380,13 @@ def main():
|
|||
sys.exit(1)
|
||||
|
||||
try:
|
||||
# Show bootstrap tool information
|
||||
bootstrap_info = builder.get_bootstrap_info()
|
||||
print(f"\n🔧 Bootstrap Tool Information:")
|
||||
print(f" Tool: {bootstrap_info['tool']}")
|
||||
print(f" Version: {bootstrap_info['version']}")
|
||||
print(f" Preferred: {'mmdebstrap' if bootstrap_info['preferred'] else 'debootstrap'}")
|
||||
|
||||
success = builder.build_variant(variant)
|
||||
if success:
|
||||
print(f"\n✅ Successfully built Debian Atomic {variant} variant")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue