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
431 lines
10 KiB
Bash
431 lines
10 KiB
Bash
#!/bin/bash
|
|
# Debian Image Builder Script
|
|
# This script demonstrates the complete Debian image building pipeline
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[0;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
OUTPUT_DIR="${PROJECT_ROOT}/output"
|
|
BUILD_DIR="${PROJECT_ROOT}/build"
|
|
MANIFEST_DIR="${BUILD_DIR}/manifests"
|
|
|
|
# Default values
|
|
RELEASE="trixie"
|
|
ARCH="amd64"
|
|
IMAGE_TYPE="qcow2"
|
|
VERBOSE=false
|
|
CLEAN=false
|
|
|
|
# Function to print colored output
|
|
print_status() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Function to show usage
|
|
show_usage() {
|
|
cat << EOF
|
|
Usage: $0 [OPTIONS]
|
|
|
|
Build a Debian image using the debian-bootc-image-builder pipeline.
|
|
|
|
OPTIONS:
|
|
-r, --release RELEASE Debian release (default: trixie)
|
|
-a, --arch ARCH Architecture (default: amd64)
|
|
-t, --type TYPE Image type: qcow2, desktop, server, development (default: qcow2)
|
|
-o, --output DIR Output directory (default: ./output)
|
|
-v, --verbose Enable verbose output
|
|
-c, --clean Clean build directory before building
|
|
-h, --help Show this help message
|
|
|
|
EXAMPLES:
|
|
$0 --type desktop --release trixie
|
|
$0 --type server --arch amd64 --verbose
|
|
$0 --type development --clean
|
|
|
|
EOF
|
|
}
|
|
|
|
# Function to parse command line arguments
|
|
parse_args() {
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-r|--release)
|
|
RELEASE="$2"
|
|
shift 2
|
|
;;
|
|
-a|--arch)
|
|
ARCH="$2"
|
|
shift 2
|
|
;;
|
|
-t|--type)
|
|
IMAGE_TYPE="$2"
|
|
shift 2
|
|
;;
|
|
-o|--output)
|
|
OUTPUT_DIR="$2"
|
|
shift 2
|
|
;;
|
|
-v|--verbose)
|
|
VERBOSE=true
|
|
shift
|
|
;;
|
|
-c|--clean)
|
|
CLEAN=true
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
show_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_error "Unknown option: $1"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Function to validate inputs
|
|
validate_inputs() {
|
|
print_status "Validating inputs..."
|
|
|
|
# Validate release
|
|
case "$RELEASE" in
|
|
trixie|bookworm|bullseye)
|
|
;;
|
|
*)
|
|
print_error "Unsupported release: $RELEASE"
|
|
print_error "Supported releases: trixie, bookworm, bullseye"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Validate architecture
|
|
case "$ARCH" in
|
|
amd64|arm64|i386)
|
|
;;
|
|
*)
|
|
print_error "Unsupported architecture: $ARCH"
|
|
print_error "Supported architectures: amd64, arm64, i386"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Validate image type
|
|
case "$IMAGE_TYPE" in
|
|
qcow2|desktop|server|development)
|
|
;;
|
|
*)
|
|
print_error "Unsupported image type: $IMAGE_TYPE"
|
|
print_error "Supported types: qcow2, desktop, server, development"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
print_success "Input validation passed"
|
|
}
|
|
|
|
# Function to setup build environment
|
|
setup_build_env() {
|
|
print_status "Setting up build environment..."
|
|
|
|
# Create directories
|
|
mkdir -p "$OUTPUT_DIR"
|
|
mkdir -p "$BUILD_DIR"
|
|
mkdir -p "$MANIFEST_DIR"
|
|
|
|
if [[ "$CLEAN" == true ]]; then
|
|
print_status "Cleaning build directory..."
|
|
rm -rf "$BUILD_DIR"/*
|
|
mkdir -p "$MANIFEST_DIR"
|
|
fi
|
|
|
|
print_success "Build environment ready"
|
|
}
|
|
|
|
# Function to run tests
|
|
run_tests() {
|
|
print_status "Running tests..."
|
|
|
|
cd "$PROJECT_ROOT"
|
|
|
|
# Run unit tests
|
|
print_status "Running unit tests..."
|
|
if make test-unit > /dev/null 2>&1; then
|
|
print_success "Unit tests passed"
|
|
else
|
|
print_error "Unit tests failed"
|
|
exit 1
|
|
fi
|
|
|
|
# Run integration tests
|
|
print_status "Running integration tests..."
|
|
if make test-integration > /dev/null 2>&1; then
|
|
print_success "Integration tests passed"
|
|
else
|
|
print_error "Integration tests failed"
|
|
exit 1
|
|
fi
|
|
|
|
print_success "All tests passed"
|
|
}
|
|
|
|
# Function to generate manifest
|
|
generate_manifest() {
|
|
print_status "Generating osbuild manifest for $IMAGE_TYPE image..."
|
|
|
|
local manifest_file="$MANIFEST_DIR/debian-${RELEASE}-${IMAGE_TYPE}.json"
|
|
|
|
# Create a simple manifest for demonstration
|
|
cat > "$manifest_file" << EOF
|
|
{
|
|
"version": "2",
|
|
"stages": [
|
|
{
|
|
"type": "org.osbuild.debian-filesystem",
|
|
"options": {
|
|
"rootfs_type": "ext4",
|
|
"ostree_integration": true,
|
|
"home_symlink": true
|
|
}
|
|
},
|
|
{
|
|
"type": "org.osbuild.apt",
|
|
"options": {
|
|
"packages": [
|
|
"linux-image-${ARCH}",
|
|
"systemd",
|
|
"initramfs-tools",
|
|
"grub-efi-${ARCH}",
|
|
"ostree"
|
|
],
|
|
"release": "${RELEASE}",
|
|
"arch": "${ARCH}",
|
|
"repos": [
|
|
{
|
|
"name": "debian",
|
|
"url": "http://deb.debian.org/debian",
|
|
"suite": "${RELEASE}",
|
|
"components": ["main", "contrib", "non-free"]
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"type": "org.osbuild.debian-kernel",
|
|
"options": {
|
|
"kernel_package": "linux-image-${ARCH}",
|
|
"initramfs_tools": true,
|
|
"ostree_integration": true,
|
|
"modules_autoload": true
|
|
}
|
|
},
|
|
{
|
|
"type": "org.osbuild.debian-grub",
|
|
"options": {
|
|
"ostree_integration": true,
|
|
"uefi": true,
|
|
"secure_boot": false,
|
|
"timeout": 5,
|
|
"default_entry": 0
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Add image-specific stages
|
|
case "$IMAGE_TYPE" in
|
|
desktop)
|
|
cat >> "$manifest_file" << EOF
|
|
,
|
|
{
|
|
"type": "org.osbuild.debian-desktop-config",
|
|
"options": {
|
|
"desktop_environment": "kde",
|
|
"display_manager": "sddm",
|
|
"user_sessions": true,
|
|
"applications": true,
|
|
"theme": "breeze"
|
|
}
|
|
}
|
|
EOF
|
|
;;
|
|
server)
|
|
cat >> "$manifest_file" << EOF
|
|
,
|
|
{
|
|
"type": "org.osbuild.debian-server-config",
|
|
"options": {
|
|
"security_hardening": true,
|
|
"firewall": "ufw",
|
|
"ssh": {
|
|
"port": 22,
|
|
"root_login": false,
|
|
"key_auth_only": false
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
;;
|
|
development)
|
|
cat >> "$manifest_file" << EOF
|
|
,
|
|
{
|
|
"type": "org.osbuild.debian-desktop-config",
|
|
"options": {
|
|
"desktop_environment": "kde",
|
|
"display_manager": "sddm",
|
|
"user_sessions": true,
|
|
"applications": true,
|
|
"theme": "breeze"
|
|
}
|
|
},
|
|
{
|
|
"type": "org.osbuild.debian-development-config",
|
|
"options": {
|
|
"development_tools": true,
|
|
"container_runtime": "docker",
|
|
"dev_user": "debian"
|
|
}
|
|
}
|
|
EOF
|
|
;;
|
|
esac
|
|
|
|
# Close the manifest
|
|
cat >> "$manifest_file" << EOF
|
|
],
|
|
"assembler": {
|
|
"type": "org.osbuild.qcow2",
|
|
"options": {
|
|
"filename": "debian-${RELEASE}-${IMAGE_TYPE}.qcow2"
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
|
|
print_success "Manifest generated: $manifest_file"
|
|
|
|
if [[ "$VERBOSE" == true ]]; then
|
|
print_status "Manifest contents:"
|
|
cat "$manifest_file" | jq '.' 2>/dev/null || cat "$manifest_file"
|
|
fi
|
|
}
|
|
|
|
# Function to simulate osbuild execution
|
|
simulate_osbuild() {
|
|
print_status "Simulating osbuild execution..."
|
|
|
|
local manifest_file="$MANIFEST_DIR/debian-${RELEASE}-${IMAGE_TYPE}.json"
|
|
local output_file="$OUTPUT_DIR/debian-${RELEASE}-${IMAGE_TYPE}.qcow2"
|
|
|
|
# Create a mock output file
|
|
print_status "Creating mock QCOW2 image..."
|
|
dd if=/dev/zero of="$output_file" bs=1M count=100 2>/dev/null || {
|
|
# Fallback if dd fails
|
|
print_warning "dd failed, creating empty file"
|
|
touch "$output_file"
|
|
}
|
|
|
|
print_success "Mock image created: $output_file"
|
|
|
|
# Show image info
|
|
if command -v qemu-img >/dev/null 2>&1; then
|
|
print_status "Image information:"
|
|
qemu-img info "$output_file" 2>/dev/null || print_warning "qemu-img not available"
|
|
fi
|
|
}
|
|
|
|
# Function to run validation
|
|
run_validation() {
|
|
print_status "Running validation..."
|
|
|
|
local output_file="$OUTPUT_DIR/debian-${RELEASE}-${IMAGE_TYPE}.qcow2"
|
|
|
|
# Check if output file exists
|
|
if [[ ! -f "$output_file" ]]; then
|
|
print_error "Output file not found: $output_file"
|
|
exit 1
|
|
fi
|
|
|
|
# Check file size
|
|
local file_size=$(stat -c%s "$output_file" 2>/dev/null || stat -f%z "$output_file" 2>/dev/null || echo "0")
|
|
if [[ "$file_size" -gt 0 ]]; then
|
|
print_success "Output file size: $file_size bytes"
|
|
else
|
|
print_warning "Output file is empty (this is expected for mock builds)"
|
|
fi
|
|
|
|
print_success "Validation completed"
|
|
}
|
|
|
|
# Function to show build summary
|
|
show_summary() {
|
|
print_status "Build Summary"
|
|
echo "=================="
|
|
echo "Release: $RELEASE"
|
|
echo "Architecture: $ARCH"
|
|
echo "Image Type: $IMAGE_TYPE"
|
|
echo "Output Directory: $OUTPUT_DIR"
|
|
echo "Build Directory: $BUILD_DIR"
|
|
echo ""
|
|
echo "Generated Files:"
|
|
echo "- Manifest: $MANIFEST_DIR/debian-${RELEASE}-${IMAGE_TYPE}.json"
|
|
echo "- Image: $OUTPUT_DIR/debian-${RELEASE}-${IMAGE_TYPE}.qcow2"
|
|
echo ""
|
|
print_success "Build completed successfully!"
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
print_status "Starting Debian image build..."
|
|
print_status "Project root: $PROJECT_ROOT"
|
|
|
|
# Parse arguments
|
|
parse_args "$@"
|
|
|
|
# Validate inputs
|
|
validate_inputs
|
|
|
|
# Setup build environment
|
|
setup_build_env
|
|
|
|
# Run tests
|
|
run_tests
|
|
|
|
# Generate manifest
|
|
generate_manifest
|
|
|
|
# Simulate osbuild execution
|
|
simulate_osbuild
|
|
|
|
# Run validation
|
|
run_validation
|
|
|
|
# Show summary
|
|
show_summary
|
|
}
|
|
|
|
# Run main function with all arguments
|
|
main "$@"
|