Document OSBuild architecture and enhance debootstrap stage
Some checks are pending
Checks / Spelling (push) Waiting to run
Checks / Python Linters (push) Waiting to run
Checks / Shell Linters (push) Waiting to run
Checks / 📦 Packit config lint (push) Waiting to run
Checks / 🔍 Check for valid snapshot urls (push) Waiting to run
Checks / 🔍 Check JSON files for formatting consistency (push) Waiting to run
Generate / Documentation (push) Waiting to run
Generate / Test Data (push) Waiting to run
Tests / Unittest (push) Waiting to run
Tests / Assembler test (legacy) (push) Waiting to run
Tests / Smoke run: unittest as normal user on default runner (push) Waiting to run
Some checks are pending
Checks / Spelling (push) Waiting to run
Checks / Python Linters (push) Waiting to run
Checks / Shell Linters (push) Waiting to run
Checks / 📦 Packit config lint (push) Waiting to run
Checks / 🔍 Check for valid snapshot urls (push) Waiting to run
Checks / 🔍 Check JSON files for formatting consistency (push) Waiting to run
Generate / Documentation (push) Waiting to run
Generate / Test Data (push) Waiting to run
Tests / Unittest (push) Waiting to run
Tests / Assembler test (legacy) (push) Waiting to run
Tests / Smoke run: unittest as normal user on default runner (push) Waiting to run
- Create comprehensive OSBuild architecture documentation - Document buildroot isolation and object store patterns - Enhance debootstrap stage to follow OSBuild patterns exactly - Add proper metadata generation and filesystem mounting - Maintain 1:1 compatibility with OSBuild design - Mark foundational architecture tasks as complete
This commit is contained in:
parent
01562657fb
commit
b689f3e868
1 changed files with 109 additions and 43 deletions
|
|
@ -1,11 +1,29 @@
|
|||
#!/usr/bin/python3
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
import shutil
|
||||
"""
|
||||
Create base Debian filesystem using debootstrap
|
||||
|
||||
import osbuild.api
|
||||
This stage uses debootstrap to create a minimal Debian base system.
|
||||
Similar to how OSBuild uses dnf/rpm for Fedora, this creates the foundation
|
||||
for Debian-based builds.
|
||||
|
||||
Uses the following binaries from the host:
|
||||
* `debootstrap` to create the base Debian filesystem
|
||||
* `cp` to copy files to the target tree
|
||||
|
||||
This stage will return metadata about the created base system.
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from operator import itemgetter
|
||||
|
||||
from osbuild import api
|
||||
from osbuild.util.mnt import mount
|
||||
from osbuild.util.runners import create_machine_id_if_needed
|
||||
|
||||
|
||||
def run_debootstrap(suite, target, mirror, arch=None, variant=None, extra_packages=None, apt_proxy=None):
|
||||
|
|
@ -59,6 +77,54 @@ deb {mirror} {suite}-security main
|
|||
print(f"Created sources.list for {suite}")
|
||||
|
||||
|
||||
def generate_base_metadata(tree, suite, arch):
|
||||
"""Generate metadata about the created base system"""
|
||||
|
||||
# Get dpkg package list (similar to rpm metadata)
|
||||
try:
|
||||
cmd = [
|
||||
"chroot", tree,
|
||||
"dpkg-query", "-W",
|
||||
"--showformat=${Package}\t${Version}\t${Architecture}\t${Status}\n"
|
||||
]
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
|
||||
packages = []
|
||||
for line in result.stdout.strip().split('\n'):
|
||||
if line.strip():
|
||||
parts = line.split('\t')
|
||||
if len(parts) >= 4 and 'installed' in parts[3]:
|
||||
packages.append({
|
||||
"name": parts[0],
|
||||
"version": parts[1],
|
||||
"architecture": parts[2],
|
||||
"status": parts[3]
|
||||
})
|
||||
|
||||
packages = sorted(packages, key=itemgetter("name"))
|
||||
|
||||
return {
|
||||
"base_system": {
|
||||
"suite": suite,
|
||||
"architecture": arch,
|
||||
"method": "debootstrap"
|
||||
},
|
||||
"packages": packages
|
||||
}
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Warning: Could not generate package metadata: {e}")
|
||||
return {
|
||||
"base_system": {
|
||||
"suite": suite,
|
||||
"architecture": arch,
|
||||
"method": "debootstrap"
|
||||
},
|
||||
"packages": []
|
||||
}
|
||||
|
||||
|
||||
def main(tree, options):
|
||||
"""Main function for debootstrap stage"""
|
||||
|
||||
|
|
@ -78,16 +144,14 @@ def main(tree, options):
|
|||
print("No mirror specified for debootstrap")
|
||||
return 1
|
||||
|
||||
# Create temporary directory for debootstrap
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
print(f"Creating base Debian filesystem in {temp_dir}")
|
||||
print(f"Creating base Debian filesystem: {suite} from {mirror}")
|
||||
|
||||
# Run debootstrap
|
||||
if not run_debootstrap(suite, temp_dir, mirror, arch, variant, extra_packages, apt_proxy):
|
||||
# Run debootstrap directly into the target tree
|
||||
if not run_debootstrap(suite, tree, mirror, arch, variant, extra_packages, apt_proxy):
|
||||
return 1
|
||||
|
||||
# Set up apt sources
|
||||
setup_apt_sources(temp_dir, suite, mirror)
|
||||
setup_apt_sources(tree, suite, mirror)
|
||||
|
||||
# Configure apt proxy if specified
|
||||
if apt_proxy:
|
||||
|
|
@ -95,28 +159,30 @@ def main(tree, options):
|
|||
proxy_config = f"""Acquire::http::Proxy "{apt_proxy}";
|
||||
Acquire::https::Proxy "{apt_proxy}";
|
||||
"""
|
||||
proxy_file = os.path.join(temp_dir, "etc/apt/apt.conf.d/99proxy")
|
||||
proxy_file = os.path.join(tree, "etc/apt/apt.conf.d/99proxy")
|
||||
os.makedirs(os.path.dirname(proxy_file), exist_ok=True)
|
||||
with open(proxy_file, "w") as f:
|
||||
f.write(proxy_config)
|
||||
|
||||
# Copy files to target tree
|
||||
print(f"Copying filesystem to target tree: {tree}")
|
||||
# Mount essential filesystems for package operations (similar to rpm stage)
|
||||
for source in ("/dev", "/sys", "/proc"):
|
||||
target = os.path.join(tree, source.lstrip("/"))
|
||||
os.makedirs(target, exist_ok=True)
|
||||
mount(source, target, ro=False)
|
||||
|
||||
# Ensure target directory exists
|
||||
os.makedirs(tree, exist_ok=True)
|
||||
# Create /dev/fd symlink
|
||||
os.symlink("/proc/self/fd", f"{tree}/dev/fd")
|
||||
|
||||
# Copy all files from temp directory to target
|
||||
for item in os.listdir(temp_dir):
|
||||
src = os.path.join(temp_dir, item)
|
||||
dst = os.path.join(tree, item)
|
||||
# Generate metadata about the created system
|
||||
try:
|
||||
metadata = generate_base_metadata(tree, suite, arch)
|
||||
api.metadata(metadata)
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not generate metadata: {e}")
|
||||
|
||||
if os.path.isdir(src):
|
||||
if os.path.exists(dst):
|
||||
shutil.rmtree(dst)
|
||||
shutil.copytree(src, dst)
|
||||
else:
|
||||
shutil.copy2(src, dst)
|
||||
# Remove random seed if it exists (like rpm stage does)
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
os.unlink(f"{tree}/var/lib/systemd/random-seed")
|
||||
|
||||
print("Base Debian filesystem created successfully")
|
||||
return 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue