#!/bin/bash # Integration script between apt-ostree and deb-bootc-image-builder # Creates complete Debian Atomic pipeline: treefile → apt-ostree → bootable image set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration WORKSPACE_PATH="/home/rob/Documents/Projects/overseer" APT_OSTREE_PATH="$WORKSPACE_PATH/apt-ostree" DEB_BOOTC_PATH="$WORKSPACE_PATH/deb-bootc-image-builder" ATOMIC_CONFIGS_PATH="$WORKSPACE_PATH/debian-atomic-configs" TEMP_DIR=$(mktemp -d ./debian-atomic-bootable-XXXXXX) # Functions log_info() { echo -e "${BLUE}ℹ️ $1${NC}" } log_success() { echo -e "${GREEN}✅ $1${NC}" } log_warning() { echo -e "${YELLOW}⚠️ $1${NC}" } log_error() { echo -e "${RED}❌ $1${NC}" } cleanup() { log_info "Cleaning up temporary files..." if [[ -d "$TEMP_DIR" ]]; then rm -rf "$TEMP_DIR" fi } # Set up cleanup on exit (disabled for debugging) # trap cleanup EXIT # Validate paths validate_paths() { log_info "Validating required components..." local missing_paths=() [[ ! -d "$APT_OSTREE_PATH" ]] && missing_paths+=("apt-ostree") [[ ! -d "$DEB_BOOTC_PATH" ]] && missing_paths+=("deb-bootc-image-builder") [[ ! -d "$ATOMIC_CONFIGS_PATH" ]] && missing_paths+=("debian-atomic-configs") if [[ ${#missing_paths[@]} -gt 0 ]]; then log_error "Missing required components: ${missing_paths[*]}" exit 1 fi log_success "All required components found" } # Step 1: Create OSTree commit using apt-ostree in container create_ostree_commit() { local treefile="$1" local treefile_name=$(basename "$treefile") log_info "Step 1: Creating OSTree commit from $treefile_name" # Run apt-ostree in the container to create the OSTree commit log_info "Running apt-ostree compose tree in Debian container..." local output local exit_code output=$(podman run --rm --privileged \ -v "$APT_OSTREE_PATH:/workspace:z" \ -v "$ATOMIC_CONFIGS_PATH:/configs:z" \ -v "$TEMP_DIR:/shared:z" \ -v "$DEB_BOOTC_PATH:/shared/deb-bootc:z" \ apt-ostree-builder:latest \ bash -c "cd /workspace && ./target/release/apt-ostree compose tree /configs/treefiles/$treefile_name --workdir /shared/apt-ostree-build" 2>&1) exit_code=$? log_info "Command completed with exit code: $exit_code" if [[ $exit_code -ne 0 ]]; then log_error "apt-ostree failed with exit code $exit_code" log_error "Output: $output" return 1 fi log_success "OSTree commit created successfully" # Extract the commit hash from the output local commit_hash=$(echo "$output" | grep "Commit hash:" | tail -1 | awk '{print $3}') if [[ -z "$commit_hash" ]]; then log_error "Could not extract commit hash from output" return 1 fi log_info "Commit hash: $commit_hash" echo "$commit_hash" } # Step 2: Create bootable image from OSTree commit create_bootable_image() { local commit_hash="$1" log_info "Step 2: Creating bootable image from OSTree commit" # Run the entire step 2 process inside the container where all tools are available log_info "Running bootable image creation in Debian container..." local output local exit_code output=$(podman run --rm --privileged \ -v "$APT_OSTREE_PATH:/workspace:z" \ -v "$ATOMIC_CONFIGS_PATH:/configs:z" \ -v "$TEMP_DIR:/shared:z" \ -v "$DEB_BOOTC_PATH:/shared/deb-bootc:z" \ apt-ostree-builder:latest \ bash -c " cd /workspace echo 'Checking repository at /shared/apt-ostree-build/repo' ls -la /shared/apt-ostree-build/ if [[ -d /shared/apt-ostree-build/repo ]]; then echo 'Repository found, extracting rootfs...' ostree checkout --repo=/shared/apt-ostree-build/repo --subpath=/ '$commit_hash' /shared/rootfs if [[ \$? -eq 0 ]]; then echo 'Rootfs extracted successfully' ls -la /shared/rootfs/ if [[ -d /shared/rootfs/usr ]] && [[ -d /shared/rootfs/etc ]]; then echo 'Rootfs structure verified' echo 'Creating bootable image using deb-bootc-image-builder...' echo 'Checking if binary exists...' ls -la /shared/deb-bootc/bib/ if [[ -f /shared/deb-bootc/bib/create-ostree-bootable-image ]]; then echo 'Binary found, checking permissions...' ls -la /shared/deb-bootc/bib/create-ostree-bootable-image echo 'Running create-ostree-bootable-image...' # Use the existing create-ostree-bootable-image binary /shared/deb-bootc/bib/create-ostree-bootable-image /shared/rootfs /shared/debian-atomic-bootable.img echo 'Command completed with exit code: $?' else echo 'Binary not found!' exit 1 fi if [[ \$? -eq 0 ]]; then echo 'Bootable image created successfully' ls -la /shared/ exit 0 else echo 'Failed to create bootable image' exit 1 fi else echo 'Invalid rootfs structure' exit 1 fi else echo 'Failed to extract rootfs' exit 1 fi else echo 'Repository not found' exit 1 fi " 2>&1) exit_code=$? log_info "Container execution completed with exit code: $exit_code" log_info "Container output:" echo "$output" if [[ $exit_code -ne 0 ]]; then log_error "Failed to create bootable image in container" return 1 fi # Check if the image was created local output_image="$TEMP_DIR/debian-atomic-bootable.img" if [[ ! -f "$output_image" ]]; then log_error "Output image not found: $output_image" return 1 fi log_success "Bootable image created successfully" # Show image information local image_size=$(du -h "$output_image" | cut -f1) log_info "Image created: $output_image ($image_size)" echo "$output_image" } # Main pipeline function run_pipeline() { local treefile="$1" local variant="${2:-minimal}" log_info "🚀 Starting Debian Atomic Bootable Image Pipeline" log_info "Treefile: $treefile" log_info "Variant: $variant" log_info "Working directory: $TEMP_DIR" # Step 1: Create OSTree commit log_info "Executing Step 1: Create OSTree commit..." local commit_hash if ! commit_hash=$(create_ostree_commit "$treefile"); then log_error "Step 1 failed: Could not create OSTree commit" return 1 fi log_success "Step 1 completed: OSTree commit $commit_hash created" # Step 2: Create bootable image log_info "Executing Step 2: Create bootable image..." local output_image if ! output_image=$(create_bootable_image "$commit_hash"); then log_error "Step 2 failed: Could not create bootable image" return 1 fi log_success "Step 2 completed: Bootable image created" log_success "🎉 Pipeline completed successfully!" log_info "Output image: $output_image" # Copy image to workspace for easy access local final_image="$WORKSPACE_PATH/debian-atomic-$variant-bootable.img" cp "$output_image" "$final_image" log_info "Image copied to: $final_image" # Show testing instructions echo log_info "🧪 To test the bootable image:" echo "qemu-system-x86_64 -m 2G -drive file=$final_image,format=raw -nographic -serial stdio" echo log_info "📋 Summary:" log_success "✅ OSTree commit created from $treefile" log_success "✅ Bootable image created: $final_image" log_success "✅ Debian Atomic bootable image pipeline completed successfully!" return 0 } # Main function main() { if [[ $# -lt 1 ]]; then echo "Usage: $0 [variant]" echo "Example: $0 debian-minimal-apt-ostree.yaml minimal" echo echo "Available treefiles:" if [[ -d "$ATOMIC_CONFIGS_PATH/treefiles" ]]; then ls "$ATOMIC_CONFIGS_PATH/treefiles/"*.yaml 2>/dev/null | sed 's/.*\///' || echo "No treefiles found" fi exit 1 fi local treefile="$1" local variant="${2:-minimal}" # Validate and run the pipeline validate_paths # Run the pipeline if ! run_pipeline "$treefile" "$variant"; then log_error "Pipeline failed" exit 1 fi log_success "Pipeline completed successfully" } # Run main function main "$@"