Some checks failed
particle-os CI / Test particle-os (push) Failing after 1s
particle-os CI / Integration Test (push) Has been skipped
particle-os CI / Security & Quality (push) Failing after 1s
Test particle-os Basic Functionality / test-basic (push) Failing after 1s
particle-os CI / Build and Release (push) Has been skipped
278 lines
9.1 KiB
Bash
Executable file
278 lines
9.1 KiB
Bash
Executable file
#!/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 <treefile> [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 "$@"
|