first commit
This commit is contained in:
commit
a61c0e9e0b
20 changed files with 2905 additions and 0 deletions
55
.gitignore
vendored
Normal file
55
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Build and temporary directories
|
||||
build/
|
||||
work-*/
|
||||
work/
|
||||
|
||||
# Output files and images
|
||||
output/
|
||||
*.raw
|
||||
*.qcow2
|
||||
*.img
|
||||
*.iso
|
||||
*.vmdk
|
||||
*.vdi
|
||||
|
||||
# Container images and tarballs
|
||||
*.tar
|
||||
*.tar.gz
|
||||
*.tar.bz2
|
||||
|
||||
# Loop devices and mounts
|
||||
/dev/loop*
|
||||
|
||||
# VM state files
|
||||
*.xml.bak
|
||||
*.xml~
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
*.out
|
||||
*.err
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
*~
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Package manager files
|
||||
*.deb
|
||||
*.rpm
|
||||
*.pkg
|
||||
57
bootc-compat.sh
Executable file
57
bootc-compat.sh
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ ! -d "/ostree/repo/objects" ]; then
|
||||
echo "Initializing ostree repository..."
|
||||
ostree admin init-fs / || true
|
||||
ostree admin stateroot-init debian || true
|
||||
fi
|
||||
|
||||
setup_boot() {
|
||||
echo "Setting up boot configuration..."
|
||||
if command -v bootctl &> /dev/null; then
|
||||
bootctl install --path=/boot || true
|
||||
fi
|
||||
if command -v update-grub &> /dev/null; then
|
||||
update-grub || true
|
||||
fi
|
||||
}
|
||||
|
||||
setup_deployment() {
|
||||
echo "Setting up deployment structure..."
|
||||
mkdir -p /var/lib/containers /etc/containers /usr/lib/bootc
|
||||
|
||||
cat > /usr/lib/bootc/status.json << EOJSON
|
||||
{
|
||||
"apiVersion": "org.containers.bootc/v1alpha1",
|
||||
"kind": "BootcHost",
|
||||
"spec": {
|
||||
"image": {
|
||||
"image": "localhost/debian-bootc:latest"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"booted": {
|
||||
"image": {
|
||||
"image": "localhost/debian-bootc:latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOJSON
|
||||
}
|
||||
|
||||
main() {
|
||||
echo "Starting Debian bootc compatibility layer..."
|
||||
setup_deployment
|
||||
setup_boot
|
||||
echo "Bootc compatibility setup complete."
|
||||
|
||||
if [ "${1:-}" = "--init" ]; then
|
||||
exec /sbin/init
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
283
build-with-cache.sh
Executable file
283
build-with-cache.sh
Executable file
|
|
@ -0,0 +1,283 @@
|
|||
#!/bin/bash
|
||||
# build-with-cache.sh - Enhanced build script with apt-cacher-ng support
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
IMAGE_NAME="${CONTAINER_IMAGE:-localhost/debian-bootc:ostree-transformed-v2}"
|
||||
IMAGE_TAG="latest"
|
||||
OUTPUT_DIR="./output"
|
||||
BUILD_DIR="."
|
||||
|
||||
# apt-cacher-ng configuration
|
||||
APT_CACHER_NG_URL="${APT_CACHER_NG_URL:-}"
|
||||
APT_CACHER_NG_DISCOVERY=true
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_debug() {
|
||||
echo -e "${BLUE}[DEBUG]${NC} $1"
|
||||
}
|
||||
|
||||
# Detect apt-cacher-ng automatically
|
||||
detect_apt_cacher_ng() {
|
||||
if [ -n "$APT_CACHER_NG_URL" ]; then
|
||||
log_info "Using apt-cacher-ng from environment: $APT_CACHER_NG_URL"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$APT_CACHER_NG_DISCOVERY" = true ]; then
|
||||
log_info "Auto-detecting apt-cacher-ng..."
|
||||
|
||||
# Common apt-cacher-ng URLs to try
|
||||
local urls=(
|
||||
"http://192.168.1.101:3142"
|
||||
"http://localhost:3142"
|
||||
"http://apt-cacher-ng:3142"
|
||||
"http://cache:3142"
|
||||
"http://192.168.1.100:3142"
|
||||
)
|
||||
|
||||
for url in "${urls[@]}"; do
|
||||
if curl -s --connect-timeout 5 "$url/acng-report.html" > /dev/null 2>&1; then
|
||||
APT_CACHER_NG_URL="$url"
|
||||
log_info "Found apt-cacher-ng at: $APT_CACHER_NG_URL"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
log_warn "No apt-cacher-ng found, using direct connections"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
log_info "Checking prerequisites..."
|
||||
|
||||
local missing_tools=()
|
||||
|
||||
for tool in podman buildah qemu-img curl; do
|
||||
if ! command -v "$tool" &> /dev/null; then
|
||||
missing_tools+=("$tool")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing_tools[@]} -ne 0 ]; then
|
||||
log_error "Missing required tools: ${missing_tools[*]}"
|
||||
log_info "Install them with:"
|
||||
log_info " sudo apt install podman buildah qemu-utils curl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All prerequisites satisfied."
|
||||
}
|
||||
|
||||
# Create build directory structure
|
||||
setup_build_environment() {
|
||||
log_info "Setting up build environment..."
|
||||
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Check if Dockerfile exists in current directory
|
||||
if [ ! -f "debian_bootc_dockerfile.txt" ]; then
|
||||
log_error "debian_bootc_dockerfile.txt not found in current directory"
|
||||
exit 1
|
||||
fi
|
||||
log_info "Using existing debian_bootc_dockerfile.txt"
|
||||
|
||||
# Create the compatibility script
|
||||
cat > "$BUILD_DIR/bootc-compat.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ ! -d "/ostree/repo/objects" ]; then
|
||||
echo "Initializing ostree repository..."
|
||||
ostree admin init-fs / || true
|
||||
ostree admin stateroot-init debian || true
|
||||
fi
|
||||
|
||||
setup_boot() {
|
||||
echo "Setting up boot configuration..."
|
||||
if command -v bootctl &> /dev/null; then
|
||||
bootctl install --path=/boot || true
|
||||
fi
|
||||
if command -v update-grub &> /dev/null; then
|
||||
update-grub || true
|
||||
fi
|
||||
}
|
||||
|
||||
setup_deployment() {
|
||||
echo "Setting up deployment structure..."
|
||||
mkdir -p /var/lib/containers /etc/containers /usr/lib/bootc
|
||||
|
||||
cat > /usr/lib/bootc/status.json << EOJSON
|
||||
{
|
||||
"apiVersion": "org.containers.bootc/v1alpha1",
|
||||
"kind": "BootcHost",
|
||||
"spec": {
|
||||
"image": {
|
||||
"image": "localhost/debian-bootc:latest"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"booted": {
|
||||
"image": {
|
||||
"image": "localhost/debian-bootc:latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOJSON
|
||||
}
|
||||
|
||||
main() {
|
||||
echo "Starting Debian bootc compatibility layer..."
|
||||
setup_deployment
|
||||
setup_boot
|
||||
echo "Bootc compatibility setup complete."
|
||||
|
||||
if [ "${1:-}" = "--init" ]; then
|
||||
exec /sbin/init
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
EOF
|
||||
|
||||
# Create configuration file
|
||||
cat > "$BUILD_DIR/config.toml" << 'EOF'
|
||||
[[users]]
|
||||
name = "debian"
|
||||
password = "$6$salt123$zKz/hA0eCEjVpNJC4T.nD/OXucJwPh5z9BRNDguk3EAU4isYPV3hEppKfCgZ/XZnSDdk2jxngc05ejbo.FLxV."
|
||||
groups = ["wheel", "sudo"]
|
||||
|
||||
[customizations]
|
||||
hostname = "debian-bootc"
|
||||
|
||||
[customizations.kernel]
|
||||
append = "console=ttyS0,115200n8 console=tty0"
|
||||
|
||||
[customizations.disk]
|
||||
root_fs_type = "ext4"
|
||||
|
||||
[customizations.services]
|
||||
enabled = ["sshd", "systemd-resolved"]
|
||||
EOF
|
||||
|
||||
log_info "Build environment ready in $BUILD_DIR"
|
||||
}
|
||||
|
||||
# Build container image with apt-cacher-ng support
|
||||
build_container_image() {
|
||||
log_info "Building container image with apt-cacher-ng support..."
|
||||
|
||||
local build_args=""
|
||||
if [ -n "$APT_CACHER_NG_URL" ]; then
|
||||
build_args="--build-arg APT_CACHER_NG_URL=$APT_CACHER_NG_URL"
|
||||
log_info "Building with apt-cacher-ng: $APT_CACHER_NG_URL"
|
||||
else
|
||||
log_info "Building without apt-cacher-ng (direct connections)"
|
||||
fi
|
||||
|
||||
# Extract image name without tag for podman build
|
||||
local image_name_only=$(echo "$IMAGE_NAME" | cut -d':' -f1)
|
||||
podman build $build_args -t "$image_name_only" -f debian_bootc_dockerfile.txt .
|
||||
|
||||
log_info "Container image built: $image_name_only"
|
||||
}
|
||||
|
||||
# Create QCOW2 image using bootc-image-builder
|
||||
create_qcow2_image() {
|
||||
log_info "Creating QCOW2 image using bootc-image-builder..."
|
||||
|
||||
# Check if bootc-image-builder is available
|
||||
if ! podman image exists quay.io/centos-bootc/bootc-image-builder; then
|
||||
log_info "Pulling bootc-image-builder..."
|
||||
podman pull quay.io/centos-bootc/bootc-image-builder
|
||||
fi
|
||||
|
||||
# Create the bootable image
|
||||
sudo podman run --rm -it --privileged \
|
||||
-v ./output:/output \
|
||||
-v ./build/config.toml:/config/config.toml:ro \
|
||||
-v /var/lib/containers/storage:/var/lib/containers/storage \
|
||||
quay.io/centos-bootc/bootc-image-builder \
|
||||
--type qcow2 \
|
||||
localhost/debian-bootc:latest
|
||||
|
||||
log_info "QCOW2 image created successfully!"
|
||||
}
|
||||
|
||||
# Export container image
|
||||
export_container_image() {
|
||||
log_info "Exporting container image..."
|
||||
|
||||
podman save -o "$OUTPUT_DIR/debian-bootc-container.tar" "$IMAGE_NAME:$IMAGE_TAG"
|
||||
|
||||
log_info "Container image exported to $OUTPUT_DIR/debian-bootc-container.tar"
|
||||
}
|
||||
|
||||
# Show build information
|
||||
show_build_info() {
|
||||
log_info "=== Build Information ==="
|
||||
log_info "Image: $IMAGE_NAME:$IMAGE_TAG"
|
||||
log_info "Output Directory: $OUTPUT_DIR"
|
||||
log_info "Build Directory: $BUILD_DIR"
|
||||
|
||||
if [ -n "$APT_CACHER_NG_URL" ]; then
|
||||
log_info "apt-cacher-ng: $APT_CACHER_NG_URL"
|
||||
log_info "Cache Status: Enabled"
|
||||
else
|
||||
log_info "apt-cacher-ng: Not configured"
|
||||
log_info "Cache Status: Disabled (direct connections)"
|
||||
fi
|
||||
|
||||
log_info "========================"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log_info "Starting Debian bootc container build with apt-cacher-ng support..."
|
||||
|
||||
# Detect apt-cacher-ng
|
||||
detect_apt_cacher_ng
|
||||
|
||||
# Show build information
|
||||
show_build_info
|
||||
|
||||
check_prerequisites
|
||||
setup_build_environment
|
||||
build_container_image
|
||||
|
||||
log_info "Container build process completed!"
|
||||
|
||||
if [ -n "$APT_CACHER_NG_URL" ]; then
|
||||
log_info "Container built with apt-cacher-ng caching enabled!"
|
||||
log_info "Cache URL: $APT_CACHER_NG_URL"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
16
config.toml
Normal file
16
config.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[[users]]
|
||||
name = "debian"
|
||||
password = "$6$salt123$zKz/hA0eCEjVpNJC4T.nD/OXucJwPh5z9BRNDguk3EAU4isYPV3hEppKfCgZ/XZnSDdk2jxngc05ejbo.FLxV."
|
||||
groups = ["wheel", "sudo"]
|
||||
|
||||
[customizations]
|
||||
hostname = "debian-bootc"
|
||||
|
||||
[customizations.kernel]
|
||||
append = "console=ttyS0,115200n8 console=tty0"
|
||||
|
||||
[customizations.disk]
|
||||
root_fs_type = "ext4"
|
||||
|
||||
[customizations.services]
|
||||
enabled = ["sshd", "systemd-resolved"]
|
||||
171
config/defaults.sh
Normal file
171
config/defaults.sh
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Default configuration for bootc image creation
|
||||
# This file sets default values that can be overridden by user configuration
|
||||
|
||||
# Container configuration
|
||||
export CONTAINER_IMAGE="${CONTAINER_IMAGE:-localhost/debian-bootc:ostree-transformed-v2}"
|
||||
export CONTAINER_TAG="${CONTAINER_TAG:-latest}"
|
||||
|
||||
# Output configuration
|
||||
export OUTPUT_DIR="${OUTPUT_DIR:-./output}"
|
||||
export IMAGE_SIZE_GB="${IMAGE_SIZE_GB:-10}"
|
||||
export IMAGE_NAME="${IMAGE_NAME:-debian-bootc}"
|
||||
|
||||
# Build configuration
|
||||
export BUILD_TYPE="${BUILD_TYPE:-container}" # container or chroot
|
||||
export USE_APT_CACHER="${USE_APT_CACHER:-true}"
|
||||
export APT_CACHER_URL="${APT_CACHER_URL:-http://localhost:3142}"
|
||||
|
||||
# OSTree configuration
|
||||
export OSTREE_BRANCH="${OSTREE_BRANCH:-debian/trixie/x86_64}"
|
||||
export OSTREE_SUBJECT="${OSTREE_SUBJECT:-Debian trixie system}"
|
||||
export OSTREE_MODE="${OSTREE_MODE:-bare-user}"
|
||||
|
||||
# Bootloader configuration
|
||||
export BOOTLOADER_TYPE="${BOOTLOADER_TYPE:-grub}" # grub or systemd-boot
|
||||
export KERNEL_VERSION="${KERNEL_VERSION:-6.12.41+deb13-amd64}"
|
||||
export CONSOLE_OPTIONS="${CONSOLE_OPTIONS:-console=tty0 console=ttyS0,115200n8}"
|
||||
|
||||
# User configuration
|
||||
export DEFAULT_USER="${DEFAULT_USER:-debian}"
|
||||
export DEFAULT_PASSWORD="${DEFAULT_PASSWORD:-debian123}"
|
||||
export USER_UID="${USER_UID:-1000}"
|
||||
export USER_GID="${USER_GID:-1000}"
|
||||
|
||||
# Network configuration
|
||||
export ENABLE_SSH="${ENABLE_SSH:-true}"
|
||||
export ENABLE_NETWORK="${ENABLE_NETWORK:-true}"
|
||||
|
||||
# Output formats
|
||||
export OUTPUT_FORMATS="${OUTPUT_FORMATS:-qcow2}" # qcow2, iso, img, vmdk, vdi, all
|
||||
export KEEP_RAW="${KEEP_RAW:-true}"
|
||||
|
||||
# Performance configuration
|
||||
export PARALLEL_JOBS="${PARALLEL_JOBS:-$(nproc)}"
|
||||
export COMPRESSION_LEVEL="${COMPRESSION_LEVEL:-6}"
|
||||
|
||||
# Validation configuration
|
||||
export VERIFY_IMAGE="${VERIFY_IMAGE:-true}"
|
||||
export VERIFY_FILESYSTEM="${VERIFY_FILESYSTEM:-true}"
|
||||
export VERIFY_BOOTLOADER="${VERIFY_BOOTLOADER:-true}"
|
||||
|
||||
# Cleanup configuration
|
||||
export CLEANUP_WORK_DIR="${CLEANUP_WORK_DIR:-true}"
|
||||
export CLEANUP_TEMP_FILES="${CLEANUP_TEMP_FILES:-true}"
|
||||
|
||||
# Logging configuration
|
||||
export LOG_LEVEL="${LOG_LEVEL:-info}" # debug, info, warn, error
|
||||
export VERBOSE="${VERBOSE:-false}"
|
||||
|
||||
# Security configuration
|
||||
export SIGN_IMAGES="${SIGN_IMAGES:-false}"
|
||||
export GPG_KEY="${GPG_KEY:-}"
|
||||
|
||||
# Architecture configuration
|
||||
export TARGET_ARCH="${TARGET_ARCH:-amd64}"
|
||||
export TARGET_DEBIAN_RELEASE="${TARGET_DEBIAN_RELEASE:-trixie}"
|
||||
|
||||
# Package configuration
|
||||
export BASE_PACKAGES="${BASE_PACKAGES:-systemd systemd-sysv linux-image-amd64 grub-pc ostree ostree-boot openssh-server sudo}"
|
||||
export ADDITIONAL_PACKAGES="${ADDITIONAL_PACKAGES:-curl wget vim less man-db}"
|
||||
|
||||
# Debian release configuration
|
||||
export DEBIAN_RELEASE="${DEBIAN_RELEASE:-trixie}" # Default to trixie (Debian 13)
|
||||
export DEBIAN_RELEASES="trixie forky sid"
|
||||
export DEBIAN_RELEASE_NAMES="trixie=Debian 13 forky=Debian 14 sid=Debian Unstable"
|
||||
export DEBIAN_RELEASE_DESCRIPTIONS="trixie=Debian 13 (Trixie) - Testing forky=Debian 14 (Forky) - Unstable sid=Debian Sid - Always Unstable"
|
||||
|
||||
# Set TARGET_DEBIAN_RELEASE based on DEBIAN_RELEASE
|
||||
export TARGET_DEBIAN_RELEASE="$DEBIAN_RELEASE"
|
||||
|
||||
# Timeout configuration
|
||||
export BUILD_TIMEOUT="${BUILD_TIMEOUT:-3600}" # 1 hour
|
||||
export EXTRACTION_TIMEOUT="${EXTRACTION_TIMEOUT:-1800}" # 30 minutes
|
||||
export CONVERSION_TIMEOUT="${CONVERSION_TIMEOUT:-900}" # 15 minutes
|
||||
|
||||
# Print configuration
|
||||
print_config() {
|
||||
echo "=== Bootc Image Creation Configuration ==="
|
||||
echo "Container: $CONTAINER_IMAGE"
|
||||
echo "Build Type: $BUILD_TYPE"
|
||||
echo "Output Directory: $OUTPUT_DIR"
|
||||
echo "Image Size: ${IMAGE_SIZE_GB}GB"
|
||||
echo "Output Formats: $OUTPUT_FORMATS"
|
||||
echo "Bootloader: $BOOTLOADER_TYPE"
|
||||
echo "Kernel: $KERNEL_VERSION"
|
||||
echo "User: $DEFAULT_USER:$DEFAULT_PASSWORD"
|
||||
echo "Architecture: $TARGET_ARCH"
|
||||
echo "Debian Release: $DEBIAN_RELEASE ($(get_debian_release_description "$DEBIAN_RELEASE"))"
|
||||
echo "OSTree Branch: $OSTREE_BRANCH"
|
||||
echo "Use apt-cacher: $USE_APT_CACHER"
|
||||
echo "Enable SSH: $ENABLE_SSH"
|
||||
echo "Verify Image: $VERIFY_IMAGE"
|
||||
echo "Log Level: $LOG_LEVEL"
|
||||
echo "=========================================="
|
||||
}
|
||||
|
||||
# Validate Debian release
|
||||
validate_debian_release() {
|
||||
local release="$1"
|
||||
for valid_release in $DEBIAN_RELEASES; do
|
||||
if [ "$release" = "$valid_release" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Get Debian release description
|
||||
get_debian_release_description() {
|
||||
local release="$1"
|
||||
echo "$DEBIAN_RELEASE_DESCRIPTIONS" | tr ' ' '\n' | grep "^$release=" | cut -d'=' -f2
|
||||
}
|
||||
|
||||
# Validate configuration
|
||||
validate_config() {
|
||||
local errors=()
|
||||
|
||||
# Check required values
|
||||
if [ -z "$CONTAINER_IMAGE" ]; then
|
||||
errors+=("CONTAINER_IMAGE is required")
|
||||
fi
|
||||
|
||||
if [ -z "$OUTPUT_DIR" ]; then
|
||||
errors+=("OUTPUT_DIR is required")
|
||||
fi
|
||||
|
||||
if [ -z "$IMAGE_SIZE_GB" ] || ! [[ "$IMAGE_SIZE_GB" =~ ^[0-9]+$ ]]; then
|
||||
errors+=("IMAGE_SIZE_GB must be a positive integer")
|
||||
fi
|
||||
|
||||
if [ -z "$BUILD_TYPE" ] || ! [[ "$BUILD_TYPE" =~ ^(container|chroot)$ ]]; then
|
||||
errors+=("BUILD_TYPE must be 'container' or 'chroot'")
|
||||
fi
|
||||
|
||||
if [ -z "$BOOTLOADER_TYPE" ] || ! [[ "$BOOTLOADER_TYPE" =~ ^(grub|systemd-boot)$ ]]; then
|
||||
errors+=("BOOTLOADER_TYPE must be 'grub' or 'systemd-boot'")
|
||||
fi
|
||||
|
||||
if [ -z "$TARGET_ARCH" ]; then
|
||||
errors+=("TARGET_ARCH is required")
|
||||
fi
|
||||
|
||||
# Validate Debian release
|
||||
if [ -z "$DEBIAN_RELEASE" ]; then
|
||||
errors+=("DEBIAN_RELEASE is required")
|
||||
elif ! validate_debian_release "$DEBIAN_RELEASE"; then
|
||||
errors+=("DEBIAN_RELEASE must be one of: $DEBIAN_RELEASES")
|
||||
fi
|
||||
|
||||
# Report errors
|
||||
if [ ${#errors[@]} -gt 0 ]; then
|
||||
echo "Configuration validation failed:" >&2
|
||||
for error in "${errors[@]}"; do
|
||||
echo " - $error" >&2
|
||||
done
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
161
create-and-boot-vm.sh
Executable file
161
create-and-boot-vm.sh
Executable file
|
|
@ -0,0 +1,161 @@
|
|||
#!/bin/bash
|
||||
# create-and-boot-vm.sh - Create and boot the debian-bootc VM
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
VM_NAME="debian-bootc"
|
||||
VM_XML="debian-bootc-vm.xml"
|
||||
QCOW2_PATH="/opt/Projects/overseer/alternate_paths/output/debian-bootc.qcow2"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
log_info "Checking prerequisites..."
|
||||
|
||||
if ! command -v virsh &> /dev/null; then
|
||||
log_error "virsh not found. Please install libvirt-clients:"
|
||||
log_info " sudo apt install libvirt-clients qemu-system-x86"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v qemu-system-x86_64 &> /dev/null; then
|
||||
log_error "qemu-system-x86_64 not found. Please install qemu:"
|
||||
log_info " sudo apt install qemu-system-x86"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$QCOW2_PATH" ]; then
|
||||
log_error "QCOW2 image not found: $QCOW2_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$VM_XML" ]; then
|
||||
log_error "VM XML configuration not found: $VM_XML"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All prerequisites satisfied."
|
||||
}
|
||||
|
||||
# Check if VM already exists
|
||||
check_vm_exists() {
|
||||
if virsh list --all --name | grep -q "^$VM_NAME$"; then
|
||||
log_warn "VM '$VM_NAME' already exists."
|
||||
read -p "Do you want to remove it and recreate? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "Removing existing VM..."
|
||||
virsh destroy "$VM_NAME" 2>/dev/null || true
|
||||
virsh undefine "$VM_NAME" 2>/dev/null || true
|
||||
else
|
||||
log_info "Using existing VM."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create the VM
|
||||
create_vm() {
|
||||
log_info "Creating VM '$VM_NAME'..."
|
||||
|
||||
# Check if libvirt is running
|
||||
if ! systemctl is-active --quiet libvirtd; then
|
||||
log_warn "libvirtd is not running. Starting it..."
|
||||
sudo systemctl start libvirtd
|
||||
sudo systemctl enable libvirtd
|
||||
fi
|
||||
|
||||
# Create the VM from XML
|
||||
virsh define "$VM_XML"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_info "VM '$VM_NAME' created successfully!"
|
||||
else
|
||||
log_error "Failed to create VM."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Start the VM
|
||||
start_vm() {
|
||||
log_info "Starting VM '$VM_NAME'..."
|
||||
|
||||
virsh start "$VM_NAME"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_info "VM '$VM_NAME' started successfully!"
|
||||
else
|
||||
log_error "Failed to start VM."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Show VM status
|
||||
show_vm_status() {
|
||||
log_info "VM Status:"
|
||||
virsh list --all | grep "$VM_NAME" || true
|
||||
|
||||
log_info "VM Details:"
|
||||
virsh dominfo "$VM_NAME" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Show connection info
|
||||
show_connection_info() {
|
||||
log_info "=== Connection Information ==="
|
||||
log_info "VM Name: $VM_NAME"
|
||||
log_info "QCOW2 Image: $QCOW2_PATH"
|
||||
|
||||
# Get VNC port
|
||||
VNC_PORT=$(virsh vncdisplay "$VM_NAME" 2>/dev/null | cut -d: -f2 || echo "N/A")
|
||||
if [ "$VNC_PORT" != "N/A" ]; then
|
||||
log_info "VNC Display: :$VNC_PORT"
|
||||
log_info "VNC URL: vnc://localhost:$VNC_PORT"
|
||||
fi
|
||||
|
||||
log_info "Serial Console: virsh console $VM_NAME"
|
||||
log_info "SSH (if network works): ssh debian@<VM_IP>"
|
||||
log_info "Login Credentials: debian / debian123"
|
||||
log_info "================================"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log_info "Creating and booting debian-bootc VM..."
|
||||
|
||||
check_prerequisites
|
||||
|
||||
if ! check_vm_exists; then
|
||||
create_vm
|
||||
fi
|
||||
|
||||
start_vm
|
||||
show_vm_status
|
||||
show_connection_info
|
||||
|
||||
log_info "VM is now running!"
|
||||
log_info "Use 'virsh console $VM_NAME' to access the serial console"
|
||||
log_info "Use 'virsh destroy $VM_NAME' to stop the VM"
|
||||
log_info "Use 'virsh undefine $VM_NAME' to remove the VM"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
350
create-bootc-image.sh
Executable file
350
create-bootc-image.sh
Executable file
|
|
@ -0,0 +1,350 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Main orchestration script for creating bootc images
|
||||
# This script uses modular components to create bootable images from containers or chroot
|
||||
|
||||
set -e
|
||||
|
||||
# Source configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/config/defaults.sh"
|
||||
|
||||
# Source all modules
|
||||
source "$SCRIPT_DIR/modules/common.sh"
|
||||
source "$SCRIPT_DIR/modules/disk.sh"
|
||||
source "$SCRIPT_DIR/modules/filesystem.sh"
|
||||
source "$SCRIPT_DIR/modules/bootloader.sh"
|
||||
source "$SCRIPT_DIR/modules/formats.sh"
|
||||
source "$SCRIPT_DIR/modules/chroot.sh"
|
||||
|
||||
# Mark common as loaded
|
||||
COMMON_LOADED=true
|
||||
|
||||
# Main workflow functions
|
||||
create_container_image() {
|
||||
log_info "Creating container image..."
|
||||
|
||||
if [ "$USE_APT_CACHER" = "true" ]; then
|
||||
log_info "Building with apt-cacher-ng support..."
|
||||
if command -v ./build-with-cache.sh >/dev/null 2>&1; then
|
||||
./build-with-cache.sh
|
||||
else
|
||||
log_warn "build-with-cache.sh not found, falling back to direct build"
|
||||
podman build -t "$CONTAINER_IMAGE" -f debian_bootc_dockerfile.txt .
|
||||
fi
|
||||
else
|
||||
log_info "Building container directly..."
|
||||
podman build -t "$CONTAINER_IMAGE" -f debian_bootc_dockerfile.txt .
|
||||
fi
|
||||
|
||||
log_info "Container image created: $CONTAINER_IMAGE"
|
||||
}
|
||||
|
||||
create_chroot_image() {
|
||||
log_info "Creating chroot-based image..."
|
||||
|
||||
# Create chroot environment
|
||||
create_chroot_environment
|
||||
|
||||
# Install packages
|
||||
install_chroot_packages
|
||||
|
||||
# Initialize OSTree
|
||||
init_ostree_repository
|
||||
create_ostree_commit
|
||||
deploy_ostree_system
|
||||
|
||||
# Configure bootloader
|
||||
configure_chroot_bootloader
|
||||
|
||||
log_info "Chroot-based image created"
|
||||
}
|
||||
|
||||
create_disk_image() {
|
||||
log_info "Creating disk image..."
|
||||
|
||||
# Create and partition disk
|
||||
create_disk_image_work
|
||||
create_essential_directories
|
||||
|
||||
log_info "Disk image created and partitioned"
|
||||
}
|
||||
|
||||
extract_filesystem() {
|
||||
log_info "Extracting filesystem..."
|
||||
|
||||
if [ "$BUILD_TYPE" = "container" ]; then
|
||||
# Extract from container
|
||||
extract_container_filesystem
|
||||
else
|
||||
# Copy from chroot
|
||||
copy_chroot_filesystem
|
||||
fi
|
||||
|
||||
# Fix permissions
|
||||
fix_file_permissions
|
||||
|
||||
# Verify integrity
|
||||
if [ "$VERIFY_FILESYSTEM" = "true" ]; then
|
||||
verify_filesystem_integrity
|
||||
fi
|
||||
|
||||
log_info "Filesystem extraction completed"
|
||||
}
|
||||
|
||||
install_bootloader() {
|
||||
log_info "Installing bootloader..."
|
||||
|
||||
if [ "$BOOTLOADER_TYPE" = "grub" ]; then
|
||||
install_grub_bootloader
|
||||
else
|
||||
install_systemd_boot
|
||||
fi
|
||||
|
||||
# Verify bootloader
|
||||
if [ "$VERIFY_BOOTLOADER" = "true" ]; then
|
||||
verify_bootloader
|
||||
fi
|
||||
|
||||
log_info "Bootloader installation completed"
|
||||
}
|
||||
|
||||
convert_formats() {
|
||||
log_info "Converting to output formats..."
|
||||
|
||||
case "$OUTPUT_FORMATS" in
|
||||
"qcow2")
|
||||
convert_to_qcow2
|
||||
;;
|
||||
"iso")
|
||||
convert_to_iso
|
||||
;;
|
||||
"img")
|
||||
convert_to_img
|
||||
;;
|
||||
"vmdk")
|
||||
convert_to_vmdk
|
||||
;;
|
||||
"vdi")
|
||||
convert_to_vdi
|
||||
;;
|
||||
"all")
|
||||
convert_to_all_formats
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown output format: $OUTPUT_FORMATS"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "Format conversion completed"
|
||||
}
|
||||
|
||||
cleanup_work() {
|
||||
log_info "Cleaning up work environment..."
|
||||
|
||||
if [ "$CLEANUP_WORK_DIR" = "true" ]; then
|
||||
cleanup
|
||||
fi
|
||||
|
||||
if [ "$BUILD_TYPE" = "chroot" ]; then
|
||||
cleanup_chroot
|
||||
fi
|
||||
|
||||
log_info "Cleanup completed"
|
||||
}
|
||||
|
||||
# Main execution function
|
||||
main() {
|
||||
log_info "Starting bootc image creation..."
|
||||
|
||||
# Print configuration
|
||||
print_config
|
||||
|
||||
# Validate configuration
|
||||
if ! validate_config; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Setup cleanup
|
||||
setup_cleanup
|
||||
|
||||
# Create output directory
|
||||
create_output_dir
|
||||
|
||||
# Create work directory
|
||||
create_work_dir
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites
|
||||
|
||||
# Create source image (container or chroot)
|
||||
if [ "$BUILD_TYPE" = "container" ]; then
|
||||
create_container_image
|
||||
else
|
||||
create_chroot_image
|
||||
fi
|
||||
|
||||
# Create disk image
|
||||
create_disk_image
|
||||
|
||||
# Extract filesystem
|
||||
extract_filesystem
|
||||
|
||||
# Get the loop device from the disk module
|
||||
# The disk module should have set loop_dev, but we need to ensure it's available
|
||||
if [ -z "$loop_dev" ]; then
|
||||
# Try to find the loop device by looking at the raw image
|
||||
if [ -f "$OUTPUT_DIR/debian-bootc.raw" ]; then
|
||||
loop_dev=$(sudo losetup --find --show "$OUTPUT_DIR/debian-bootc.raw")
|
||||
log_info "Found loop device: $loop_dev"
|
||||
else
|
||||
log_error "Cannot find loop device or raw image"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install bootloader
|
||||
install_bootloader
|
||||
|
||||
# Convert to output formats
|
||||
convert_formats
|
||||
|
||||
# Verify final image
|
||||
if [ "$VERIFY_IMAGE" = "true" ]; then
|
||||
verify_disk_integrity
|
||||
fi
|
||||
|
||||
# Show final results
|
||||
show_format_info
|
||||
|
||||
# Cleanup
|
||||
cleanup_work
|
||||
|
||||
log_info "Bootc image creation completed successfully!"
|
||||
log_info "Output directory: $OUTPUT_DIR"
|
||||
}
|
||||
|
||||
# Show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Create a bootable bootc image from container or chroot.
|
||||
|
||||
OPTIONS:
|
||||
-t, --type TYPE Build type: container or chroot (default: container)
|
||||
-f, --format FORMAT Output format: qcow2, iso, img, vmdk, vdi, all (default: qcow2)
|
||||
-s, --size SIZE Image size in GB (default: 10)
|
||||
-o, --output DIR Output directory (default: ./output)
|
||||
-c, --container IMAGE Container image name (default: localhost/debian-bootc:ostree-transformed-v2)
|
||||
-b, --bootloader TYPE Bootloader type: grub or systemd-boot (default: grub)
|
||||
-a, --arch ARCH Target architecture (default: amd64)
|
||||
-r, --release RELEASE Debian release: trixie, forky, sid (default: trixie)
|
||||
-u, --user USER Default username (default: debian)
|
||||
-p, --password PASS Default password (default: debian123)
|
||||
-n, --no-cache Disable apt-cacher-ng
|
||||
-v, --verbose Enable verbose output
|
||||
-h, --help Show this help message
|
||||
|
||||
EXAMPLES:
|
||||
# Create QCOW2 image from container
|
||||
$0 -t container -f qcow2
|
||||
|
||||
# Create ISO image from chroot
|
||||
$0 -t chroot -f iso -s 20
|
||||
|
||||
# Create all formats from container
|
||||
$0 -t container -f all -o ./my-images
|
||||
|
||||
# Custom configuration
|
||||
BUILD_TYPE=chroot OUTPUT_FORMATS=iso $0
|
||||
|
||||
CONFIGURATION:
|
||||
Environment variables can be used to override defaults:
|
||||
- BUILD_TYPE: container or chroot
|
||||
- OUTPUT_FORMATS: qcow2, iso, img, vmdk, vdi, all
|
||||
- IMAGE_SIZE_GB: Image size in gigabytes
|
||||
- OUTPUT_DIR: Output directory
|
||||
- CONTAINER_IMAGE: Container image name
|
||||
- BOOTLOADER_TYPE: grub or systemd-boot
|
||||
- TARGET_ARCH: Target architecture
|
||||
- TARGET_DEBIAN_RELEASE: Debian release
|
||||
- DEFAULT_USER: Default username
|
||||
- DEFAULT_PASSWORD: Default password
|
||||
- USE_APT_CACHER: Enable/disable apt-cacher-ng
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-t|--type)
|
||||
BUILD_TYPE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-f|--format)
|
||||
OUTPUT_FORMATS="$2"
|
||||
shift 2
|
||||
;;
|
||||
-s|--size)
|
||||
IMAGE_SIZE_GB="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--output)
|
||||
OUTPUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-c|--container)
|
||||
CONTAINER_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-b|--bootloader)
|
||||
BOOTLOADER_TYPE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-a|--arch)
|
||||
TARGET_ARCH="$2"
|
||||
shift 2
|
||||
;;
|
||||
-r|--release)
|
||||
DEBIAN_RELEASE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-u|--user)
|
||||
DEFAULT_USER="$2"
|
||||
shift 2
|
||||
;;
|
||||
-p|--password)
|
||||
DEFAULT_PASSWORD="$2"
|
||||
shift 2
|
||||
;;
|
||||
-n|--no-cache)
|
||||
USE_APT_CACHER="false"
|
||||
shift
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSE="true"
|
||||
LOG_LEVEL="debug"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
parse_args "$@"
|
||||
main
|
||||
fi
|
||||
121
debian-bootc-vm.xml
Normal file
121
debian-bootc-vm.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain type="kvm">
|
||||
<name>debian-bootc</name>
|
||||
<uuid>12345678-1234-1234-1234-123456789abc</uuid>
|
||||
<title>Debian Bootc OSTree System</title>
|
||||
<description>Debian bootc container with OSTree support</description>
|
||||
|
||||
<memory unit="GiB">2</memory>
|
||||
<currentMemory unit="GiB">2</currentMemory>
|
||||
<vcpu>2</vcpu>
|
||||
<maxvcpu>4</maxvcpu>
|
||||
|
||||
<os>
|
||||
<type arch="x86_64" machine="pc-q35-8.0">hvm</type>
|
||||
<boot dev="hd"/>
|
||||
<boot dev="cdrom"/>
|
||||
<bootmenu enable="yes" timeout="3000"/>
|
||||
</os>
|
||||
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
|
||||
<cpu mode="host-model" check="partial"/>
|
||||
|
||||
<clock offset="utc">
|
||||
<timer name="rtc" tickpolicy="catchup"/>
|
||||
<timer name="pit" tickpolicy="delay"/>
|
||||
<timer name="hpet" present="no"/>
|
||||
</clock>
|
||||
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
|
||||
<!-- Disk -->
|
||||
<disk type="file" device="disk">
|
||||
<driver name="qemu" type="raw" cache="writeback"/>
|
||||
<source file="/opt/Projects/overseer/alternate_paths/output/debian-bootc-simple.raw"/>
|
||||
<target dev="sda" bus="sata"/>
|
||||
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
|
||||
</disk>
|
||||
|
||||
<!-- Network (temporarily disabled due to conflict) -->
|
||||
<!--
|
||||
<interface type="network">
|
||||
<source network="default"/>
|
||||
<model type="virtio"/>
|
||||
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
|
||||
</interface>
|
||||
-->
|
||||
|
||||
<!-- Graphics -->
|
||||
<graphics type="vnc" port="-1" autoport="yes" listen="0.0.0.0">
|
||||
<listen type="address" address="0.0.0.0"/>
|
||||
</graphics>
|
||||
|
||||
<!-- Serial Console -->
|
||||
<serial type="pty">
|
||||
<target type="isa-serial" port="0">
|
||||
<model name="isa-serial"/>
|
||||
</target>
|
||||
</serial>
|
||||
|
||||
<!-- Console -->
|
||||
<console type="pty">
|
||||
<target type="serial" port="0"/>
|
||||
</console>
|
||||
|
||||
<!-- Input Devices -->
|
||||
<input type="tablet" bus="usb">
|
||||
<address type="usb" bus="0" port="1"/>
|
||||
</input>
|
||||
<input type="keyboard" bus="usb">
|
||||
<address type="usb" bus="0" port="2"/>
|
||||
</input>
|
||||
|
||||
<!-- USB Controller -->
|
||||
<controller type="usb" index="0" model="qemu-xhci">
|
||||
<address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
|
||||
</controller>
|
||||
|
||||
<!-- SATA Controller -->
|
||||
<controller type="sata" index="0">
|
||||
<address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
|
||||
</controller>
|
||||
|
||||
<!-- PCI Bridge -->
|
||||
<controller type="pci" index="0" model="pcie-root"/>
|
||||
<controller type="pci" index="1" model="pcie-root-port">
|
||||
<model name="pcie-root-port"/>
|
||||
<target chassis="1" port="0x8"/>
|
||||
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0" multifunction="on"/>
|
||||
</controller>
|
||||
<controller type="pci" index="2" model="pcie-root-port">
|
||||
<model name="pcie-root-port"/>
|
||||
<target chassis="2" port="0x9"/>
|
||||
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x1"/>
|
||||
</controller>
|
||||
<controller type="pci" index="3" model="pcie-root-port">
|
||||
<model name="pcie-root-port"/>
|
||||
<target chassis="3" port="0xa"/>
|
||||
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x2"/>
|
||||
</controller>
|
||||
<controller type="pci" index="4" model="pcie-root-port">
|
||||
<model name="pcie-root-port"/>
|
||||
<target chassis="4" port="0xb"/>
|
||||
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x3"/>
|
||||
</controller>
|
||||
|
||||
<!-- RNG for entropy -->
|
||||
<rng model="virtio">
|
||||
<backend model="random">/dev/urandom</backend>
|
||||
<address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
|
||||
</rng>
|
||||
</devices>
|
||||
</domain>
|
||||
142
debian_bootc_dockerfile.txt
Normal file
142
debian_bootc_dockerfile.txt
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
FROM debian:trixie-slim
|
||||
|
||||
# Install essential packages for bootc compatibility
|
||||
RUN apt-get update && apt-get install -y \
|
||||
ostree \
|
||||
ostree-boot \
|
||||
systemd \
|
||||
systemd-boot \
|
||||
linux-image-amd64 \
|
||||
grub-efi-amd64 \
|
||||
openssh-server \
|
||||
sudo \
|
||||
curl \
|
||||
wget \
|
||||
ca-certificates \
|
||||
polkitd \
|
||||
pkexec \
|
||||
libpolkit-gobject-1-0 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Download and install bootc package
|
||||
RUN wget https://git.raines.xyz/robojerk/-/packages/debian/bootc/1.6.0-1~trixie1/files/495 -O bootc_1.6.0-1~trixie1_amd64.deb && \
|
||||
dpkg -i bootc_1.6.0-1~trixie1_amd64.deb && \
|
||||
rm bootc_1.6.0-1~trixie1_amd64.deb
|
||||
|
||||
# Create a default user
|
||||
RUN useradd -m -s /bin/bash -G sudo debian && \
|
||||
echo "debian:debian123" | chpasswd
|
||||
|
||||
# Configure SSH
|
||||
RUN mkdir -p /home/debian/.ssh && \
|
||||
chmod 700 /home/debian/.ssh && \
|
||||
chown debian:debian /home/debian/.ssh
|
||||
|
||||
# ===== OSTREE FILESYSTEM TRANSFORMATION =====
|
||||
# This is the critical step that transforms traditional Debian to OSTree
|
||||
|
||||
# Initialize OSTree repository
|
||||
RUN mkdir -p /ostree/repo && \
|
||||
ostree init --repo=/ostree/repo --mode=bare-user
|
||||
|
||||
# Create OSTree deployment structure
|
||||
RUN ostree admin init-fs / && \
|
||||
ostree admin stateroot-init debian
|
||||
|
||||
# Create a simple OSTree commit from the current filesystem
|
||||
RUN mkdir -p /tmp/ostree-commit && \
|
||||
cd /tmp/ostree-commit && \
|
||||
# Copy only the files we want in OSTree (exclude special filesystems)
|
||||
cp -r /bin . && \
|
||||
cp -r /lib . && \
|
||||
cp -r /lib64 . && \
|
||||
cp -r /sbin . && \
|
||||
cp -r /usr . && \
|
||||
cp -r /etc . && \
|
||||
cp -r /var . && \
|
||||
cp -r /home . && \
|
||||
cp -r /root . && \
|
||||
cp -r /boot . && \
|
||||
# Create essential directories properly
|
||||
mkdir -p proc && \
|
||||
mkdir -p sys && \
|
||||
mkdir -p dev && \
|
||||
mkdir -p tmp && \
|
||||
mkdir -p run && \
|
||||
mkdir -p media && \
|
||||
mkdir -p mnt && \
|
||||
mkdir -p ostree && \
|
||||
# Create OSTree-expected kernel locations
|
||||
mkdir -p usr/lib/ostree-boot && \
|
||||
# Debug: check what's in boot directory
|
||||
echo "Boot directory contents:" && ls -la boot/ && \
|
||||
# Move kernel and initrd to OSTree-expected location
|
||||
if [ -f boot/vmlinuz-6.12.41+deb13-amd64 ]; then \
|
||||
cp boot/vmlinuz-6.12.41+deb13-amd64 usr/lib/ostree-boot/ && \
|
||||
echo "Kernel copied successfully"; \
|
||||
else \
|
||||
echo "Kernel not found!" && \
|
||||
find boot/ -name "*vmlinuz*" -o -name "*kernel*" 2>/dev/null; \
|
||||
fi && \
|
||||
if [ -f boot/initrd.img-6.12.41+deb13-amd64 ]; then \
|
||||
cp boot/initrd.img-6.12.41+deb13-amd64 usr/lib/ostree-boot/ && \
|
||||
echo "Initrd copied successfully"; \
|
||||
else \
|
||||
echo "Initrd not found!" && \
|
||||
find boot/ -name "*initrd*" 2>/dev/null; \
|
||||
fi && \
|
||||
# Create the commit
|
||||
ostree commit \
|
||||
--repo=/ostree/repo \
|
||||
--branch=debian/trixie/x86_64 \
|
||||
--subject="Debian trixie system" \
|
||||
--tree=dir=. && \
|
||||
echo "OSTree commit created successfully" && \
|
||||
# Clean up
|
||||
cd / && rm -rf /tmp/ostree-commit
|
||||
|
||||
# Deploy the OSTree commit to create proper deployment structure
|
||||
# Note: Deployment will be done at runtime when the container boots
|
||||
RUN echo "OSTree commit created, deployment will be done at runtime" && \
|
||||
echo "Commit hash: $(ostree rev-parse --repo=/ostree/repo debian/trixie/x86_64)"
|
||||
|
||||
# Configure OSTree
|
||||
RUN mkdir -p /etc/ostree && \
|
||||
echo "[origin]" > /etc/ostree/remotes.d/origin.conf && \
|
||||
echo "repo=/ostree/repo" >> /etc/ostree/remotes.d/origin.conf
|
||||
|
||||
# Configure bootloader
|
||||
RUN mkdir -p /boot/loader/entries
|
||||
|
||||
# Add bootc compatibility layer script
|
||||
COPY bootc-compat.sh /usr/local/bin/bootc-compat.sh
|
||||
RUN chmod +x /usr/local/bin/bootc-compat.sh
|
||||
|
||||
# Set up bootc status directory
|
||||
RUN mkdir -p /usr/lib/bootc
|
||||
|
||||
# Create bootc status file
|
||||
RUN echo '{' > /usr/lib/bootc/status.json && \
|
||||
echo ' "apiVersion": "org.containers.bootc/v1alpha1",' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "kind": "BootcHost",' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "spec": {' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "image": {' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "image": "localhost/debian-bootc:latest"' >> /usr/lib/bootc/status.json && \
|
||||
echo ' }' >> /usr/lib/bootc/status.json && \
|
||||
echo ' },' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "status": {' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "booted": {' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "image": {' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "image": "localhost/debian-bootc:latest",' >> /usr/lib/bootc/status.json && \
|
||||
echo ' "imageDigest": "sha256:$(echo -n '\''debian-bootc'\'' | sha256sum | cut -d'\'' '\'' -f1)"' >> /usr/lib/bootc/status.json && \
|
||||
echo ' }' >> /usr/lib/bootc/status.json && \
|
||||
echo ' }' >> /usr/lib/bootc/status.json && \
|
||||
echo ' }' >> /usr/lib/bootc/status.json && \
|
||||
echo '}' >> /usr/lib/bootc/status.json
|
||||
|
||||
# Set proper labels
|
||||
LABEL bootc.filesystem="ext4"
|
||||
LABEL bootc.architecture="x86_64"
|
||||
LABEL ostree.commit="debian/trixie/x86_64"
|
||||
|
||||
CMD ["/usr/local/bin/bootc-compat.sh"]
|
||||
12
default-network.xml
Normal file
12
default-network.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<network>
|
||||
<name>default</name>
|
||||
<uuid>12345678-1234-1234-1234-123456789abc</uuid>
|
||||
<forward mode='nat'/>
|
||||
<bridge name='virbr0' stp='on' delay='0'/>
|
||||
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
||||
<dhcp>
|
||||
<range start='192.168.122.2' end='192.168.122.254'/>
|
||||
</dhcp>
|
||||
</ip>
|
||||
</network>
|
||||
|
||||
226
justfile
Normal file
226
justfile
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
# Justfile for bootc image creation
|
||||
# Provides user-friendly commands for creating bootable images
|
||||
|
||||
# Default configuration
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Create QCOW2 image from container (default)
|
||||
qcow2:
|
||||
@echo "Creating QCOW2 image from container..."
|
||||
./create-bootc-image.sh -t container -f qcow2
|
||||
|
||||
# Create QCOW2 image from chroot
|
||||
qcow2-chroot:
|
||||
@echo "Creating QCOW2 image from chroot..."
|
||||
./create-bootc-image.sh -t chroot -f qcow2
|
||||
|
||||
# Create QCOW2 image from chroot with specific Debian release
|
||||
qcow2-chroot-release release="trixie":
|
||||
@echo "Creating QCOW2 image from chroot using Debian {{release}}..."
|
||||
DEBIAN_RELEASE={{release}} ./create-bootc-image.sh -t chroot -f qcow2
|
||||
|
||||
# Create ISO image from container
|
||||
iso:
|
||||
@echo "Creating ISO image from container..."
|
||||
./create-bootc-image.sh -t container -f iso
|
||||
|
||||
# Create ISO image from chroot
|
||||
iso-chroot:
|
||||
@echo "Creating ISO image from chroot..."
|
||||
./create-bootc-image.sh -t chroot -f iso
|
||||
|
||||
# Create IMG (raw) image from container
|
||||
img:
|
||||
@echo "Creating IMG image from container..."
|
||||
./create-bootc-image.sh -t container -f img
|
||||
|
||||
# Create IMG (raw) image from chroot
|
||||
img-chroot:
|
||||
@echo "Creating IMG image from chroot..."
|
||||
./create-bootc-image.sh -t chroot -f img
|
||||
|
||||
# Create all formats from container
|
||||
all:
|
||||
@echo "Creating all formats from container..."
|
||||
./create-bootc-image.sh -t container -f all
|
||||
|
||||
# Create all formats from chroot
|
||||
all-chroot:
|
||||
@echo "Creating all formats from chroot..."
|
||||
./create-bootc-image.sh -t chroot -f all
|
||||
|
||||
# Create VMDK image from container
|
||||
vmdk:
|
||||
@echo "Creating VMDK image from container..."
|
||||
./create-bootc-image.sh -t container -f vmdk
|
||||
|
||||
# Create VDI image from container
|
||||
vdi:
|
||||
@echo "Creating VDI image from container..."
|
||||
./create-bootc-image.sh -t container -f vdi
|
||||
|
||||
# Create custom image with specific size
|
||||
custom size="20" format="qcow2":
|
||||
@echo "Creating {{format}} image with size {{size}}GB from container..."
|
||||
./create-bootc-image.sh -t container -f {{format}} -s {{size}}
|
||||
|
||||
# Create custom image from chroot with specific size
|
||||
custom-chroot size="20" format="qcow2":
|
||||
@echo "Creating {{format}} image with size {{size}}GB from chroot..."
|
||||
./create-bootc-image.sh -t chroot -f {{format}} -s {{size}}
|
||||
|
||||
# Create custom image from chroot with specific size and Debian release
|
||||
custom-chroot-release size="20" format="qcow2" release="trixie":
|
||||
@echo "Creating {{format}} image with size {{size}}GB from chroot using Debian {{release}}..."
|
||||
DEBIAN_RELEASE={{release}} ./create-bootc-image.sh -t chroot -f {{format}} -s {{size}}
|
||||
|
||||
# Build container only
|
||||
build:
|
||||
@echo "Building container image..."
|
||||
./build-with-cache.sh
|
||||
|
||||
# Build container without cache
|
||||
build-no-cache:
|
||||
@echo "Building container image without cache..."
|
||||
BUILD_TYPE=container USE_APT_CACHER=false ./create-bootc-image.sh -t container -f qcow2
|
||||
|
||||
# Setup apt-cacher-ng
|
||||
setup-cache:
|
||||
@echo "Setting up apt-cacher-ng..."
|
||||
./setup-apt-cacher-ng.sh
|
||||
|
||||
# Test container
|
||||
test:
|
||||
@echo "Testing container..."
|
||||
./test-bootc-container.sh
|
||||
|
||||
# Create and boot VM
|
||||
vm:
|
||||
@echo "Creating and booting VM..."
|
||||
./create-and-boot-vm.sh
|
||||
|
||||
# Clean output directory
|
||||
clean:
|
||||
@echo "Cleaning output directory..."
|
||||
rm -rf output/*
|
||||
|
||||
# Clean work directories
|
||||
clean-work:
|
||||
@echo "Cleaning work directories..."
|
||||
rm -rf work-* simple-work-* ostree-work-*
|
||||
|
||||
# Clean everything
|
||||
clean-all: clean clean-work
|
||||
@echo "All cleanup completed"
|
||||
|
||||
# Show cleanup examples
|
||||
cleanup-examples:
|
||||
@echo "Cleanup Examples:"
|
||||
@echo " # After successful build, clean work files"
|
||||
@echo " just clean-work"
|
||||
@echo ""
|
||||
@echo " # Before new build, clean everything"
|
||||
@echo " just clean-all"
|
||||
@echo ""
|
||||
@echo " # Quick cleanup of just output files"
|
||||
@echo " just clean"
|
||||
|
||||
# Show configuration
|
||||
config:
|
||||
@echo "Current configuration:"
|
||||
@echo "Configuration can be viewed by running:"
|
||||
@echo " ./create-bootc-image.sh --help"
|
||||
@echo ""
|
||||
@echo "Or check the defaults file:"
|
||||
@echo " cat config/defaults.sh"
|
||||
|
||||
# Show available formats
|
||||
formats:
|
||||
@echo "Available output formats:"
|
||||
@echo " qcow2 - QEMU Copy-On-Write (default)"
|
||||
@echo " iso - Bootable ISO image"
|
||||
@echo " img - Raw disk image"
|
||||
@echo " vmdk - VMware disk format"
|
||||
@echo " vdi - VirtualBox disk format"
|
||||
@echo " all - All formats"
|
||||
|
||||
# Show build types
|
||||
types:
|
||||
@echo "Available build types:"
|
||||
@echo " container - Extract from container image (default)"
|
||||
@echo " chroot - Build from chroot environment"
|
||||
|
||||
# Show available Debian releases
|
||||
releases:
|
||||
@echo "Available Debian releases:"
|
||||
@echo " trixie - Debian 13 (Testing) - DEFAULT"
|
||||
@echo " forky - Debian 14 (Unstable)"
|
||||
@echo " sid - Debian Sid (Always Unstable)"
|
||||
|
||||
# Show examples
|
||||
examples:
|
||||
@echo "Example commands:"
|
||||
@echo " just qcow2 # Create QCOW2 from container"
|
||||
@echo " just iso-chroot # Create ISO from chroot"
|
||||
@echo " just custom 15 iso # Create 15GB ISO from container"
|
||||
@echo " just all # Create all formats from container"
|
||||
@echo " just vm # Create and boot VM"
|
||||
@echo ""
|
||||
@echo "Debian release examples:"
|
||||
@echo " just qcow2-chroot-release forky # Create QCOW2 from chroot using Debian 14"
|
||||
@echo " just custom-chroot-release 25 iso trixie # Create 25GB ISO from chroot using Debian 13"
|
||||
@echo " DEBIAN_RELEASE=sid just qcow2-chroot # Use Debian Sid via environment variable"
|
||||
|
||||
# Show help
|
||||
help:
|
||||
@echo "Bootc Image Creation Commands"
|
||||
@echo "============================="
|
||||
@echo ""
|
||||
@echo "Basic Commands:"
|
||||
@echo " just qcow2 # Create QCOW2 image (default)"
|
||||
@echo " just iso # Create ISO image"
|
||||
@echo " just img # Create IMG image"
|
||||
@echo " just all # Create all formats"
|
||||
@echo ""
|
||||
@echo "Chroot Commands:"
|
||||
@echo " just qcow2-chroot # Create QCOW2 from chroot"
|
||||
@echo " just iso-chroot # Create ISO from chroot"
|
||||
@echo " just img-chroot # Create IMG from chroot"
|
||||
@echo " just all-chroot # Create all formats from chroot"
|
||||
@echo ""
|
||||
@echo "Debian Release Commands:"
|
||||
@echo " just qcow2-chroot-release forky # Create QCOW2 from chroot using Debian 14"
|
||||
@echo " just qcow2-chroot-release sid # Create QCOW2 from chroot using Debian Sid"
|
||||
@echo " just custom-chroot-release 25 iso trixie # Create 25GB ISO from chroot using Debian 13"
|
||||
@echo ""
|
||||
@echo "Custom Commands:"
|
||||
@echo " just custom 20 iso # Create 20GB ISO from container"
|
||||
@echo " just custom-chroot 15 qcow2 # Create 15GB QCOW2 from chroot"
|
||||
@echo ""
|
||||
@echo "Utility Commands:"
|
||||
@echo " just build # Build container only"
|
||||
@echo " just vm # Create and boot VM"
|
||||
@echo " just clean # Clean output files"
|
||||
@echo " just clean-work # Clean work directories"
|
||||
@echo " just clean-all # Clean everything"
|
||||
@echo " just cleanup-examples # Show cleanup examples"
|
||||
@echo " just config # Show configuration"
|
||||
@echo " just formats # Show available formats"
|
||||
@echo " just types # Show build types"
|
||||
@echo " just releases # Show available Debian releases"
|
||||
@echo " just examples # Show examples"
|
||||
@echo ""
|
||||
@echo "Environment Variables:"
|
||||
@echo " DEBIAN_RELEASE # Set Debian release (trixie, forky, sid)"
|
||||
@echo " BUILD_TYPE # Set build type (container, chroot)"
|
||||
@echo " OUTPUT_FORMATS # Set output format (qcow2, iso, img, vmdk, vdi, all)"
|
||||
@echo ""
|
||||
@echo "For more options, run: ./create-bootc-image.sh --help"
|
||||
|
||||
# List all available commands
|
||||
list:
|
||||
@echo "Available commands:"
|
||||
@just --list
|
||||
|
||||
|
||||
236
modules/bootloader.sh
Normal file
236
modules/bootloader.sh
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Bootloader management module for bootc image creation
|
||||
# This module handles GRUB installation and configuration
|
||||
|
||||
# Common functions are sourced by the main script
|
||||
|
||||
# Install GRUB bootloader
|
||||
install_grub_bootloader() {
|
||||
log_info "Installing bootloader..."
|
||||
|
||||
# Check if kernel exists
|
||||
if [ -f "$WORK_DIR/mnt/boot/vmlinuz-6.12.41+deb13-amd64" ]; then
|
||||
log_info "Kernel found in /boot location"
|
||||
KERNEL_PATH="boot/vmlinuz-6.12.41+deb13-amd64"
|
||||
INITRD_PATH="boot/initrd.img-6.12.41+deb13-amd64"
|
||||
elif [ -f "$WORK_DIR/mnt/usr/lib/ostree-boot/vmlinuz-6.12.41+deb13-amd64" ]; then
|
||||
log_info "Kernel found in OSTree location"
|
||||
KERNEL_PATH="usr/lib/ostree-boot/vmlinuz-6.12.41+deb13-amd64"
|
||||
INITRD_PATH="usr/lib/ostree-boot/initrd.img-6.12.41+deb13-amd64"
|
||||
else
|
||||
log_error "Kernel not found in expected locations"
|
||||
log_info "Searching for kernel files..."
|
||||
find "$WORK_DIR/mnt" -name "*vmlinuz*" -o -name "*kernel*" 2>/dev/null | head -10
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install GRUB bootloader
|
||||
log_info "Installing GRUB bootloader..."
|
||||
|
||||
# Create GRUB directory
|
||||
sudo mkdir -p "$WORK_DIR/mnt/boot/grub"
|
||||
|
||||
# Temporarily unmount and remount for safer GRUB installation
|
||||
log_info "Temporarily unmounting filesystem for GRUB installation..."
|
||||
sudo umount "$WORK_DIR/mnt"
|
||||
|
||||
# Get the loop device from the disk module
|
||||
if [ -z "$loop_dev" ]; then
|
||||
log_error "Loop device not set. Cannot install bootloader."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Ensure the loop device path is correct
|
||||
local device_path="${loop_dev}"
|
||||
if [[ "$device_path" == /dev/* ]]; then
|
||||
device_path="${device_path#/dev/}"
|
||||
fi
|
||||
|
||||
log_info "Loop device: $loop_dev, device path: $device_path"
|
||||
log_info "Mounting partition /dev/${device_path}p2"
|
||||
sudo mount "/dev/${device_path}p2" "$WORK_DIR/mnt"
|
||||
|
||||
# Install GRUB to the disk
|
||||
log_info "Installing GRUB to /dev/$device_path..."
|
||||
if sudo grub-install --target=i386-pc --boot-directory="$WORK_DIR/mnt/boot" "/dev/$device_path"; then
|
||||
log_info "GRUB installed successfully"
|
||||
else
|
||||
log_warn "GRUB installation failed, trying alternative method..."
|
||||
# Try installing to the partition instead
|
||||
if sudo grub-install --target=i386-pc --boot-directory="$WORK_DIR/mnt/boot" "/dev/${device_path}p2"; then
|
||||
log_info "GRUB installed to partition successfully"
|
||||
else
|
||||
log_error "GRUB installation failed completely"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create GRUB configuration
|
||||
log_info "Creating GRUB configuration..."
|
||||
sudo tee "$WORK_DIR/mnt/boot/grub/grub.cfg" > /dev/null << EOF
|
||||
set timeout=5
|
||||
set default=0
|
||||
|
||||
menuentry "Debian Bootc" {
|
||||
linux /$KERNEL_PATH root=/dev/sda2 rw console=tty0 console=ttyS0,115200n8
|
||||
initrd /$INITRD_PATH
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Bootloader installation completed"
|
||||
}
|
||||
|
||||
# Install systemd-boot (for UEFI systems)
|
||||
install_systemd_boot() {
|
||||
log_info "Installing systemd-boot..."
|
||||
|
||||
# Create bootloader entries directory
|
||||
sudo mkdir -p "$WORK_DIR/mnt/boot/loader/entries"
|
||||
|
||||
# Create bootloader entry
|
||||
sudo tee "$WORK_DIR/mnt/boot/loader/entries/debian-bootc.conf" > /dev/null << EOF
|
||||
title Debian Bootc
|
||||
version 1
|
||||
linux /ostree/debian-bootc/vmlinuz-6.12.41+deb13-amd64
|
||||
initrd /ostree/debian-bootc/initramfs-6.12.41+deb13-amd64.img
|
||||
options ostree=/ostree/boot.0/debian-bootc/0 rw console=tty0 console=ttyS0,115200n8
|
||||
EOF
|
||||
|
||||
# Create loader configuration
|
||||
sudo tee "$WORK_DIR/mnt/boot/loader/loader.conf" > /dev/null << EOF
|
||||
default debian-bootc
|
||||
timeout 5
|
||||
editor no
|
||||
EOF
|
||||
|
||||
log_info "systemd-boot installation completed"
|
||||
}
|
||||
|
||||
# Verify bootloader installation
|
||||
verify_bootloader() {
|
||||
log_info "Verifying bootloader installation..."
|
||||
|
||||
# Check GRUB configuration
|
||||
if [ -f "$WORK_DIR/mnt/boot/grub/grub.cfg" ]; then
|
||||
log_info "GRUB configuration found"
|
||||
else
|
||||
log_error "GRUB configuration not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check GRUB core image
|
||||
if [ -f "$WORK_DIR/mnt/boot/grub/i386-pc/core.img" ]; then
|
||||
log_info "GRUB core image found"
|
||||
else
|
||||
log_warn "GRUB core image not found - bootloader may not work"
|
||||
fi
|
||||
|
||||
# Check kernel and initrd
|
||||
if [ -f "$WORK_DIR/mnt/boot/vmlinuz-6.12.41+deb13-amd64" ]; then
|
||||
log_info "Kernel found: vmlinuz-6.12.41+deb13-amd64"
|
||||
else
|
||||
log_error "Kernel not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -f "$WORK_DIR/mnt/boot/initrd.img-6.12.41+deb13-amd64" ]; then
|
||||
log_info "Initrd found: initrd.img-6.12.41+deb13-amd64"
|
||||
else
|
||||
log_error "Initrd not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Bootloader verification completed successfully"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Show bootloader information
|
||||
show_bootloader_info() {
|
||||
log_info "Bootloader information:"
|
||||
|
||||
echo "GRUB configuration:"
|
||||
if [ -f "$WORK_DIR/mnt/boot/grub/grub.cfg" ]; then
|
||||
cat "$WORK_DIR/mnt/boot/grub/grub.cfg"
|
||||
else
|
||||
echo "GRUB configuration not found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Boot directory contents:"
|
||||
ls -la "$WORK_DIR/mnt/boot/"
|
||||
|
||||
echo ""
|
||||
echo "GRUB directory contents:"
|
||||
if [ -d "$WORK_DIR/mnt/boot/grub" ]; then
|
||||
ls -la "$WORK_DIR/mnt/boot/grub/"
|
||||
else
|
||||
echo "GRUB directory not found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Customize GRUB configuration
|
||||
customize_grub_config() {
|
||||
local custom_config="$1"
|
||||
|
||||
if [ -n "$custom_config" ] && [ -f "$custom_config" ]; then
|
||||
log_info "Applying custom GRUB configuration..."
|
||||
sudo cp "$custom_config" "$WORK_DIR/mnt/boot/grub/grub.cfg"
|
||||
log_info "Custom GRUB configuration applied"
|
||||
else
|
||||
log_warn "No custom GRUB configuration provided or file not found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set GRUB timeout
|
||||
set_grub_timeout() {
|
||||
local timeout="${1:-5}"
|
||||
|
||||
log_info "Setting GRUB timeout to ${timeout} seconds..."
|
||||
|
||||
# Update the existing grub.cfg with new timeout
|
||||
sudo sed -i "s/set timeout=.*/set timeout=$timeout/" "$WORK_DIR/mnt/boot/grub/grub.cfg"
|
||||
|
||||
log_info "GRUB timeout set to ${timeout} seconds"
|
||||
}
|
||||
|
||||
# Add custom GRUB menu entries
|
||||
add_grub_menu_entry() {
|
||||
local title="$1"
|
||||
local kernel_path="$2"
|
||||
local initrd_path="$3"
|
||||
local root_device="${4:-/dev/sda2}"
|
||||
local extra_params="${5:-}"
|
||||
|
||||
log_info "Adding GRUB menu entry: $title"
|
||||
|
||||
# Append to grub.cfg
|
||||
sudo tee -a "$WORK_DIR/mnt/boot/grub/grub.cfg" > /dev/null << EOF
|
||||
|
||||
menuentry "$title" {
|
||||
linux /$kernel_path root=$root_device rw console=tty0 console=ttyS0,115200n8 $extra_params
|
||||
initrd /$initrd_path
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "GRUB menu entry added: $title"
|
||||
}
|
||||
|
||||
# Print module usage
|
||||
print_module_usage() {
|
||||
echo "Usage: source modules/bootloader.sh"
|
||||
echo "This module handles bootloader installation and configuration."
|
||||
echo ""
|
||||
echo "Available functions:"
|
||||
echo " install_bootloader - Install GRUB bootloader"
|
||||
echo " install_systemd_boot - Install systemd-boot (UEFI)"
|
||||
echo " verify_bootloader - Verify bootloader installation"
|
||||
echo " show_bootloader_info - Display bootloader information"
|
||||
echo " customize_grub_config - Apply custom GRUB configuration"
|
||||
echo " set_grub_timeout - Set GRUB timeout value"
|
||||
echo " add_grub_menu_entry - Add custom GRUB menu entries"
|
||||
echo ""
|
||||
echo "Required variables:"
|
||||
echo " WORK_DIR - Working directory for operations"
|
||||
echo " loop_dev - Loop device for disk operations"
|
||||
}
|
||||
215
modules/chroot.sh
Normal file
215
modules/chroot.sh
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Chroot-based OSTree creation module for bootc image creation
|
||||
# This module implements the debian-ostree-builder approach using chroot
|
||||
|
||||
# Common functions are sourced by the main script
|
||||
|
||||
# Create chroot environment
|
||||
create_chroot_environment() {
|
||||
log_info "Creating chroot environment..."
|
||||
|
||||
# Create chroot directory
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
mkdir -p "$chroot_dir"
|
||||
|
||||
# Install debootstrap if not available
|
||||
if ! command -v debootstrap >/dev/null 2>&1; then
|
||||
log_info "Installing debootstrap..."
|
||||
sudo apt update
|
||||
sudo apt install -y debootstrap
|
||||
fi
|
||||
|
||||
# Create base Debian system
|
||||
log_info "Creating base Debian system with debootstrap..."
|
||||
sudo debootstrap --arch=amd64 --variant=minbase "$TARGET_DEBIAN_RELEASE" "$chroot_dir" http://deb.debian.org/debian/
|
||||
|
||||
# Mount necessary filesystems
|
||||
log_info "Mounting necessary filesystems..."
|
||||
sudo mount --bind /dev "$chroot_dir/dev"
|
||||
sudo mount --bind /proc "$chroot_dir/proc"
|
||||
sudo mount --bind /sys "$chroot_dir/sys"
|
||||
sudo mount --bind /dev/pts "$chroot_dir/dev/pts"
|
||||
|
||||
log_info "Chroot environment created at: $chroot_dir"
|
||||
}
|
||||
|
||||
# Install packages in chroot
|
||||
install_chroot_packages() {
|
||||
log_info "Installing packages in chroot..."
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
# Update package lists
|
||||
sudo chroot "$chroot_dir" apt update
|
||||
|
||||
# Install essential packages
|
||||
sudo chroot "$chroot_dir" apt install -y \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
linux-image-amd64 \
|
||||
linux-headers-amd64 \
|
||||
grub-pc \
|
||||
ostree \
|
||||
ostree-boot \
|
||||
network-manager \
|
||||
openssh-server \
|
||||
sudo \
|
||||
curl \
|
||||
wget \
|
||||
vim \
|
||||
less \
|
||||
man-db
|
||||
|
||||
# Clean up package cache
|
||||
sudo chroot "$chroot_dir" apt clean
|
||||
|
||||
log_info "Package installation completed"
|
||||
}
|
||||
|
||||
# Initialize OSTree repository in chroot
|
||||
init_ostree_repository() {
|
||||
log_info "Initializing OSTree repository in chroot..."
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
# Initialize OSTree repository
|
||||
sudo chroot "$chroot_dir" ostree init --repo=/ostree/repo --mode=bare-user
|
||||
|
||||
# Create stateroot for Debian
|
||||
sudo chroot "$chroot_dir" ostree admin init-fs /
|
||||
sudo chroot "$chroot_dir" ostree admin stateroot-init debian
|
||||
|
||||
log_info "OSTree repository initialized"
|
||||
}
|
||||
|
||||
# Create OSTree commit from chroot
|
||||
create_ostree_commit() {
|
||||
log_info "Creating OSTree commit from chroot..."
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
# Commit the current system state
|
||||
sudo chroot "$chroot_dir" ostree commit \
|
||||
--repo=/ostree/repo \
|
||||
--branch=debian/$TARGET_DEBIAN_RELEASE/x86_64 \
|
||||
--subject="Debian $TARGET_DEBIAN_RELEASE system" \
|
||||
--tree=dir=/
|
||||
|
||||
log_info "OSTree commit created"
|
||||
}
|
||||
|
||||
# Deploy OSTree system
|
||||
deploy_ostree_system() {
|
||||
log_info "Deploying OSTree system..."
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
# Deploy the commit
|
||||
sudo chroot "$chroot_dir" ostree admin deploy \
|
||||
--os=debian \
|
||||
--karg=console=tty0 \
|
||||
--karg=console=ttyS0,115200n8 \
|
||||
debian/$TARGET_DEBIAN_RELEASE/x86_64
|
||||
|
||||
log_info "OSTree system deployed"
|
||||
}
|
||||
|
||||
# Configure bootloader in chroot
|
||||
configure_chroot_bootloader() {
|
||||
log_info "Configuring bootloader in chroot..."
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
# Install GRUB
|
||||
sudo chroot "$chroot_dir" grub-install --target=i386-pc /dev/sda
|
||||
|
||||
# Generate GRUB configuration
|
||||
sudo chroot "$chroot_dir" grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
log_info "Bootloader configured"
|
||||
}
|
||||
|
||||
# Copy chroot filesystem to mounted partition
|
||||
copy_chroot_filesystem() {
|
||||
log_info "Copying chroot filesystem to mounted partition..."
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
# Copy the entire chroot filesystem
|
||||
sudo cp -r "$chroot_dir"/* "$WORK_DIR/mnt/"
|
||||
|
||||
# Create essential symlinks
|
||||
sudo ln -sf usr/bin "$WORK_DIR/mnt/bin"
|
||||
sudo ln -sf usr/lib "$WORK_DIR/mnt/lib"
|
||||
sudo ln -sf usr/sbin "$WORK_DIR/mnt/sbin"
|
||||
sudo ln -sf usr/lib64 "$WORK_DIR/mnt/lib64"
|
||||
|
||||
log_info "Chroot filesystem copied"
|
||||
}
|
||||
|
||||
# Cleanup chroot environment
|
||||
cleanup_chroot() {
|
||||
log_info "Cleaning up chroot environment..."
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
# Unmount filesystems
|
||||
sudo umount "$chroot_dir/dev/pts" 2>/dev/null || true
|
||||
sudo umount "$chroot_dir/sys" 2>/dev/null || true
|
||||
sudo umount "$chroot_dir/proc" 2>/dev/null || true
|
||||
sudo umount "$chroot_dir/dev" 2>/dev/null || true
|
||||
|
||||
# Remove chroot directory
|
||||
sudo rm -rf "$chroot_dir"
|
||||
|
||||
log_info "Chroot environment cleaned up"
|
||||
}
|
||||
|
||||
# Show chroot information
|
||||
show_chroot_info() {
|
||||
log_info "Chroot information:"
|
||||
|
||||
local chroot_dir="$WORK_DIR/chroot"
|
||||
|
||||
if [ -d "$chroot_dir" ]; then
|
||||
echo "Chroot directory: $chroot_dir"
|
||||
echo "Chroot size: $(du -sh "$chroot_dir" 2>/dev/null || echo 'Unknown')"
|
||||
|
||||
if [ -d "$chroot_dir/ostree" ]; then
|
||||
echo "OSTree repository: Found"
|
||||
echo "OSTree size: $(du -sh "$chroot_dir/ostree" 2>/dev/null || echo 'Unknown')"
|
||||
else
|
||||
echo "OSTree repository: Not found"
|
||||
fi
|
||||
|
||||
if [ -d "$chroot_dir/boot" ]; then
|
||||
echo "Boot directory: Found"
|
||||
echo "Kernel: $(ls "$chroot_dir/boot"/vmlinuz* 2>/dev/null || echo 'Not found')"
|
||||
else
|
||||
echo "Boot directory: Not found"
|
||||
fi
|
||||
else
|
||||
echo "Chroot directory: Not found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Print module usage
|
||||
print_module_usage() {
|
||||
echo "Usage: source modules/chroot.sh"
|
||||
echo "This module implements chroot-based OSTree creation."
|
||||
echo ""
|
||||
echo "Available functions:"
|
||||
echo " create_chroot_environment - Create chroot environment"
|
||||
echo " install_chroot_packages - Install packages in chroot"
|
||||
echo " init_ostree_repository - Initialize OSTree repository"
|
||||
echo " create_ostree_commit - Create OSTree commit"
|
||||
echo " deploy_ostree_system - Deploy OSTree system"
|
||||
echo " configure_chroot_bootloader - Configure bootloader"
|
||||
echo " copy_chroot_filesystem - Copy to mounted partition"
|
||||
echo " cleanup_chroot - Cleanup chroot environment"
|
||||
echo " show_chroot_info - Display chroot information"
|
||||
echo ""
|
||||
echo "Required variables:"
|
||||
echo " WORK_DIR - Working directory for operations"
|
||||
}
|
||||
183
modules/common.sh
Normal file
183
modules/common.sh
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Common functions and utilities for bootc image creation modules
|
||||
# This module provides shared functionality used across all other modules
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_debug() {
|
||||
echo -e "${BLUE}[DEBUG]${NC} $1"
|
||||
}
|
||||
|
||||
# Global variables (will be set by calling script)
|
||||
WORK_DIR=""
|
||||
loop_dev=""
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
if [ -n "$WORK_DIR" ] && [ -d "$WORK_DIR" ]; then
|
||||
log_info "Cleaning up work directory..."
|
||||
sudo umount "$WORK_DIR/mnt" 2>/dev/null || true
|
||||
sudo losetup -d "$loop_dev" 2>/dev/null || true
|
||||
sudo rm -rf "$WORK_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set trap for cleanup
|
||||
setup_cleanup() {
|
||||
trap cleanup EXIT INT TERM
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
log_info "Checking prerequisites..."
|
||||
|
||||
local required_commands=("podman" "qemu-img" "parted" "losetup" "mkfs.ext4" "grub-install" "grub-mkconfig")
|
||||
|
||||
for cmd in "${required_commands[@]}"; do
|
||||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||
log_error "Required command '$cmd' not found"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Check if container image exists
|
||||
if ! podman image exists "$CONTAINER_IMAGE"; then
|
||||
log_error "Container image '$CONTAINER_IMAGE' not found"
|
||||
log_info "Please build the image first with: podman build -t $CONTAINER_IMAGE -f debian_bootc_dockerfile.txt ."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All prerequisites satisfied"
|
||||
}
|
||||
|
||||
# Create output directory
|
||||
create_output_dir() {
|
||||
log_info "Creating output directory..."
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
}
|
||||
|
||||
# Create work directory
|
||||
create_work_dir() {
|
||||
WORK_DIR="./work-$$"
|
||||
log_info "Creating work directory: $WORK_DIR"
|
||||
mkdir -p "$WORK_DIR"
|
||||
}
|
||||
|
||||
# Validate configuration
|
||||
validate_config() {
|
||||
if [ -z "$CONTAINER_IMAGE" ]; then
|
||||
log_error "CONTAINER_IMAGE not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$OUTPUT_DIR" ]; then
|
||||
log_error "OUTPUT_DIR not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$IMAGE_SIZE_GB" ]; then
|
||||
log_error "IMAGE_SIZE_GB not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_debug "Configuration validated successfully"
|
||||
}
|
||||
|
||||
# Show progress
|
||||
show_progress() {
|
||||
local step="$1"
|
||||
local total="$2"
|
||||
local current="$3"
|
||||
|
||||
local percentage=$((current * 100 / total))
|
||||
local bar_length=30
|
||||
local filled=$((bar_length * current / total))
|
||||
local empty=$((bar_length - filled))
|
||||
|
||||
printf "\r["
|
||||
printf "%${filled}s" | tr ' ' '#'
|
||||
printf "%${empty}s" | tr ' ' '-'
|
||||
printf "] %d%% - %s" "$percentage" "$step"
|
||||
|
||||
if [ "$current" -eq "$total" ]; then
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
# Check disk space
|
||||
check_disk_space() {
|
||||
# Get the directory where the main script is located
|
||||
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
local required_space=$((IMAGE_SIZE_GB * 1024 * 1024 * 1024)) # Convert GB to bytes
|
||||
local available_space=$(df "$script_dir" | awk 'NR==2 {print $4}')
|
||||
|
||||
# Convert available space to GB for comparison
|
||||
local available_gb=$((available_space / 1024 / 1024 / 1024))
|
||||
|
||||
log_debug "Disk space check: Required: ${IMAGE_SIZE_GB}GB, Available: ${available_gb}GB"
|
||||
|
||||
if [ "$available_gb" -lt "$IMAGE_SIZE_GB" ]; then
|
||||
log_error "Insufficient disk space. Required: ${IMAGE_SIZE_GB}GB, Available: ${available_gb}GB"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_debug "Disk space check passed"
|
||||
}
|
||||
|
||||
# Wait for user confirmation
|
||||
confirm_action() {
|
||||
local message="$1"
|
||||
local default="${2:-n}"
|
||||
|
||||
if [ "$default" = "y" ]; then
|
||||
read -p "$message [Y/n]: " -r
|
||||
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
read -p "$message [y/N]: " -r
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Print module usage
|
||||
print_module_usage() {
|
||||
local module_name="$1"
|
||||
echo "Usage: source modules/$module_name.sh"
|
||||
echo "This module provides common functionality for bootc image creation."
|
||||
echo ""
|
||||
echo "Available functions:"
|
||||
echo " log_info, log_warn, log_error, log_debug - Logging functions"
|
||||
echo " cleanup, setup_cleanup - Cleanup management"
|
||||
echo " check_prerequisites - Validate system requirements"
|
||||
echo " create_output_dir, create_work_dir - Directory management"
|
||||
echo " validate_config - Configuration validation"
|
||||
echo " show_progress - Progress display"
|
||||
echo " check_disk_space - Disk space validation"
|
||||
echo " confirm_action - User confirmation prompts"
|
||||
}
|
||||
136
modules/disk.sh
Normal file
136
modules/disk.sh
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Disk management module for bootc image creation
|
||||
# This module handles disk image creation, partitioning, and filesystem setup
|
||||
|
||||
# Common functions are sourced by the main script
|
||||
|
||||
# Create and partition disk image
|
||||
create_disk_image_work() {
|
||||
log_info "Creating disk image..."
|
||||
|
||||
# Check disk space first (temporarily disabled for debugging)
|
||||
# check_disk_space
|
||||
|
||||
# Create raw image first to ensure proper sizing
|
||||
log_info "Creating raw image with size: ${IMAGE_SIZE_GB}GB"
|
||||
dd if=/dev/zero of="$OUTPUT_DIR/debian-bootc.raw" bs=1M count=$((IMAGE_SIZE_GB * 1024))
|
||||
|
||||
# Create loop device
|
||||
loop_dev=$(sudo losetup --find --show "$OUTPUT_DIR/debian-bootc.raw")
|
||||
log_info "Using loop device: $loop_dev"
|
||||
|
||||
# Export the loop device variable so other modules can use it
|
||||
export loop_dev
|
||||
|
||||
# Partition the disk with proper GPT layout including BIOS Boot Partition
|
||||
log_info "Partitioning disk..."
|
||||
sudo parted "$loop_dev" mklabel gpt
|
||||
# Create 1MB BIOS Boot Partition for GRUB
|
||||
sudo parted "$loop_dev" mkpart primary 1MiB 2MiB
|
||||
sudo parted "$loop_dev" set 1 bios_grub on
|
||||
# Create main system partition
|
||||
sudo parted "$loop_dev" mkpart primary ext4 2MiB 100%
|
||||
sudo parted "$loop_dev" set 2 boot on
|
||||
|
||||
# Verify partitions were created correctly
|
||||
log_info "Verifying partition layout..."
|
||||
sudo parted "$loop_dev" print
|
||||
|
||||
# Create filesystem on the main partition (partition 2)
|
||||
log_info "Creating filesystem..."
|
||||
sudo mkfs.ext4 "${loop_dev}p2"
|
||||
|
||||
# Mount the main partition (partition 2)
|
||||
log_info "Mounting partition..."
|
||||
mkdir -p "$WORK_DIR/mnt"
|
||||
sudo mount "${loop_dev}p2" "$WORK_DIR/mnt"
|
||||
|
||||
log_info "Device size: $(sudo blockdev --getsize64 $loop_dev) bytes"
|
||||
}
|
||||
|
||||
# Create essential directories
|
||||
create_essential_directories() {
|
||||
log_info "Creating essential directories..."
|
||||
|
||||
# Create essential directories individually
|
||||
sudo mkdir -p "$WORK_DIR/mnt/usr"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/etc"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/var"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/home"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/root"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/boot"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/proc"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/sys"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/dev"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/tmp"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/run"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/media"
|
||||
sudo mkdir -p "$WORK_DIR/mnt/mnt"
|
||||
|
||||
log_info "Essential directories created"
|
||||
}
|
||||
|
||||
# Unmount and cleanup disk
|
||||
cleanup_disk() {
|
||||
log_info "Cleaning up disk operations..."
|
||||
|
||||
if [ -n "$WORK_DIR" ] && [ -d "$WORK_DIR/mnt" ]; then
|
||||
sudo umount "$WORK_DIR/mnt" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -n "$loop_dev" ]; then
|
||||
sudo losetup -d "$loop_dev" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Get disk information
|
||||
get_disk_info() {
|
||||
if [ -n "$loop_dev" ]; then
|
||||
log_info "Disk information:"
|
||||
sudo parted "$loop_dev" print
|
||||
echo ""
|
||||
sudo fdisk -l "$loop_dev"
|
||||
else
|
||||
log_warn "No loop device available for disk info"
|
||||
fi
|
||||
}
|
||||
|
||||
# Verify disk integrity
|
||||
verify_disk_integrity() {
|
||||
log_info "Verifying disk integrity..."
|
||||
|
||||
if [ ! -f "$OUTPUT_DIR/debian-bootc.raw" ]; then
|
||||
log_error "Raw disk image not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local image_size=$(stat -c%s "$OUTPUT_DIR/debian-bootc.raw")
|
||||
local expected_size=$((IMAGE_SIZE_GB * 1024 * 1024 * 1024))
|
||||
|
||||
if [ "$image_size" -ne "$expected_size" ]; then
|
||||
log_error "Disk image size mismatch. Expected: $expected_size, Got: $image_size"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Disk integrity verified successfully"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Print module usage
|
||||
print_module_usage() {
|
||||
echo "Usage: source modules/disk.sh"
|
||||
echo "This module handles disk image creation and management."
|
||||
echo ""
|
||||
echo "Available functions:"
|
||||
echo " create_disk_image - Create and partition disk image"
|
||||
echo " create_essential_directories - Create required directory structure"
|
||||
echo " cleanup_disk - Unmount and cleanup disk operations"
|
||||
echo " get_disk_info - Display disk partition information"
|
||||
echo " verify_disk_integrity - Verify disk image integrity"
|
||||
echo ""
|
||||
echo "Required variables:"
|
||||
echo " OUTPUT_DIR - Output directory for images"
|
||||
echo " IMAGE_SIZE_GB - Image size in gigabytes"
|
||||
echo " WORK_DIR - Working directory for operations"
|
||||
}
|
||||
188
modules/filesystem.sh
Normal file
188
modules/filesystem.sh
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Filesystem management module for bootc image creation
|
||||
# This module handles container filesystem extraction and setup
|
||||
|
||||
# Common functions are sourced by the main script
|
||||
|
||||
# Extract container filesystem
|
||||
extract_container_filesystem() {
|
||||
log_info "Extracting container filesystem..."
|
||||
|
||||
# Change ownership to allow container to write
|
||||
log_info "Setting directory permissions..."
|
||||
sudo chown -R 1000:1000 "$WORK_DIR/mnt"
|
||||
|
||||
# Extract container filesystem directly
|
||||
log_info "Extracting container filesystem..."
|
||||
podman run --rm -v "$WORK_DIR/mnt:/extract" "$CONTAINER_IMAGE" \
|
||||
/bin/bash -c "
|
||||
cd /extract
|
||||
echo 'Starting filesystem extraction...'
|
||||
|
||||
# Copy the main system directories with verbose output
|
||||
echo 'Copying /usr...'
|
||||
cp -rv /usr . 2>&1 || echo 'Copy of /usr failed'
|
||||
|
||||
echo 'Copying /etc...'
|
||||
cp -rv /etc . 2>&1 || echo 'Copy of /etc failed'
|
||||
|
||||
echo 'Copying /var...'
|
||||
cp -rv /var . 2>&1 || echo 'Copy of /var failed'
|
||||
|
||||
echo 'Copying /home...'
|
||||
cp -rv /home . 2>&1 || echo 'Copy of /home failed'
|
||||
|
||||
echo 'Copying /root...'
|
||||
cp -rv /root . 2>&1 || echo 'Copy of /root failed'
|
||||
|
||||
echo 'Copying /boot...'
|
||||
cp -rv /boot . 2>&1 || echo 'Copy of /boot failed'
|
||||
|
||||
# Create symlinks for traditional compatibility (usr-merge structure)
|
||||
echo 'Creating symlinks for usr-merge compatibility...'
|
||||
if [ -d usr/bin ]; then
|
||||
ln -sf usr/bin bin
|
||||
echo 'Created bin -> usr/bin symlink'
|
||||
fi
|
||||
if [ -d usr/lib ]; then
|
||||
ln -sf usr/lib lib
|
||||
echo 'Created lib -> usr/lib symlink'
|
||||
fi
|
||||
if [ -d usr/lib64 ]; then
|
||||
ln -sf usr/lib64 lib64
|
||||
echo 'Created lib64 -> usr/lib64 symlink'
|
||||
fi
|
||||
if [ -d usr/sbin ]; then
|
||||
ln -sf usr/sbin sbin
|
||||
echo 'Created sbin -> usr/sbin symlink'
|
||||
fi
|
||||
|
||||
echo 'Filesystem extraction completed'
|
||||
echo 'Final directory listing:'
|
||||
ls -la
|
||||
echo 'Checking usr directory:'
|
||||
ls -la usr/
|
||||
echo 'Checking if critical directories exist:'
|
||||
[ -d usr/lib ] && echo 'usr/lib exists' || echo 'usr/lib MISSING'
|
||||
[ -d usr/sbin ] && echo 'usr/sbin exists' || echo 'usr/sbin MISSING'
|
||||
[ -d usr/bin ] && echo 'usr/bin exists' || echo 'usr/bin MISSING'
|
||||
echo 'Checking boot directory:'
|
||||
ls -la boot/
|
||||
"
|
||||
|
||||
# Restore proper ownership for the final image
|
||||
log_info "Restoring proper ownership..."
|
||||
sudo chown -R root:root "$WORK_DIR/mnt"
|
||||
|
||||
log_info "Filesystem extraction completed"
|
||||
}
|
||||
|
||||
# Fix file permissions
|
||||
fix_file_permissions() {
|
||||
log_info "Fixing critical file permissions..."
|
||||
|
||||
# Fix sudo permissions
|
||||
sudo chmod 4755 "$WORK_DIR/mnt/usr/bin/sudo" # Set setuid bit for sudo
|
||||
sudo chown root:root "$WORK_DIR/mnt/usr/bin/sudo" # Ensure sudo is owned by root
|
||||
|
||||
# Fix home directory permissions (use UID 1000 which is typically the first user)
|
||||
sudo chown -R 1000:1000 "$WORK_DIR/mnt/home/debian"
|
||||
sudo chmod 755 "$WORK_DIR/mnt/home/debian"
|
||||
|
||||
# Ensure critical system tools have proper permissions
|
||||
sudo chmod 755 "$WORK_DIR/mnt/usr/bin/ip" 2>/dev/null || echo "ip command not found"
|
||||
sudo chmod 755 "$WORK_DIR/mnt/usr/bin/ping" 2>/dev/null || echo "ping command not found"
|
||||
sudo chmod 755 "$WORK_DIR/mnt/bin/shutdown" 2>/dev/null || echo "shutdown command not found"
|
||||
sudo chmod 755 "$WORK_DIR/mnt/bin/halt" 2>/dev/null || echo "halt command not found"
|
||||
sudo chmod 755 "$WORK_DIR/mnt/bin/poweroff" 2>/dev/null || echo "poweroff command not found"
|
||||
|
||||
# Set proper permissions for system directories
|
||||
sudo chmod 1777 "$WORK_DIR/mnt/tmp"
|
||||
sudo chmod 755 "$WORK_DIR/mnt/proc" "$WORK_DIR/mnt/sys" "$WORK_DIR/mnt/dev" \
|
||||
"$WORK_DIR/mnt/run" "$WORK_DIR/mnt/media" "$WORK_DIR/mnt/mnt"
|
||||
|
||||
log_info "File permissions fixed"
|
||||
}
|
||||
|
||||
# Verify filesystem integrity
|
||||
verify_filesystem_integrity() {
|
||||
log_info "Verifying filesystem integrity..."
|
||||
|
||||
local critical_dirs=("usr" "etc" "var" "boot" "home")
|
||||
local missing_dirs=()
|
||||
|
||||
for dir in "${critical_dirs[@]}"; do
|
||||
if [ ! -d "$WORK_DIR/mnt/$dir" ]; then
|
||||
missing_dirs+=("$dir")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing_dirs[@]} -gt 0 ]; then
|
||||
log_error "Missing critical directories: ${missing_dirs[*]}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for critical symlinks
|
||||
local critical_symlinks=("bin" "lib" "sbin")
|
||||
local missing_symlinks=()
|
||||
|
||||
for symlink in "${critical_symlinks[@]}"; do
|
||||
if [ ! -L "$WORK_DIR/mnt/$symlink" ]; then
|
||||
missing_symlinks+=("$symlink")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing_symlinks[@]} -gt 0 ]; then
|
||||
log_error "Missing critical symlinks: ${missing_symlinks[*]}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for kernel and initrd
|
||||
if [ ! -f "$WORK_DIR/mnt/boot/vmlinuz-6.12.41+deb13-amd64" ]; then
|
||||
log_error "Kernel not found in expected location"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$WORK_DIR/mnt/boot/initrd.img-6.12.41+deb13-amd64" ]; then
|
||||
log_error "Initrd not found in expected location"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Filesystem integrity verified successfully"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Show filesystem statistics
|
||||
show_filesystem_stats() {
|
||||
log_info "Filesystem statistics:"
|
||||
|
||||
echo "Directory sizes:"
|
||||
du -sh "$WORK_DIR/mnt"/* 2>/dev/null | sort -hr
|
||||
|
||||
echo ""
|
||||
echo "File counts:"
|
||||
find "$WORK_DIR/mnt" -type f | wc -l | xargs echo "Total files:"
|
||||
find "$WORK_DIR/mnt" -type d | wc -l | xargs echo "Total directories:"
|
||||
find "$WORK_DIR/mnt" -type l | wc -l | xargs echo "Total symlinks:"
|
||||
|
||||
echo ""
|
||||
echo "Largest files:"
|
||||
find "$WORK_DIR/mnt" -type f -exec ls -lh {} + 2>/dev/null | sort -k5 -hr | head -10
|
||||
}
|
||||
|
||||
# Print module usage
|
||||
print_module_usage() {
|
||||
echo "Usage: source modules/filesystem.sh"
|
||||
echo "This module handles filesystem extraction and management."
|
||||
echo ""
|
||||
echo "Available functions:"
|
||||
echo " extract_container_filesystem - Extract container filesystem"
|
||||
echo " fix_file_permissions - Fix critical file permissions"
|
||||
echo " verify_filesystem_integrity - Verify filesystem integrity"
|
||||
echo " show_filesystem_stats - Display filesystem statistics"
|
||||
echo ""
|
||||
echo "Required variables:"
|
||||
echo " CONTAINER_IMAGE - Container image to extract from"
|
||||
echo " WORK_DIR - Working directory for operations"
|
||||
}
|
||||
171
modules/formats.sh
Normal file
171
modules/formats.sh
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Output format conversion module for bootc image creation
|
||||
# This module handles conversion to different output formats (QCOW2, ISO, IMG)
|
||||
|
||||
# Common functions are sourced by the main script
|
||||
|
||||
# Convert to QCOW2
|
||||
convert_to_qcow2() {
|
||||
log_info "Converting to QCOW2..."
|
||||
|
||||
# Unmount before conversion
|
||||
sudo umount "$WORK_DIR/mnt"
|
||||
|
||||
# Convert raw image to QCOW2
|
||||
qemu-img convert -f raw -O qcow2 "$OUTPUT_DIR/debian-bootc.raw" "$OUTPUT_DIR/debian-bootc.qcow2"
|
||||
|
||||
# Keep the raw image for VM use
|
||||
log_info "Raw image kept: $OUTPUT_DIR/debian-bootc.raw"
|
||||
log_info "QCOW2 image created: $OUTPUT_DIR/debian-bootc-simple.qcow2"
|
||||
|
||||
# Show final image info
|
||||
ls -lh "$OUTPUT_DIR/debian-bootc.qcow2"
|
||||
}
|
||||
|
||||
# Convert to ISO
|
||||
convert_to_iso() {
|
||||
log_info "Converting to ISO..."
|
||||
|
||||
# Unmount before conversion
|
||||
sudo umount "$WORK_DIR/mnt"
|
||||
|
||||
# Create temporary directory for ISO contents
|
||||
local iso_temp="$WORK_DIR/iso-temp"
|
||||
mkdir -p "$iso_temp"
|
||||
|
||||
# Copy filesystem to temporary directory
|
||||
log_info "Preparing ISO contents..."
|
||||
sudo cp -r "$WORK_DIR/mnt"/* "$iso_temp/"
|
||||
|
||||
# Create bootable ISO
|
||||
log_info "Creating bootable ISO..."
|
||||
genisoimage -o "$OUTPUT_DIR/debian-bootc.iso" \
|
||||
-b isolinux/isolinux.bin \
|
||||
-c isolinux/boot.cat \
|
||||
-no-emul-boot \
|
||||
-boot-load-size 4 \
|
||||
-boot-info-table \
|
||||
-r \
|
||||
-J \
|
||||
-v \
|
||||
"$iso_temp"
|
||||
|
||||
# Cleanup temporary directory
|
||||
sudo rm -rf "$iso_temp"
|
||||
|
||||
log_info "ISO image created: $OUTPUT_DIR/debian-bootc.iso"
|
||||
ls -lh "$OUTPUT_DIR/debian-bootc.iso"
|
||||
}
|
||||
|
||||
# Convert to IMG (raw format)
|
||||
convert_to_img() {
|
||||
log_info "Converting to IMG format..."
|
||||
|
||||
# Unmount before conversion
|
||||
sudo umount "$WORK_DIR/mnt"
|
||||
|
||||
# Copy raw image to IMG
|
||||
cp "$OUTPUT_DIR/debian-bootc.raw" "$OUTPUT_DIR/debian-bootc.img"
|
||||
|
||||
log_info "IMG image created: $OUTPUT_DIR/debian-bootc.img"
|
||||
ls -lh "$OUTPUT_DIR/debian-bootc.img"
|
||||
}
|
||||
|
||||
# Convert to VMDK (VMware format)
|
||||
convert_to_vmdk() {
|
||||
log_info "Converting to VMDK..."
|
||||
|
||||
# Unmount before conversion
|
||||
sudo umount "$WORK_DIR/mnt"
|
||||
|
||||
# Convert raw image to VMDK
|
||||
qemu-img convert -f raw -O vmdk "$OUTPUT_DIR/debian-bootc.raw" "$OUTPUT_DIR/debian-bootc.vmdk"
|
||||
|
||||
log_info "VMDK image created: $OUTPUT_DIR/debian-bootc.vmdk"
|
||||
ls -lh "$OUTPUT_DIR/debian-bootc.vmdk"
|
||||
}
|
||||
|
||||
# Convert to VDI (VirtualBox format)
|
||||
convert_to_vdi() {
|
||||
log_info "Converting to VDI..."
|
||||
|
||||
# Unmount before conversion
|
||||
sudo umount "$WORK_DIR/mnt"
|
||||
|
||||
# Convert raw image to VDI
|
||||
qemu-img convert -f raw -O vdi "$OUTPUT_DIR/debian-bootc.raw" "$OUTPUT_DIR/debian-bootc.vdi"
|
||||
|
||||
log_info "VDI image created: $OUTPUT_DIR/debian-bootc.vdi"
|
||||
ls -lh "$OUTPUT_DIR/debian-bootc.vdi"
|
||||
}
|
||||
|
||||
# Convert to multiple formats
|
||||
convert_to_all_formats() {
|
||||
log_info "Converting to all supported formats..."
|
||||
|
||||
# Unmount before conversion
|
||||
sudo umount "$WORK_DIR/mnt"
|
||||
|
||||
# Convert to all formats
|
||||
convert_to_qcow2
|
||||
convert_to_iso
|
||||
convert_to_img
|
||||
convert_to_vmdk
|
||||
convert_to_vdi
|
||||
|
||||
log_info "All format conversions completed!"
|
||||
|
||||
# Show all created images
|
||||
echo ""
|
||||
log_info "Created images:"
|
||||
ls -lh "$OUTPUT_DIR"/debian-bootc.*
|
||||
}
|
||||
|
||||
# Show format information
|
||||
show_format_info() {
|
||||
log_info "Format information:"
|
||||
|
||||
if [ -f "$OUTPUT_DIR/debian-bootc.raw" ]; then
|
||||
echo "Raw image: $(ls -lh "$OUTPUT_DIR/debian-bootc.raw")"
|
||||
fi
|
||||
|
||||
if [ -f "$OUTPUT_DIR/debian-bootc.qcow2" ]; then
|
||||
echo "QCOW2 image: $(ls -lh "$OUTPUT_DIR/debian-bootc.qcow2")"
|
||||
fi
|
||||
|
||||
if [ -f "$OUTPUT_DIR/debian-bootc.iso" ]; then
|
||||
echo "ISO image: $(ls -lh "$OUTPUT_DIR/debian-bootc.iso")"
|
||||
fi
|
||||
|
||||
if [ -f "$OUTPUT_DIR/debian-bootc.img" ]; then
|
||||
echo "IMG image: $(ls -lh "$OUTPUT_DIR/debian-bootc.img")"
|
||||
fi
|
||||
|
||||
if [ -f "$OUTPUT_DIR/debian-bootc.vmdk" ]; then
|
||||
echo "VMDK image: $(ls -lh "$OUTPUT_DIR/debian-bootc.vmdk")"
|
||||
fi
|
||||
|
||||
if [ -f "$OUTPUT_DIR/debian-bootc.vdi" ]; then
|
||||
echo "VDI image: $(ls -lh "$OUTPUT_DIR/debian-bootc.vdi")"
|
||||
fi
|
||||
}
|
||||
|
||||
# Print module usage
|
||||
print_module_usage() {
|
||||
echo "Usage: source modules/formats.sh"
|
||||
echo "This module handles output format conversion."
|
||||
echo ""
|
||||
echo "Available functions:"
|
||||
echo " convert_to_qcow2 - Convert to QCOW2 format"
|
||||
echo " convert_to_iso - Convert to ISO format"
|
||||
echo " convert_to_img - Convert to IMG format"
|
||||
echo " convert_to_vmdk - Convert to VMDK format"
|
||||
echo " convert_to_vdi - Convert to VDI format"
|
||||
echo " convert_to_all_formats - Convert to all formats"
|
||||
echo " show_format_info - Display format information"
|
||||
echo ""
|
||||
echo "Required variables:"
|
||||
echo " OUTPUT_DIR - Output directory for images"
|
||||
echo " WORK_DIR - Working directory for operations"
|
||||
}
|
||||
74
setup-apt-cacher-ng.sh
Executable file
74
setup-apt-cacher-ng.sh
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
#!/bin/bash
|
||||
# setup-apt-cacher-ng.sh - Quick setup for apt-cacher-ng
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
log_info() {
|
||||
echo -e "\033[0;32m[INFO]\033[0m $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "\033[1;33m[WARN]\033[0m $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "\033[0;31m[ERROR]\033[0m $1"
|
||||
}
|
||||
|
||||
# Check if apt-cacher-ng is already running
|
||||
check_existing() {
|
||||
if curl -s --connect-timeout 5 "http://localhost:3142/acng-report.html" > /dev/null 2>&1; then
|
||||
log_info "apt-cacher-ng is already running at http://localhost:3142"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Install apt-cacher-ng
|
||||
install_apt_cacher_ng() {
|
||||
log_info "Installing apt-cacher-ng..."
|
||||
sudo apt update
|
||||
sudo apt install -y apt-cacher-ng
|
||||
|
||||
# Configure to allow all clients
|
||||
sudo sed -i 's/^#BindAddress: 127.0.0.1/BindAddress: 0.0.0.0/' /etc/apt-cacher-ng/acng.conf
|
||||
|
||||
# Start and enable service
|
||||
sudo systemctl enable apt-cacher-ng
|
||||
sudo systemctl start apt-cacher-ng
|
||||
|
||||
log_info "apt-cacher-ng installed and started"
|
||||
}
|
||||
|
||||
# Test the setup
|
||||
test_setup() {
|
||||
log_info "Testing apt-cacher-ng..."
|
||||
if curl -s --connect-timeout 5 "http://localhost:3142/acng-report.html" > /dev/null 2>&1; then
|
||||
log_info "✅ apt-cacher-ng is working!"
|
||||
log_info "Cache URL: http://localhost:3142"
|
||||
log_info "Status page: http://localhost:3142/acng-report.html"
|
||||
return 0
|
||||
else
|
||||
log_error "❌ apt-cacher-ng is not responding"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log_info "Setting up apt-cacher-ng for faster bootc builds..."
|
||||
|
||||
if check_existing; then
|
||||
log_info "apt-cacher-ng is already available"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
install_apt_cacher_ng
|
||||
test_setup
|
||||
|
||||
log_info "Setup complete! You can now use:"
|
||||
log_info " export APT_CACHER_NG_URL=http://localhost:3142"
|
||||
log_info " ./build-with-cache.sh"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
60
show-debian-releases.sh
Executable file
60
show-debian-releases.sh
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Script to demonstrate Debian release functionality
|
||||
# Shows available releases and current configuration
|
||||
|
||||
set -e
|
||||
|
||||
# Source configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/config/defaults.sh"
|
||||
|
||||
echo "=== Debian Release Information ==="
|
||||
echo ""
|
||||
|
||||
echo "Available Debian Releases:"
|
||||
echo " trixie - Debian 13 (Testing) - DEFAULT"
|
||||
echo " forky - Debian 14 (Unstable)"
|
||||
echo " sid - Debian Sid (Always Unstable)"
|
||||
echo ""
|
||||
|
||||
echo "Current Configuration:"
|
||||
echo " DEBIAN_RELEASE: $DEBIAN_RELEASE"
|
||||
echo " TARGET_DEBIAN_RELEASE: $TARGET_DEBIAN_RELEASE"
|
||||
echo " Description: $(get_debian_release_description "$DEBIAN_RELEASE")"
|
||||
echo ""
|
||||
|
||||
echo "OSTree Configuration:"
|
||||
echo " Branch: $OSTREE_BRANCH"
|
||||
echo " Subject: $OSTREE_SUBJECT"
|
||||
echo ""
|
||||
|
||||
echo "Usage Examples:"
|
||||
echo " # Use specific release"
|
||||
echo " DEBIAN_RELEASE=forky ./create-bootc-image.sh -t chroot -f qcow2"
|
||||
echo " DEBIAN_RELEASE=sid ./create-bootc-image.sh -t chroot -f qcow2"
|
||||
echo ""
|
||||
echo " # Use justfile with specific release"
|
||||
echo " just qcow2-chroot-release forky"
|
||||
echo " just qcow2-chroot-release sid"
|
||||
echo " just custom-chroot-release 20 iso trixie"
|
||||
echo ""
|
||||
echo " # Check available releases"
|
||||
echo " just releases"
|
||||
echo ""
|
||||
|
||||
echo "Environment Variable Override:"
|
||||
echo " export DEBIAN_RELEASE=forky"
|
||||
echo " export DEBIAN_RELEASE=sid"
|
||||
echo " ./create-bootc-image.sh -t chroot -f qcow2"
|
||||
echo ""
|
||||
|
||||
echo "Validation:"
|
||||
if validate_debian_release "$DEBIAN_RELEASE"; then
|
||||
echo " ✓ Current release '$DEBIAN_RELEASE' is valid"
|
||||
else
|
||||
echo " ✗ Current release '$DEBIAN_RELEASE' is invalid"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== End of Information ==="
|
||||
48
test-bootc-container.sh
Executable file
48
test-bootc-container.sh
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "=== Testing Debian Bootc Container Components ==="
|
||||
|
||||
# Test basic commands
|
||||
echo "1. Testing basic commands:"
|
||||
podman run --rm localhost/debian-bootc:latest /bin/bash -c "
|
||||
echo 'bootc version:' && bootc --version
|
||||
echo 'ostree version:' && ostree --version
|
||||
echo 'grub version:' && grub-install --version
|
||||
echo 'kernel version:' && uname -r
|
||||
"
|
||||
|
||||
echo -e "\n2. Testing OSTree functionality:"
|
||||
podman run --rm -v /tmp:/tmp localhost/debian-bootc:latest /bin/bash -c "
|
||||
cd /tmp
|
||||
mkdir -p test-ostree
|
||||
ostree admin init-fs /tmp/test-ostree
|
||||
echo 'OSTree init successful'
|
||||
ls -la /tmp/test-ostree/
|
||||
"
|
||||
|
||||
echo -e "\n3. Testing bootc functionality:"
|
||||
podman run --rm localhost/debian-bootc:latest /bin/bash -c "
|
||||
echo 'Testing bootc commands:'
|
||||
bootc --help | head -5
|
||||
"
|
||||
|
||||
echo -e "\n4. Testing systemd-boot components:"
|
||||
podman run --rm localhost/debian-bootc:latest /bin/bash -c "
|
||||
echo 'systemd-boot files:'
|
||||
ls -la /usr/lib/systemd/boot/
|
||||
echo 'systemd-boot packages:'
|
||||
dpkg -l | grep systemd-boot
|
||||
"
|
||||
|
||||
echo -e "\n5. Testing GRUB components:"
|
||||
podman run --rm localhost/debian-bootc:latest /bin/bash -c "
|
||||
echo 'GRUB files:'
|
||||
ls -la /usr/lib/grub/
|
||||
echo 'GRUB packages:'
|
||||
dpkg -l | grep grub
|
||||
"
|
||||
|
||||
echo -e "\n=== Container Test Complete ==="
|
||||
echo "If all tests passed, the container should be capable of creating bootable images."
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue