particle-os/scripts/test-bootc-deployment.sh
robojerk f9fb8d3bd0 Fix critical PATH issues and add related projects to README
- Fixed sfdisk PATH issue in Containerfile.base (sfdisk is in /usr/sbin)
- Updated Containerfile.minimal to use full path for grub-install
- Enhanced test-bootc-deployment.sh to properly check utility locations
- Added comprehensive section about related projects (apt-ostree, deb-bootupd, debian-bootc-corrected)
- Updated validation script to handle Debian-specific utility locations
- Improved error messages with specific solutions for PATH and utility issues

This addresses the critical requirements from scope.md regarding disk utilities
and PATH environment variables for bootc deployment.
2025-08-10 18:15:04 -07:00

342 lines
11 KiB
Bash
Executable file

#!/bin/bash
# Particle-OS Bootc Deployment Test Script
# Tests all critical requirements identified in scope.md
set -e
echo "🔍 Particle-OS Bootc Deployment Validation"
echo "=========================================="
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
local status=$1
local message=$2
if [ "$status" = "PASS" ]; then
echo -e "${GREEN}✅ PASS${NC}: $message"
elif [ "$status" = "FAIL" ]; then
echo -e "${RED}❌ FAIL${NC}: $message"
else
echo -e "${YELLOW}⚠️ WARN${NC}: $message"
fi
}
# Function to check if command exists and is working
check_command() {
local cmd=$1
local description=$2
local required=$3
if command -v "$cmd" >/dev/null 2>&1; then
# Handle commands that don't support --version or -V
if [ "$cmd" = "mkfs.fat" ]; then
if "$cmd" --help >/dev/null 2>&1; then
print_status "PASS" "$description: $cmd is available and working"
return 0
else
print_status "FAIL" "$description: $cmd exists but not working properly"
return 1
fi
elif "$cmd" --version >/dev/null 2>&1 || "$cmd" -V >/dev/null 2>&1; then
print_status "PASS" "$description: $cmd is available and working"
return 0
else
print_status "FAIL" "$description: $cmd exists but not working properly"
return 1
fi
else
if [ "$required" = "true" ]; then
print_status "FAIL" "$description: $cmd is missing (REQUIRED)"
return 1
else
print_status "WARN" "$description: $cmd is missing (optional)"
return 0
fi
fi
}
# Function to check PATH environment
check_path() {
echo -e "\n🔍 Checking PATH environment..."
echo "Current PATH: $PATH"
# Check if critical directories are in PATH
if [[ ":$PATH:" == *":/usr/sbin:"* ]] && [[ ":$PATH:" == *":/sbin:"* ]]; then
print_status "PASS" "PATH includes /usr/sbin and /sbin"
else
print_status "FAIL" "PATH missing /usr/sbin or /sbin (CRITICAL for bootc)"
echo "Fixing PATH..."
export PATH="/usr/sbin:/sbin:$PATH"
echo "Updated PATH: $PATH"
fi
# Check if critical utilities are accessible via PATH
echo -e "\n🔍 Checking utility accessibility via PATH..."
if command -v sfdisk >/dev/null 2>&1; then
print_status "PASS" "sfdisk accessible via PATH"
else
print_status "FAIL" "sfdisk not accessible via PATH (should be in /usr/sbin)"
echo "Checking if sfdisk exists in /usr/sbin..."
if [ -x "/usr/sbin/sfdisk" ]; then
print_status "PASS" "sfdisk exists in /usr/sbin but not in PATH"
else
print_status "FAIL" "sfdisk missing from /usr/sbin"
fi
fi
}
# Function to check disk utilities (CRITICAL from scope.md)
check_disk_utilities() {
echo -e "\n🔧 Checking disk utilities (CRITICAL for bootc deployment)..."
local all_passed=true
# Check required disk utilities with explicit path checking
echo -e "\n🔍 Checking disk utilities in their correct locations..."
# Check sfdisk (critical - should be in /usr/sbin)
if [ -x "/usr/sbin/sfdisk" ]; then
if /usr/sbin/sfdisk --version >/dev/null 2>&1; then
print_status "PASS" "sfdisk available in /usr/sbin and working"
else
print_status "FAIL" "sfdisk in /usr/sbin but not working properly"
all_passed=false
fi
else
print_status "FAIL" "sfdisk missing from /usr/sbin (CRITICAL)"
all_passed=false
fi
# Check other utilities
check_command "parted" "Alternative partitioning tool" "true" || all_passed=false
check_command "mkfs.ext4" "Ext4 filesystem creation" "true" || all_passed=false
check_command "mkfs.fat" "FAT filesystem creation" "true" || all_passed=false
# Check for GRUB installation (handle different names and locations)
if [ -x "/usr/sbin/grub-install" ]; then
if /usr/sbin/grub-install --version >/dev/null 2>&1; then
print_status "PASS" "grub-install available in /usr/sbin and working"
else
print_status "FAIL" "grub-install in /usr/sbin but not working properly"
all_passed=false
fi
elif [ -x "/usr/bin/grub-install" ]; then
if /usr/bin/grub-install --version >/dev/null 2>&1; then
print_status "PASS" "grub-install available in /usr/bin and working"
else
print_status "FAIL" "grub-install in /usr/bin but not working properly"
all_passed=false
fi
elif command -v "grub2-install" >/dev/null 2>&1; then
check_command "grub2-install" "GRUB2 bootloader installation" "true" || all_passed=false
else
print_status "FAIL" "GRUB bootloader installation: neither grub-install nor grub2-install found (REQUIRED)"
all_passed=false
fi
check_command "efibootmgr" "UEFI boot manager" "true" || all_passed=false
# Check additional utilities
check_command "fdisk" "Disk partitioning utility" "false"
check_command "gdisk" "GPT partitioning utility" "false"
if [ "$all_passed" = "false" ]; then
echo -e "\n${RED}❌ CRITICAL: Some required disk utilities are missing!${NC}"
echo "This will prevent bootc from deploying successfully."
echo ""
echo "Common solutions:"
echo "1. Install missing packages: apt install util-linux parted e2fsprogs dosfstools grub-efi-amd64 efibootmgr"
echo "2. Fix PATH: export PATH=\"/usr/sbin:/sbin:\$PATH\""
echo "3. Check utility locations: ls -la /usr/sbin/sfdisk /usr/sbin/grub-install"
return 1
fi
print_status "PASS" "All critical disk utilities are available"
return 0
}
# Function to check bootc functionality
check_bootc() {
echo -e "\n🚀 Checking bootc functionality..."
if command -v bootc >/dev/null 2>&1; then
local version=$(bootc --version 2>/dev/null || echo "unknown")
print_status "PASS" "bootc is available: $version"
# Test basic bootc commands
if bootc --help >/dev/null 2>&1; then
print_status "PASS" "bootc --help works correctly"
else
print_status "FAIL" "bootc --help failed"
return 1
fi
else
print_status "FAIL" "bootc is not available (CRITICAL)"
return 1
fi
return 0
}
# Function to check OSTree functionality
check_ostree() {
echo -e "\n🌳 Checking OSTree functionality..."
if command -v ostree >/dev/null 2>&1; then
local version=$(ostree --version 2>/dev/null || echo "unknown")
print_status "PASS" "ostree is available: $version"
# Test basic ostree commands
if ostree --help >/dev/null 2>&1; then
print_status "PASS" "ostree --help works correctly"
else
print_status "FAIL" "ostree --help failed"
return 1
fi
else
print_status "FAIL" "ostree is not available (CRITICAL)"
return 1
fi
return 0
}
# Function to check filesystem structure
check_filesystem_structure() {
echo -e "\n📁 Checking OSTree filesystem structure..."
local all_passed=true
# Check required directories
local required_dirs=(
"/ostree"
"/sysroot"
"/usr/lib/ostree-boot"
"/usr/lib/modules"
"/usr/lib/kernel"
"/etc/ostree"
"/var/lib/ostree"
"/var/home"
)
for dir in "${required_dirs[@]}"; do
if [ -d "$dir" ]; then
print_status "PASS" "Directory exists: $dir"
else
print_status "FAIL" "Directory missing: $dir"
all_passed=false
fi
done
# Check home symlink
if [ -L "/home" ] && [ "$(readlink /home)" = "../var/home" ]; then
print_status "PASS" "Home symlink correctly points to /var/home"
else
print_status "FAIL" "Home symlink incorrect or missing"
all_passed=false
fi
if [ "$all_passed" = "false" ]; then
return 1
fi
return 0
}
# Function to check container runtime
check_container_runtime() {
echo -e "\n🐳 Checking container runtime..."
if command -v podman >/dev/null 2>&1; then
local version=$(podman --version 2>/dev/null || echo "unknown")
print_status "PASS" "podman is available: $version"
# Test podman functionality
if podman --help >/dev/null 2>&1; then
print_status "PASS" "podman --help works correctly"
else
print_status "FAIL" "podman --help failed"
return 1
fi
else
print_status "FAIL" "podman is not available (CRITICAL)"
return 1
fi
return 0
}
# Function to run deployment test
test_deployment() {
echo -e "\n🧪 Testing bootc deployment capabilities..."
# Check if we're in a container
if [ -f /.dockerenv ] || grep -q docker /proc/1/cgroup 2>/dev/null; then
print_status "WARN" "Running in container - deployment test limited"
echo "Note: Full deployment test requires host system access"
return 0
fi
# Check if we have access to block devices
if [ -b /dev/sda ] || [ -b /dev/vda ]; then
print_status "PASS" "Block devices accessible for deployment testing"
else
print_status "WARN" "No block devices accessible for deployment testing"
fi
# Check if we have sufficient privileges
if [ "$(id -u)" -eq 0 ]; then
print_status "PASS" "Running with root privileges for deployment"
else
print_status "WARN" "Not running with root privileges - some tests may fail"
fi
}
# Main validation function
main() {
echo "Starting comprehensive validation..."
local exit_code=0
# Run all checks
check_path || exit_code=1
check_disk_utilities || exit_code=1
check_bootc || exit_code=1
check_ostree || exit_code=1
check_filesystem_structure || exit_code=1
check_container_runtime || exit_code=1
test_deployment || exit_code=1
# Summary
echo -e "\n📊 Validation Summary"
echo "===================="
if [ $exit_code -eq 0 ]; then
echo -e "${GREEN}🎉 All critical checks passed!${NC}"
echo "Your Particle-OS image is ready for bootc deployment."
echo ""
echo "Next steps:"
echo "1. Test image in VM: just test-image"
echo "2. Validate boot process"
echo "3. Test OSTree functionality"
else
echo -e "${RED}❌ Some critical checks failed!${NC}"
echo "Please fix the issues above before attempting deployment."
echo ""
echo "Common solutions:"
echo "1. Install missing packages: apt install util-linux parted e2fsprogs dosfstools"
echo "2. Fix PATH: export PATH=\"/usr/sbin:/sbin:\$PATH\""
echo "3. Ensure all Containerfile requirements are met"
fi
return $exit_code
}
# Run main function
main "$@"