diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3eb96ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,108 @@ +# ParticleOS Installer .gitignore + +# Build artifacts and output +build/ +output/ +*.iso +*.deb +*.squashfs +*.manifest +*.size + +# Temporary files +*.tmp +*.temp +*.cache +*.log +*.pid +*.lock + +# System files +.DS_Store +Thumbs.db +*~ + +# Editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Backup files +*.bak +*.backup +*.old + +# Test artifacts +test-*/ +test-*.deb +test-*.iso + +# Package manager files +*.dpkg-old +*.dpkg-dist +*.dpkg-new + +# Chroot and mount points +chroot/ +mnt/ +proc/ +sys/ +dev/ + +# OSTree repositories +ostree-repo/ +*.ostree + +# Boot artifacts +boot/ +initrd* +vmlinuz* + +# Network and SSL +*.pem +*.key +*.crt +*.csr + +# User-specific files +*.local +.env +.env.local + +# Documentation builds +docs/_build/ +site/ + +# Python (if any scripts use Python) +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python +env/ +venv/ +.venv/ + +# Node.js (if any web components) +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# IDE and editor specific +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db \ No newline at end of file diff --git a/aurora-systems.yml b/aurora-systems.yml index d19e30a..81b7e66 100644 --- a/aurora-systems.yml +++ b/aurora-systems.yml @@ -66,13 +66,7 @@ packages: - fonts-noto - fonts-noto-cjk - # Additional applications - - firefox - - thunderbird - - libreoffice - - gimp - - vlc - - transmission-gtk + # Package exclusions (conflicts or unwanted packages) exclude: diff --git a/build-iso-mmdebstrap-hardened.sh b/build-iso-mmdebstrap-hardened.sh new file mode 100755 index 0000000..f36d353 --- /dev/null +++ b/build-iso-mmdebstrap-hardened.sh @@ -0,0 +1,553 @@ +#!/bin/bash + +# ParticleOS ISO Builder with mmdebstrap - HARDENED VERSION +# Builds a bootable ISO using mmdebstrap + apt-ostree integration +# Includes comprehensive error handling, safety checks, and hardening measures + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +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" +} + +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}================================${NC}" +} + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_NAME="particleos" +VERSION="1.0.0" +BUILD_DIR="$SCRIPT_DIR/build" +CHROOT_DIR="$BUILD_DIR/chroot" +ISO_DIR="$BUILD_DIR/iso" +OUTPUT_DIR="$SCRIPT_DIR/output" + +# Enhanced safety check: Ensure BUILD_DIR is within SCRIPT_DIR +if [[ ! "$BUILD_DIR" =~ ^"$SCRIPT_DIR" ]]; then + print_error "BUILD_DIR ($BUILD_DIR) is not within SCRIPT_DIR ($SCRIPT_DIR). Aborting for safety." + exit 1 +fi + +# Track mounted filesystems for cleanup +MOUNTED_FILESYSTEMS=() + +# Enhanced cleanup function to unmount filesystems in reverse order +cleanup_mounts() { + print_status "Cleaning up mounted filesystems..." + # Iterate in reverse for safer unmounting + for (( i=${#MOUNTED_FILESYSTEMS[@]}-1; i>=0; i-- )); do + mount_point="${MOUNTED_FILESYSTEMS[i]}" + if mountpoint -q "$mount_point" 2>/dev/null; then + print_status "Unmounting $mount_point" + sudo umount "$mount_point" 2>/dev/null || print_warning "Failed to unmount $mount_point" + fi + done + MOUNTED_FILESYSTEMS=() +} + +# Signal trap to ensure cleanup on script exit (handles Ctrl+C, errors, etc.) +trap cleanup_mounts EXIT INT TERM + +# Enhanced safe mount function with error checking +safe_mount() { + local source="$1" + local target="$2" + local type="${3:-}" + + # Validate mount points + if [[ ! -d "$target" ]]; then + print_error "Mount target directory does not exist: $target" + exit 1 + fi + + if [ -n "$type" ]; then + sudo mount -t "$type" "$source" "$target" + else + sudo mount --bind "$source" "$target" + fi + + if [ $? -eq 0 ]; then + MOUNTED_FILESYSTEMS+=("$target") + print_status "Mounted $source to $target" + else + print_error "Failed to mount $source to $target" + exit 1 + fi +} + +# Enhanced safe chroot function with error checking +safe_chroot() { + local command="$1" + local description="${2:-chroot command}" + + print_status "Running: $description" + if sudo chroot "$CHROOT_DIR" bash -c "$command"; then + print_success "$description completed successfully" + else + print_error "$description failed" + exit 1 + fi +} + +# Enhanced prerequisites check with better error handling +check_prerequisites() { + print_header "Phase 1: Check Prerequisites" + + local missing_packages=() + + # Check for build tools + for package in mmdebstrap squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin; do + if ! dpkg -s "$package" &>/dev/null; then + missing_packages+=("$package") + fi + done + + # Enhanced ISOLINUX checks + if [ ! -f "/usr/lib/ISOLINUX/isohdpfx.bin" ]; then + print_error "ISOLINUX isohdpfx.bin not found. Please ensure 'isolinux' package is installed." + exit 1 + fi + # Also check for isolinux.bin in standard locations + if [ ! -f "/usr/lib/syslinux/isolinux.bin" ] && [ ! -f "/usr/lib/ISOLINUX/isolinux.bin" ]; then + print_error "isolinux.bin not found. Please ensure 'isolinux' package is installed." + exit 1 + fi + + if [ ${#missing_packages[@]} -gt 0 ]; then + print_status "Installing missing packages: ${missing_packages[*]}" + sudo apt update || { print_error "Failed to update package lists"; exit 1; } + sudo apt install -y "${missing_packages[@]}" || { print_error "Failed to install missing packages"; exit 1; } + fi + + # Enhanced disk space check (increased to 15GB for safety) + local available_space=$(df "$SCRIPT_DIR" | awk 'NR==2 {print $4}') + local required_space=$((15 * 1024 * 1024)) # 15GB in KB + + if [ "$available_space" -lt "$required_space" ]; then + print_error "Insufficient disk space. Need at least 15GB free, have $(($available_space / 1024 / 1024))GB" + exit 1 + fi + + # Check network connectivity + if ! ping -c 1 archive.ubuntu.com &>/dev/null; then + print_error "Cannot reach Ubuntu archives. Check your internet connection." + exit 1 + fi + + if ! curl -s -I "https://git.raines.xyz/robojerk/apt-ostree/raw/branch/main/apt-ostree_0.1.0-1_amd64.deb" | head -n 1 | grep "HTTP/[12] [23].." > /dev/null; then + print_error "Cannot reach apt-ostree repository. Check your internet connection." + exit 1 + fi + + print_success "All prerequisites satisfied" +} + +# Enhanced clean build environment with expanded safety checks +clean_build() { + print_header "Phase 2: Clean Build Environment" + + if [ -d "$BUILD_DIR" ]; then + # Enhanced safety check: Expanded blacklist of critical directories + if [[ "$BUILD_DIR" == "/" ]] || [[ "$BUILD_DIR" == "/home" ]] || [[ "$BUILD_DIR" == "/opt" ]] || \ + [[ "$BUILD_DIR" == "/usr" ]] || [[ "$BUILD_DIR" == "/var" ]] || [[ "$BUILD_DIR" == "/etc" ]] || \ + [[ "$BUILD_DIR" == "/root" ]] || [[ "$BUILD_DIR" == "/tmp" ]] || [[ "$BUILD_DIR" == "/sbin" ]] || \ + [[ "$BUILD_DIR" == "/bin" ]] || [[ "$BUILD_DIR" == "/lib" ]] || [[ "$BUILD_DIR" == "/lib64" ]]; then + print_error "BUILD_DIR ($BUILD_DIR) is a critical system directory. Aborting for safety." + exit 1 + fi + + print_status "Removing previous build directory: $BUILD_DIR..." + sudo rm -rf "$BUILD_DIR" || { print_error "Failed to remove previous build directory"; exit 1; } + fi + + mkdir -p "$BUILD_DIR" "$CHROOT_DIR" "$ISO_DIR" "$OUTPUT_DIR" || { print_error "Failed to create build directories"; exit 1; } + print_success "Build environment cleaned" +} + +# Enhanced base system creation using mmdebstrap +create_base_system() { + print_header "Phase 3: Create Base System with mmdebstrap" + + print_status "Creating base Ubuntu system using mmdebstrap..." + + # Enhanced base system with mmdebstrap + # Using --variant=minbase as it provides a minimal system more suitable for custom builds. + # Added 'locales' for proper locale generation and 'resolvconf' for DNS if needed. + if sudo mmdebstrap \ + --architectures=amd64 \ + --variant=minbase \ + --include=systemd,systemd-sysv,dbus,curl,ca-certificates,gnupg,locales,resolvconf \ + noble \ + "$CHROOT_DIR" \ + http://archive.ubuntu.com/ubuntu/; then + print_success "Base system created with mmdebstrap" + else + print_error "Failed to create base system with mmdebstrap" + exit 1 + fi +} + +# Enhanced base system configuration +configure_base_system() { + print_header "Phase 4: Configure Base System" + + print_status "Configuring base system..." + + # Mount necessary filesystems + safe_mount "/dev" "$CHROOT_DIR/dev" + safe_mount "/run" "$CHROOT_DIR/run" + safe_mount "none" "$CHROOT_DIR/proc" "proc" + safe_mount "none" "$CHROOT_DIR/sys" "sysfs" + + # Configure package sources + safe_chroot "echo 'deb http://archive.ubuntu.com/ubuntu noble main restricted universe multiverse' > /etc/apt/sources.list" "Configure main sources" + safe_chroot "echo 'deb http://archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse' >> /etc/apt/sources.list" "Configure updates sources" + safe_chroot "echo 'deb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse' >> /etc/apt/sources.list" "Configure security sources" + + # Add Forgejo repository for apt-ostree and potentially other DEB packages (like Firefox if available) + print_status "Setting up Forgejo repository for apt-ostree and other packages..." + safe_chroot "mkdir -p /etc/apt/keyrings" "Create keyrings directory" + # Use -o /dev/null for curl output to stdout, pipe to gpg + safe_chroot "curl -fsSL https://git.raines.xyz/api/packages/robojerk/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/forgejo-robojerk.gpg" "Download and import Forgejo GPG key" + safe_chroot "echo 'deb [signed-by=/etc/apt/keyrings/forgejo-robojerk.gpg] https://git.raines.xyz/api/packages/robojerk/debian noble main' > /etc/apt/sources.list.d/forgejo.list" "Add Forgejo repository" + + # Update package lists + safe_chroot "apt update" "Update package lists" + + # Enhanced package installation with ostree and bootc + # Including 'ostree' and 'bootc' as requested + # If a DEB for Firefox exists in any enabled repo, it will be preferred over Snap due to preferences below. + safe_chroot "DEBIAN_FRONTEND=noninteractive apt install -y \ + kubuntu-desktop plasma-desktop plasma-workspace kde-plasma-desktop sddm \ + ostree bootc flatpak \ + network-manager plasma-nm \ + openssh-server \ + curl wget vim nano htop neofetch tree \ + firefox \ + pulseaudio pulseaudio-utils \ + fonts-ubuntu fonts-noto \ + build-essential git \ + live-boot live-config casper" "Install desktop and core live packages" + + # Download and install apt-ostree from custom repository (assuming it's not in the Forgejo apt repo directly) + print_status "Installing apt-ostree from custom repository directly..." + safe_chroot "timeout 60 wget -O /tmp/apt-ostree.deb 'https://git.raines.xyz/robojerk/apt-ostree/raw/branch/main/apt-ostree_0.1.0-1_amd64.deb'" "Download apt-ostree" + safe_chroot "dpkg -i /tmp/apt-ostree.deb || apt install -f -y" "Install apt-ostree and fix dependencies" + safe_chroot "rm -f /tmp/apt-ostree.deb" "Clean up apt-ostree download" + + # Enhanced snap removal and blocking + print_status "Removing snapd and setting APT preferences to block snaps..." + safe_chroot "DEBIAN_FRONTEND=noninteractive apt purge -y snapd ubuntu-advantage-tools update-notifier update-manager unattended-upgrades" "Purge unwanted packages" + safe_chroot "apt autoremove -y" "Autoremove orphaned packages" + safe_chroot "apt-mark hold snapd" "Hold snapd" + # Create an APT preference file to strongly discourage snapd and enforce non-snap Firefox + safe_chroot "echo 'Package: snapd' > /etc/apt/preferences.d/nosnap.pref" "Create nosnap.pref" + safe_chroot "echo 'Pin: release *' >> /etc/apt/preferences.d/nosnap.pref" "Set nosnap.pref pin release" + safe_chroot "echo 'Pin-Priority: -1' >> /etc/apt/preferences.d/nosnap.pref" "Set nosnap.pref pin priority" + safe_chroot "echo 'Package: firefox' >> /etc/apt/preferences.d/nosnap.pref" "Add firefox to nosnap.pref" + safe_chroot "echo 'Pin: release o=Ubuntu' >> /etc/apt/preferences.d/nosnap.pref" "Pin Firefox to Ubuntu archive" + safe_chroot "echo 'Pin-Priority: 1000' >> /etc/apt/preferences.d/nosnap.pref" "Give high priority to APT Firefox" + + # Enhanced system configuration + safe_chroot "echo 'particleos' > /etc/hostname" "Set hostname" + safe_chroot "echo '127.0.0.1 localhost' >> /etc/hosts" "Add localhost to hosts" # More standard + safe_chroot "echo '127.0.1.1 particleos.local particleos' >> /etc/hosts" "Add hostname to hosts" + safe_chroot "ln -sf /usr/share/zoneinfo/UTC /etc/localtime" "Set timezone to UTC" + safe_chroot "locale-gen en_US.UTF-8" "Generate locale" # Important for desktop + safe_chroot "update-locale LANG=en_US.UTF-8" "Set default locale" + + # Enhanced user creation + print_status "Creating user 'particle'..." + safe_chroot "useradd -m -s /bin/bash particle" "Create particle user" + safe_chroot "echo 'particle:particle' | chpasswd" "Set particle password" + safe_chroot "usermod -aG sudo particle" "Add particle to sudo group" + safe_chroot "echo 'particle ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/particle" "Allow particle sudo without password (for live system)" + safe_chroot "chmod 0440 /etc/sudoers.d/particle" "Set correct permissions for sudoers file" + + # Enhanced service configuration + print_status "Enabling essential services..." + safe_chroot "systemctl enable sddm NetworkManager ssh" "Enable key services" # Removed systemd-networkd, systemd-resolved if NetworkManager is used for DNS. + safe_chroot "systemctl disable apt-daily.timer apt-daily-upgrade.timer" "Disable daily apt timers for live system" + + # Enhanced apt-ostree configuration + print_status "Configuring apt-ostree..." + safe_chroot "mkdir -p /etc/apt-ostree" "Create apt-ostree config directory" + safe_chroot "echo 'ref: particleos/desktop/1.0.0' > /etc/apt-ostree/ref" "Configure apt-ostree ref" + # Additional OSTree setup (initial commit, etc.) would typically happen here if building a committed image + # For a live ISO, apt-ostree mostly provides its tools. + + # Enhanced cleanup + print_status "Cleaning APT caches in chroot..." + safe_chroot "apt clean" "Clean apt cache" + safe_chroot "rm -rf /var/lib/apt/lists/*" "Remove apt lists" + safe_chroot "rm -rf /tmp/*" "Clean /tmp" + + print_success "Base system configured" +} + +# Enhanced live filesystem creation +create_live_fs() { + print_header "Phase 5: Create Live Filesystem" + + print_status "Creating live filesystem structure..." + + # Create ISO directory structure + # Adding EFI/BOOT and boot/grub for UEFI/BIOS + mkdir -p "$ISO_DIR"/{casper,boot/grub,EFI/BOOT,isolinux} || { print_error "Failed to create ISO directories"; exit 1; } + + # Enhanced kernel and initrd copying + print_status "Copying kernel and initramfs..." + # Find the latest kernel and initrd + local kernel_version=$(basename "$CHROOT_DIR"/boot/vmlinuz-* | sort -V | tail -n 1 | sed 's/vmlinuz-//') + local initrd_version=$(basename "$CHROOT_DIR"/boot/initrd.img-* | sort -V | tail -n 1 | sed 's/initrd.img-//') + + if [ -z "$kernel_version" ] || [ -z "$initrd_version" ]; then + print_error "Could not find kernel or initrd in chroot/boot." + exit 1 + fi + + cp "$CHROOT_DIR/boot/vmlinuz-$kernel_version" "$ISO_DIR/casper/vmlinuz" || { print_error "Failed to copy kernel"; exit 1; } + cp "$CHROOT_DIR/boot/initrd.img-$initrd_version" "$ISO_DIR/casper/initrd" || { print_error "Failed to copy initrd"; exit 1; } + print_success "Kernel and initramfs copied." + + # Enhanced filesystem manifest creation + print_status "Creating filesystem manifest..." + safe_chroot "dpkg-query -W --showformat='\${Package} \${Version}\n' > /filesystem.manifest" "Create filesystem manifest" + cp "$CHROOT_DIR/filesystem.manifest" "$ISO_DIR/casper/filesystem.manifest" || { print_error "Failed to copy filesystem.manifest"; exit 1; } + safe_chroot "rm /filesystem.manifest" "Clean up manifest in chroot" # Remove temp file in chroot + + # Enhanced filesystem size calculation + print_status "Calculating filesystem size..." + sudo du -sx --block-size=1 "$CHROOT_DIR" | cut -f1 > "$ISO_DIR/casper/filesystem.size" || { print_error "Failed to create filesystem.size"; exit 1; } + print_success "Filesystem size calculated." + + # Enhanced squashfs creation + print_status "Creating squashfs filesystem from chroot..." + # IMPORTANT: Unmount internal chroot mounts before mksquashfs for cleanest image + cleanup_mounts # Call the cleanup function here to unmount /dev, /run, /proc, /sys from chroot + + if sudo mksquashfs "$CHROOT_DIR" "$ISO_DIR/casper/filesystem.squashfs" -comp xz -e boot; then + print_success "Squashfs created." + else + print_error "Failed to create squashfs." + exit 1 + fi + print_status "Re-mounting filesystems in chroot for any subsequent operations (though none currently follow in this script)." + # Re-mount for consistency, though currently nothing follows. The EXIT trap will handle final unmount. + safe_mount "/dev" "$CHROOT_DIR/dev" + safe_mount "/run" "$CHROOT_DIR/run" + safe_mount "none" "$CHROOT_DIR/proc" "proc" + safe_mount "none" "$CHROOT_DIR/sys" "sysfs" +} + +# Enhanced boot configuration setup +setup_boot() { + print_header "Phase 6: Setup Boot Configuration" + + print_status "Setting up boot configuration..." + + # Enhanced GRUB configuration (for UEFI) + cat > "$ISO_DIR/boot/grub/grub.cfg" << 'EOF' +set timeout=10 +set default=0 + +menuentry "Try ParticleOS without installing" { + linux /casper/vmlinuz boot=casper quiet splash --- + initrd /casper/initrd +} + +menuentry "Install ParticleOS" { + linux /casper/vmlinuz boot=casper quiet splash --- + initrd /casper/initrd +} + +menuentry "Check disc for defects" { + linux /casper/vmlinuz boot=casper integrity-check quiet splash --- + initrd /casper/initrd +} +EOF + print_success "GRUB configuration created." + + # Enhanced ISOLINUX configuration (for BIOS) + cat > "$ISO_DIR/isolinux/isolinux.cfg" << 'EOF' +DEFAULT live +TIMEOUT 300 +PROMPT 1 + +LABEL live + MENU LABEL Try ParticleOS without installing + KERNEL /casper/vmlinuz + APPEND boot=casper initrd=/casper/initrd quiet splash --- + +LABEL live-install + MENU LABEL Install ParticleOS + KERNEL /casper/vmlinuz + APPEND boot=casper initrd=/casper/initrd quiet splash --- + +LABEL check + MENU LABEL Check disc for defects + KERNEL /casper/vmlinuz + APPEND boot=casper integrity-check initrd=/casper/initrd quiet splash --- +EOF + print_success "ISOLINUX configuration created." + + # Enhanced ISOLINUX boot files copying + print_status "Copying ISOLINUX boot files..." + # Determine correct isolinux path (can vary by distro/version) + ISOLINUX_BIN_PATH="" + if [ -f "/usr/lib/syslinux/isolinux.bin" ]; then + ISOLINUX_BIN_PATH="/usr/lib/syslinux" + elif [ -f "/usr/lib/ISOLINUX/isolinux.bin" ]; then + ISOLINUX_BIN_PATH="/usr/lib/ISOLINUX" + fi + + if [ -z "$ISOLINUX_BIN_PATH" ]; then + print_error "isolinux.bin path not found. ISO creation might fail." + exit 1 + fi + + cp "$ISOLINUX_BIN_PATH/isolinux.bin" "$ISO_DIR/isolinux/" || { print_error "Failed to copy isolinux.bin"; exit 1; } + print_success "ISOLINUX boot files copied." + + # Enhanced EFI boot image creation (for UEFI) + # This assumes grub-efi-amd64-bin provides the necessary files to create efi.img. + # A robust solution might involve grub-mkimage. For a simple live ISO, this is often sufficient. + print_status "Creating EFI boot image..." + GRUB_EFI_DIR="/usr/lib/grub/efi-amd64" # Standard path for grub-efi-amd64-bin + if [ ! -d "$GRUB_EFI_DIR" ]; then + print_error "GRUB EFI directory not found at $GRUB_EFI_DIR. Cannot create EFI boot image." + exit 1 + fi + + mkdir -p "$ISO_DIR/EFI/BOOT" || { print_error "Failed to create EFI/BOOT directory"; exit 1; } + # Copy essential EFI files for direct boot (e.g., used by some VMs/UEFI firmwares) + cp "$GRUB_EFI_DIR/grubx64.efi" "$ISO_DIR/EFI/BOOT/bootx64.efi" || { print_error "Failed to copy grubx64.efi"; exit 1; } + + # Create the EFI grub.cfg for the live system + cat > "$ISO_DIR/EFI/BOOT/grub.cfg" << 'EOF' +search --set=root --file /casper/vmlinuz +set timeout=10 +set default=0 + +menuentry "Try ParticleOS without installing" { + linux ($root)/casper/vmlinuz boot=casper quiet splash --- + initrd ($root)/casper/initrd +} + +menuentry "Install ParticleOS" { + linux ($root)/casper/vmlinuz boot=casper quiet splash --- + initrd ($root)/casper/initrd +} + +menuentry "Check disc for defects" { + linux ($root)/casper/vmlinuz boot=casper integrity-check quiet splash --- + initrd ($root)/casper/initrd +} +EOF + print_success "EFI boot configuration created." +} + +# Enhanced ISO creation +create_iso() { + print_header "Phase 7: Create ISO" # Updated phase number + + print_status "Creating bootable ISO using xorriso..." + + # Enhanced check for isolinux.bin location for xorriso + local isolinux_bin="" + if [ -f "/usr/lib/syslinux/isolinux.bin" ]; then + isolinux_bin="/usr/lib/syslinux/isolinux.bin" + elif [ -f "/usr/lib/ISOLINUX/isolinux.bin" ]; then + isolinux_bin="/usr/lib/ISOLINUX/isolinux.bin" + fi + + if [ -z "$isolinux_bin" ]; then + print_error "Cannot find isolinux.bin for xorriso. Aborting ISO creation." + exit 1 + fi + + # Enhanced ISO creation using xorriso + # -part_like_isohybrid: Better for modern systems + if sudo xorriso -as mkisofs \ + -o "$OUTPUT_DIR/${PROJECT_NAME}-${VERSION}.iso" \ + -J -joliet-long \ + -r -V "ParticleOS ${VERSION}" \ + -b isolinux/isolinux.bin \ + -boot-load-size 4 -boot-info-table \ + -no-emul-boot -eltorito-alt-boot \ + -e EFI/BOOT/bootx64.efi -no-emul-boot \ + -isohybrid-mbr "$isolinux_bin" \ + -partition_offset 16 \ + -part_like_isohybrid \ + "$ISO_DIR"; then + print_success "ISO created successfully: $OUTPUT_DIR/${PROJECT_NAME}-${VERSION}.iso" + else + print_error "Failed to create ISO" + exit 1 + fi +} + +# Enhanced main build process +main() { + echo "๐Ÿš€ ParticleOS ISO Builder (mmdebstrap) - HARDENED VERSION" + echo "==================================================" + echo "Project: $PROJECT_NAME" + echo "Version: $VERSION" + echo "Build Directory: $BUILD_DIR" + echo "Tool: mmdebstrap" + echo "" + echo "๐Ÿ›ก๏ธ This build includes enhanced safety measures:" + echo " - Expanded directory blacklist" + echo " - Enhanced error handling" + echo " - Better mount/unmount management" + echo " - Comprehensive ISOLINUX support" + echo " - Robust cleanup procedures" + echo "" + + # Run enhanced build phases + check_prerequisites + clean_build + create_base_system + configure_base_system + create_live_fs # New phase for clarity + setup_boot # New phase for clarity + create_iso + + print_header "Build Complete!" + echo "" + echo "๐ŸŽ‰ ParticleOS ISO built successfully!" + echo "๐Ÿ“ Location: $OUTPUT_DIR/${PROJECT_NAME}-${VERSION}.iso" + echo "" + echo "๐Ÿงช Test the ISO:" + echo " qemu-system-x86_64 -m 4G -enable-kvm \\" + echo " -cdrom $OUTPUT_DIR/${PROJECT_NAME}-${VERSION}.iso \\" + echo " -boot d" + echo "" + echo "๐Ÿ›ก๏ธ Enhanced safety measures applied!" +} + +# Run main function +main "$@" \ No newline at end of file diff --git a/build-iso-mmdebstrap-safe.sh b/build-iso-mmdebstrap-safe.sh new file mode 100755 index 0000000..0ffb25f --- /dev/null +++ b/build-iso-mmdebstrap-safe.sh @@ -0,0 +1,324 @@ +#!/bin/bash + +# ParticleOS ISO Builder with mmdebstrap - SAFE VERSION +# Builds a bootable ISO using mmdebstrap + apt-ostree integration +# Includes comprehensive error handling and safety checks + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +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" +} + +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}================================${NC}" +} + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_NAME="particleos" +VERSION="1.0.0" +BUILD_DIR="$SCRIPT_DIR/build" +CHROOT_DIR="$BUILD_DIR/chroot" +ISO_DIR="$BUILD_DIR/iso" +OUTPUT_DIR="$SCRIPT_DIR/output" + +# Safety check: Ensure BUILD_DIR is within SCRIPT_DIR +if [[ ! "$BUILD_DIR" =~ ^"$SCRIPT_DIR" ]]; then + print_error "BUILD_DIR ($BUILD_DIR) is not within SCRIPT_DIR ($SCRIPT_DIR). Aborting for safety." + exit 1 +fi + +# Track mounted filesystems for cleanup +MOUNTED_FILESYSTEMS=() + +# Cleanup function to unmount filesystems +cleanup_mounts() { + print_status "Cleaning up mounted filesystems..." + for mount_point in "${MOUNTED_FILESYSTEMS[@]}"; do + if mountpoint -q "$mount_point" 2>/dev/null; then + print_status "Unmounting $mount_point" + sudo umount "$mount_point" 2>/dev/null || print_warning "Failed to unmount $mount_point" + fi + done + MOUNTED_FILESYSTEMS=() +} + +# Signal trap to ensure cleanup on script exit +trap cleanup_mounts EXIT INT TERM + +# Safe mount function +safe_mount() { + local source="$1" + local target="$2" + local type="${3:-}" + + if [ -n "$type" ]; then + sudo mount -t "$type" "$source" "$target" + else + sudo mount --bind "$source" "$target" + fi + + if [ $? -eq 0 ]; then + MOUNTED_FILESYSTEMS+=("$target") + print_status "Mounted $source to $target" + else + print_error "Failed to mount $source to $target" + exit 1 + fi +} + +# Safe chroot function with error checking +safe_chroot() { + local command="$1" + local description="${2:-chroot command}" + + print_status "Running: $description" + if sudo chroot "$CHROOT_DIR" bash -c "$command"; then + print_success "$description completed successfully" + else + print_error "$description failed" + exit 1 + fi +} + +# Check prerequisites with better error handling +check_prerequisites() { + print_header "Phase 1: Check Prerequisites" + + local missing_packages=() + + # Check for build tools + for package in mmdebstrap squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin; do + if ! dpkg -s "$package" &>/dev/null; then + missing_packages+=("$package") + fi + done + + # Check for ISOLINUX + if [ ! -f "/usr/lib/ISOLINUX/isohdpfx.bin" ]; then + print_error "ISOLINUX isohdpfx.bin not found. Please install isolinux." + exit 1 + fi + + if [ ${#missing_packages[@]} -gt 0 ]; then + print_status "Installing missing packages: ${missing_packages[*]}" + sudo apt update + sudo apt install -y "${missing_packages[@]}" + fi + + # Verify disk space (need at least 10GB free) + local available_space=$(df "$SCRIPT_DIR" | awk 'NR==2 {print $4}') + local required_space=$((10 * 1024 * 1024)) # 10GB in KB + + if [ "$available_space" -lt "$required_space" ]; then + print_error "Insufficient disk space. Need at least 10GB free, have $(($available_space / 1024 / 1024))GB" + exit 1 + fi + + print_success "All prerequisites satisfied" +} + +# Clean build environment with safety checks +clean_build() { + print_header "Phase 2: Clean Build Environment" + + if [ -d "$BUILD_DIR" ]; then + # Safety check: Ensure we're not deleting something important + if [[ "$BUILD_DIR" == "/" ]] || [[ "$BUILD_DIR" == "/home" ]] || [[ "$BUILD_DIR" == "/opt" ]]; then + print_error "BUILD_DIR ($BUILD_DIR) is a critical system directory. Aborting for safety." + exit 1 + fi + + print_status "Removing previous build directory..." + sudo rm -rf "$BUILD_DIR" + fi + + mkdir -p "$BUILD_DIR" "$CHROOT_DIR" "$ISO_DIR" "$OUTPUT_DIR" + print_success "Build environment cleaned" +} + +# Create base system using mmdebstrap +create_base_system() { + print_header "Phase 3: Create Base System with mmdebstrap" + + print_status "Creating base Ubuntu system using mmdebstrap..." + + # Create base system with mmdebstrap + if sudo mmdebstrap \ + --architectures=amd64 \ + --variant=apt \ + --include=systemd,systemd-sysv,dbus,curl,ca-certificates,gnupg \ + noble \ + "$CHROOT_DIR" \ + http://archive.ubuntu.com/ubuntu/; then + print_success "Base system created with mmdebstrap" + else + print_error "Failed to create base system" + exit 1 + fi +} + +# Configure base system +configure_base_system() { + print_header "Phase 4: Configure Base System" + + print_status "Configuring base system..." + + # Mount necessary filesystems + safe_mount "/dev" "$CHROOT_DIR/dev" + safe_mount "/run" "$CHROOT_DIR/run" + safe_mount "none" "$CHROOT_DIR/proc" "proc" + safe_mount "none" "$CHROOT_DIR/sys" "sysfs" + + # Configure package sources + safe_chroot "echo 'deb http://archive.ubuntu.com/ubuntu noble main restricted universe multiverse' > /etc/apt/sources.list" "Configure main sources" + safe_chroot "echo 'deb http://archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse' >> /etc/apt/sources.list" "Configure updates sources" + safe_chroot "echo 'deb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse' >> /etc/apt/sources.list" "Configure security sources" + + # Skip Forgejo repository for now - we'll download apt-ostree directly + print_status "Skipping Forgejo repository setup - will download apt-ostree directly" + + # Update package lists + safe_chroot "apt update" "Update package lists" + + # Install desktop and additional packages (non-interactive) + safe_chroot "DEBIAN_FRONTEND=noninteractive apt install -y kubuntu-desktop plasma-desktop plasma-workspace kde-plasma-desktop sddm flatpak network-manager plasma-nm openssh-server curl wget vim nano htop neofetch tree firefox pulseaudio pulseaudio-utils fonts-ubuntu fonts-noto build-essential git" "Install desktop packages" + + # Download and install apt-ostree from custom repository + print_status "Installing apt-ostree from custom repository..." + safe_chroot "timeout 60 wget -O /tmp/apt-ostree.deb 'https://git.raines.xyz/robojerk/apt-ostree/raw/branch/main/apt-ostree_0.1.0-1_amd64.deb'" "Download apt-ostree" + safe_chroot "dpkg -i /tmp/apt-ostree.deb" "Install apt-ostree" + safe_chroot "rm /tmp/apt-ostree.deb" "Clean up apt-ostree download" + + # Remove unwanted packages and block snaps + safe_chroot "DEBIAN_FRONTEND=noninteractive apt remove -y snapd ubuntu-advantage-tools update-notifier update-manager unattended-upgrades" "Remove unwanted packages" + safe_chroot "apt-mark hold snapd" "Hold snapd" + safe_chroot "echo 'Package: snapd' > /etc/apt/preferences.d/no-snapd" "Block snapd" + safe_chroot "echo 'Pin: release *' >> /etc/apt/preferences.d/no-snapd" "Block snapd pin" + safe_chroot "echo 'Pin-Priority: -1' >> /etc/apt/preferences.d/no-snapd" "Block snapd priority" + + # Configure system + safe_chroot "echo 'particleos' > /etc/hostname" "Set hostname" + safe_chroot "echo 'particleos.local particleos' >> /etc/hosts" "Configure hosts" + safe_chroot "ln -sf /usr/share/zoneinfo/UTC /etc/localtime" "Set timezone" + + # Create user + safe_chroot "useradd -m -s /bin/bash particle" "Create particle user" + safe_chroot "echo 'particle:particle' | chpasswd" "Set particle password" + safe_chroot "usermod -aG sudo particle" "Add particle to sudo group" + + # Configure services + safe_chroot "systemctl enable systemd-networkd systemd-resolved sddm NetworkManager ssh" "Enable services" + + # Configure apt-ostree + safe_chroot "mkdir -p /etc/apt-ostree" "Create apt-ostree config directory" + safe_chroot "echo 'main' > /etc/apt-ostree/ref" "Configure apt-ostree ref" + + print_success "Base system configured" +} + +# Create ISO +create_iso() { + print_header "Phase 5: Create ISO" + + print_status "Creating ISO structure..." + + # Create ISO directory structure + mkdir -p "$ISO_DIR"/{casper,boot/grub,EFI/BOOT} + + # Copy kernel and initrd + cp "$CHROOT_DIR"/boot/vmlinuz-* "$ISO_DIR/casper/vmlinuz" + cp "$CHROOT_DIR"/boot/initrd.img-* "$ISO_DIR/casper/initrd" + + # Create filesystem manifest + safe_chroot "dpkg-query -W --showformat='${Package} ${Version}\n' > /tmp/filesystem.manifest" "Create filesystem manifest" + cp "$CHROOT_DIR/tmp/filesystem.manifest" "$ISO_DIR/casper/filesystem.manifest" + + # Create filesystem size + du -sx --block-size=1 "$CHROOT_DIR" | cut -f1 > "$ISO_DIR/casper/filesystem.size" + + # Create squashfs + print_status "Creating squashfs filesystem..." + if sudo mksquashfs "$CHROOT_DIR" "$ISO_DIR/casper/filesystem.squashfs" -comp xz -e boot; then + print_success "Squashfs created" + else + print_error "Failed to create squashfs" + exit 1 + fi + + # Create GRUB configuration + cat > "$ISO_DIR/boot/grub/grub.cfg" << 'EOF' +set timeout=10 +set default=0 + +menuentry "Try ParticleOS without installing" { + linux /casper/vmlinuz boot=casper quiet splash + initrd /casper/initrd +} + +menuentry "Install ParticleOS" { + linux /casper/vmlinuz boot=casper quiet splash + initrd /casper/initrd +} +EOF + + # Create ISO + print_status "Creating bootable ISO..." + if sudo xorriso -as mkisofs -r -V "ParticleOS $VERSION" -o "$OUTPUT_DIR/particleos-$VERSION.iso" \ + -J -joliet-long -b isolinux/isolinux.bin -c isolinux/boot.cat \ + -boot-load-size 4 -boot-info-table -no-emul-boot \ + -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot \ + -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ + "$ISO_DIR"; then + print_success "ISO created successfully: $OUTPUT_DIR/particleos-$VERSION.iso" + else + print_error "Failed to create ISO" + exit 1 + fi +} + +# Main execution +main() { + echo "๐Ÿš€ ParticleOS ISO Builder (mmdebstrap) - SAFE VERSION" + echo "=======================================" + echo "Project: $PROJECT_NAME" + echo "Version: $VERSION" + echo "Build Directory: $BUILD_DIR" + echo "Tool: mmdebstrap" + echo "" + + check_prerequisites + clean_build + create_base_system + configure_base_system + create_iso + + print_success "ParticleOS ISO build completed successfully!" + print_status "ISO file: $OUTPUT_DIR/particleos-$VERSION.iso" +} + +# Run main function +main "$@" \ No newline at end of file diff --git a/build-iso-podman.sh b/build-iso-podman.sh new file mode 100755 index 0000000..1416531 --- /dev/null +++ b/build-iso-podman.sh @@ -0,0 +1,658 @@ +#!/bin/bash + +# ParticleOS ISO Builder with Podman - HARDENED ULTRA SAFE VERSION +# Builds a bootable ISO using Podman containers for complete isolation +# This approach cannot break your host system +# Includes all hardening features from the analysis + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +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" + # Exit immediately on error. If this is an error from the container, + # the container's error message should have already propagated. + exit 1 +} + +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}================================${NC}" +} + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_NAME="particleos" +VERSION="1.0.0" +BUILD_DIR="$SCRIPT_DIR/build" +OUTPUT_DIR="$SCRIPT_DIR/output" +CONTAINER_NAME="particleos-builder" +IMAGE_NAME="particleos-builder:latest" + +# Safety check: Ensure BUILD_DIR is within SCRIPT_DIR +if [[ ! "$BUILD_DIR" =~ ^"$SCRIPT_DIR" ]]; then + print_error "BUILD_DIR ($BUILD_DIR) is not within SCRIPT_DIR ($SCRIPT_DIR). Aborting for safety." + exit 1 +fi + +# Determine Podman command (sudo or not) +PODMAN_CMD="" +check_podman() { + print_header "Phase 1: Check Podman Availability" + + if ! command -v podman &> /dev/null; then + print_error "Podman is not installed. Please install Podman first: sudo apt update && sudo apt install -y podman" + fi + + # Try running podman without sudo first + if podman info &> /dev/null; then + PODMAN_CMD="podman" + print_success "Podman available (rootless or with user access)." + else + # If rootless fails, try with sudo + if sudo podman info &> /dev/null; then + PODMAN_CMD="sudo podman" + print_warning "Podman requires sudo. This is normal for some configurations. Using '$PODMAN_CMD'." + else + print_error "Podman cannot be run even with sudo. Check your Podman installation and user permissions." + fi + fi +} + +# Check prerequisites +check_prerequisites() { + print_header "Phase 2: Check Prerequisites" + + # Check disk space (need at least 15GB free for container + ISO) + local available_space=$(df "$SCRIPT_DIR" | awk 'NR==2 {print $4}') + local required_space=$((15 * 1024 * 1024)) # 15GB in KB + + if [ "$available_space" -lt "$required_space" ]; then + print_error "Insufficient disk space. Need at least 15GB free, have $(($available_space / 1024 / 1024))GB" + fi + + # Check network connectivity + if ! ping -c 1 archive.ubuntu.com &>/dev/null; then + print_error "Cannot reach Ubuntu archives. Check your internet connection." + fi + + # Using --silent --head for curl to check HTTP status code more reliably + if ! curl --silent --head "https://git.raines.xyz/robojerk/apt-ostree/raw/branch/main/apt-ostree_0.1.0-1_amd64.deb" | grep "HTTP/[12] [23].." > /dev/null; then + print_error "Cannot reach apt-ostree repository. Check your internet connection." + fi + + print_success "All prerequisites satisfied" +} + +# Clean build environment +clean_build() { + print_header "Phase 3: Clean Build Environment" + + # Remove any existing container + if $PODMAN_CMD container exists "$CONTAINER_NAME" 2>/dev/null; then + print_status "Removing existing container: $CONTAINER_NAME" + $PODMAN_CMD container rm -f "$CONTAINER_NAME" 2>/dev/null || true + fi + + # Remove any existing image + if $PODMAN_CMD image exists "$IMAGE_NAME" 2>/dev/null; then + print_status "Removing existing image: $IMAGE_NAME" + $PODMAN_CMD image rm -f "$IMAGE_NAME" 2>/dev/null || true + fi + + # Clean build directories + if [ -d "$BUILD_DIR" ]; then + print_status "Removing previous build directory: $BUILD_DIR..." + # Add host-side safety check for rm -rf + if [[ "$BUILD_DIR" == "/" ]] || [[ "$BUILD_DIR" == "/home" ]] || [[ "$BUILD_DIR" == "/opt" ]] || \ + [[ "$BUILD_DIR" == "/usr" ]] || [[ "$BUILD_DIR" == "/var" ]] || [[ "$BUILD_DIR" == "/etc" ]]; then + print_error "BUILD_DIR ($BUILD_DIR) is a critical system directory. Aborting for safety." + fi + rm -rf "$BUILD_DIR" || print_error "Failed to remove previous build directory." + fi + + mkdir -p "$BUILD_DIR" "$OUTPUT_DIR" || print_error "Failed to create build directories." + print_success "Build environment cleaned" +} + +# Create Dockerfile for the build environment +create_dockerfile() { + print_header "Phase 4: Create Build Environment" + + cat > "$BUILD_DIR/Dockerfile" << 'EOF' +FROM ubuntu:noble + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC + +# Update and install build tools +# Added software-properties-common for add-apt-repository +# Added live-build for more complete live ISO tools if needed, though casper/live-boot should be sufficient +RUN apt update && apt install -y \ + mmdebstrap \ + squashfs-tools \ + xorriso \ + grub-pc-bin \ + grub-efi-amd64-bin \ + isolinux \ + curl \ + wget \ + ca-certificates \ + gnupg \ + software-properties-common \ + live-build \ + && rm -rf /var/lib/apt/lists/* + +# Set up working directory +WORKDIR /build + +# Copy build script +COPY build-in-container.sh /build/ +RUN chmod +x /build/build-in-container.sh + +# Default command +CMD ["/build/build-in-container.sh"] +EOF + + print_success "Dockerfile created" +} + +# Create the build script that runs inside the container +create_container_build_script() { + cat > "$BUILD_DIR/build-in-container.sh" << 'EOF' +#!/bin/bash + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +print_status() { + echo -e "${BLUE}[CONTAINER]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[CONTAINER SUCCESS]${NC} $1" +} + +print_error() { + echo -e "${RED}[CONTAINER ERROR]${NC} $1" + exit 1 # Exit immediately on error inside the container +} + +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}================================${NC}" +} + +# Configuration +PROJECT_NAME="particleos" +VERSION="1.0.0" +CHROOT_DIR="/tmp/chroot" +ISO_DIR="/tmp/iso" +OUTPUT_DIR="/output" # Mapped from host's OUTPUT_DIR + +# Track mounted filesystems for cleanup inside container's chroot +MOUNTED_FILESYSTEMS_IN_CHROOT=() + +# Cleanup function to unmount filesystems inside the container's chroot +cleanup_chroot_mounts() { + print_status "Cleaning up mounted filesystems in chroot..." + # Iterate in reverse for safer unmounting + for (( i=${#MOUNTED_FILESYSTEMS_IN_CHROOT[@]}-1; i>=0; i-- )); do + mount_point="${MOUNTED_FILESYSTEMS_IN_CHROOT[i]}" + if mountpoint -q "$mount_point" 2>/dev/null; then + print_status "Unmounting $mount_point" + umount "$mount_point" 2>/dev/null || print_error "Failed to unmount $mount_point" + fi + done + MOUNTED_FILESYSTEMS_IN_CHROOT=() +} + +# Signal trap for internal script to ensure cleanup on exit/error +trap cleanup_chroot_mounts EXIT INT TERM + +print_header "Starting Container Build Process" + +# Create directories +mkdir -p "$CHROOT_DIR" "$ISO_DIR" "$OUTPUT_DIR" || print_error "Failed to create necessary directories in container." + +# Ensure chroot directory is clean +rm -rf "$CHROOT_DIR"/* || print_error "Failed to clean chroot directory." + +print_header "Phase 1: Create Base System" + +# Create base system with mmdebstrap +print_status "Creating base Ubuntu system..." +mmdebstrap \ + --architectures=amd64 \ + --variant=apt \ + --include=systemd,systemd-sysv,dbus,curl,ca-certificates,gnupg,locales,resolvconf \ + --mode=unshare \ + noble \ + "$CHROOT_DIR" \ + http://archive.ubuntu.com/ubuntu/ || print_error "mmdebstrap failed." + +print_success "Base system created" + +print_header "Phase 2: Configure Base System" + +# Mount necessary filesystems +# Using 'mount' directly inside the container, it needs root or privileged container mode +mount --bind /dev "$CHROOT_DIR/dev" || print_error "Failed to bind mount /dev." +MOUNTED_FILESYSTEMS_IN_CHROOT+=("$CHROOT_DIR/dev") + +mount --bind /run "$CHROOT_DIR/run" || print_error "Failed to bind mount /run." +MOUNTED_FILESYSTEMS_IN_CHROOT+=("$CHROOT_DIR/run") + +mount -t proc none "$CHROOT_DIR/proc" || print_error "Failed to mount /proc." +MOUNTED_FILESYSTEMS_IN_CHROOT+=("$CHROOT_DIR/proc") + +mount -t sysfs none "$CHROOT_DIR/sys" || print_error "Failed to mount /sys." +MOUNTED_FILESYSTEMS_IN_CHROOT+=("$CHROOT_DIR/sys") + +# Configure package sources +# Corrected chroot bash -c syntax +print_status "Configuring APT sources..." +chroot "$CHROOT_DIR" bash -c ' +echo "deb http://archive.ubuntu.com/ubuntu noble main restricted universe multiverse" > /etc/apt/sources.list && \ +echo "deb http://archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse" >> /etc/apt/sources.list && \ +echo "deb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse" >> /etc/apt/sources.list +' || print_error "Failed to configure APT sources." + +# Add Mozilla PPA for Firefox DEB package (no snap) +print_status "Adding Mozilla PPA for Firefox DEB package..." +# Install software-properties-common in chroot first +chroot "$CHROOT_DIR" apt install -y software-properties-common || print_error "Failed to install software-properties-common." +chroot "$CHROOT_DIR" add-apt-repository -y ppa:mozillateam/ppa || print_error "Failed to add Mozilla PPA." + +# Update package lists +print_status "Updating package lists..." +chroot "$CHROOT_DIR" apt update || print_error "Failed to update package lists." + +# Install desktop and additional packages (enhanced with ostree and bootc) +print_status "Installing desktop environment and essential packages..." +chroot "$CHROOT_DIR" DEBIAN_FRONTEND=noninteractive apt install -y \ + kubuntu-desktop \ + plasma-desktop \ + plasma-workspace \ + kde-plasma-desktop \ + sddm \ + ostree \ + bootc \ + flatpak \ + network-manager \ + plasma-nm \ + openssh-server \ + curl \ + wget \ + vim \ + nano \ + htop \ + neofetch \ + tree \ + firefox \ + pulseaudio \ + pulseaudio-utils \ + fonts-ubuntu \ + fonts-noto \ + build-essential \ + git \ + live-boot \ + live-config \ + casper \ + systemd-sysv \ + dbus \ + locales \ + resolvconf || print_error "Failed to install desktop and essential packages." + +# Download and install apt-ostree from custom repository +print_status "Installing apt-ostree from custom repository directly..." +chroot "$CHROOT_DIR" timeout 60 wget -O /tmp/apt-ostree.deb 'https://git.raines.xyz/robojerk/apt-ostree/raw/branch/main/apt-ostree_0.1.0-1_amd64.deb' || print_error "Failed to download apt-ostree." +chroot "$CHROOT_DIR" dpkg -i /tmp/apt-ostree.deb || chroot "$CHROOT_DIR" apt install -f -y || print_error "Failed to install apt-ostree or fix dependencies." +chroot "$CHROOT_DIR" rm -f /tmp/apt-ostree.deb || print_error "Failed to clean up apt-ostree deb." + +# Enhanced snap removal and blocking +print_status "Removing snapd and setting APT preferences to block snaps..." +chroot "$CHROOT_DIR" DEBIAN_FRONTEND=noninteractive apt purge -y snapd ubuntu-advantage-tools update-notifier update-manager unattended-upgrades || print_error "Failed to purge snapd and related packages." +chroot "$CHROOT_DIR" apt autoremove -y || print_error "Failed to autoremove orphaned packages." +chroot "$CHROOT_DIR" apt-mark hold snapd || print_error "Failed to hold snapd." + +# Create an APT preference file to strongly discourage snapd and ensure Firefox from PPA +chroot "$CHROOT_DIR" bash -c ' +echo "Package: snapd" > /etc/apt/preferences.d/nosnap.pref && \ +echo "Pin: release *" >> /etc/apt/preferences.d/nosnap.pref && \ +echo "Pin-Priority: -1" >> /etc/apt/preferences.d/nosnap.pref && \ +echo "Package: firefox" >> /etc/apt/preferences.d/nosnap.pref && \ +echo "Pin: release o=LP-PPA-mozillateam" >> /etc/apt/preferences.d/nosnap.pref && \ +echo "Pin-Priority: 1000" >> /etc/apt/preferences.d/nosnap.pref +' || print_error "Failed to create APT preference file." + +# Enhanced system configuration +print_status "Configuring system settings..." +chroot "$CHROOT_DIR" bash -c ' +echo "particleos" > /etc/hostname && \ +echo "127.0.0.1 localhost" >> /etc/hosts && \ +echo "127.0.1.1 particleos.local particleos" >> /etc/hosts && \ +ln -sf /usr/share/zoneinfo/UTC /etc/localtime && \ +locale-gen en_US.UTF-8 && \ +update-locale LANG=en_US.UTF-8 +' || print_error "Failed to configure system settings." + +# Create user +print_status "Creating particle user..." +chroot "$CHROOT_DIR" useradd -m -s /bin/bash particle || print_error "Failed to create particle user." +chroot "$CHROOT_DIR" echo 'particle:particle' | chpasswd || print_error "Failed to set particle password." +chroot "$CHROOT_DIR" usermod -aG sudo particle || print_error "Failed to add particle to sudo group." +chroot "$CHROOT_DIR" bash -c "echo 'particle ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/particle" || print_error "Failed to create sudoers file for particle." +chroot "$CHROOT_DIR" chmod 0440 /etc/sudoers.d/particle || print_error "Failed to set permissions for sudoers file." + +# Enhanced service configuration +print_status "Enabling essential services..." +chroot "$CHROOT_DIR" systemctl enable sddm NetworkManager ssh || print_error "Failed to enable essential services." +chroot "$CHROOT_DIR" systemctl disable apt-daily.timer apt-daily-upgrade.timer || print_error "Failed to disable apt daily timers." + +# Enhanced apt-ostree configuration +print_status "Configuring apt-ostree..." +chroot "$CHROOT_DIR" mkdir -p /etc/apt-ostree || print_error "Failed to create apt-ostree config directory." +chroot "$CHROOT_DIR" echo 'ref: particleos/desktop/1.0.0' > /etc/apt-ostree/ref || print_error "Failed to configure apt-ostree ref." + +# Clean up +print_status "Cleaning APT caches and temporary files in chroot..." +chroot "$CHROOT_DIR" apt clean || print_error "Failed to clean apt cache in chroot." +chroot "$CHROOT_DIR" rm -rf /var/lib/apt/lists/* /tmp/* || print_error "Failed to remove apt lists or tmp files in chroot." + +print_success "Base system configured" + +print_header "Phase 3: Create ISO" + +# Unmount filesystems from chroot before creating squashfs +cleanup_chroot_mounts + +# Create ISO directory structure +mkdir -p "$ISO_DIR"/{casper,boot/grub,EFI/BOOT,isolinux} || print_error "Failed to create ISO directory structure." + +# Copy kernel and initrd - more robust lookup +print_status "Copying kernel and initramfs..." +# Find the latest kernel and initrd +KERNEL_PATH=$(find "$CHROOT_DIR/boot" -maxdepth 1 -name "vmlinuz-*" | sort -V | tail -n 1) +INITRD_PATH=$(find "$CHROOT_DIR/boot" -maxdepth 1 -name "initrd.img-*" | sort -V | tail -n 1) + +if [ -z "$KERNEL_PATH" ]; then + print_error "Kernel (vmlinuz-*) not found in $CHROOT_DIR/boot." +fi +if [ -z "$INITRD_PATH" ]; then + print_error "Initrd (initrd.img-*) not found in $CHROOT_DIR/boot." +fi + +cp "$KERNEL_PATH" "$ISO_DIR/casper/vmlinuz" || print_error "Failed to copy kernel." +cp "$INITRD_PATH" "$ISO_DIR/casper/initrd" || print_error "Failed to copy initrd." +print_success "Kernel and initramfs copied." + +# Create filesystem manifest +print_status "Creating filesystem manifest..." +chroot "$CHROOT_DIR" dpkg-query -W --showformat='${Package} ${Version}\n' > "/filesystem.manifest.tmp" || print_error "Failed to create filesystem manifest in chroot." +mv "/filesystem.manifest.tmp" "$ISO_DIR/casper/filesystem.manifest" || print_error "Failed to move filesystem manifest." +print_success "Filesystem manifest created." + +# Create filesystem size +print_status "Calculating filesystem size..." +du -sx --block-size=1 "$CHROOT_DIR" | cut -f1 > "$ISO_DIR/casper/filesystem.size" || print_error "Failed to create filesystem.size." +print_success "Filesystem size calculated." + +# Create squashfs +print_status "Creating squashfs filesystem..." +# Ensure chroot mounts are truly clean before this step +if mountpoint -q "$CHROOT_DIR/dev" || mountpoint -q "$CHROOT_DIR/run" || mountpoint -q "$CHROOT_DIR/proc" || mountpoint -q "$CHROOT_DIR/sys"; then + print_error "Chroot mounts are still active before mksquashfs. This should not happen." +fi +mksquashfs "$CHROOT_DIR" "$ISO_DIR/casper/filesystem.squashfs" -comp xz -e boot || print_error "Failed to create squashfs filesystem." +print_success "Squashfs created." + +# Create GRUB configuration +cat > "$ISO_DIR/boot/grub/grub.cfg" << 'GRUBEOF' +set timeout=10 +set default=0 + +menuentry "Try ParticleOS without installing" { + linux /casper/vmlinuz boot=casper quiet splash --- + initrd /casper/initrd +} + +menuentry "Install ParticleOS" { + linux /casper/vmlinuz boot=casper quiet splash --- + initrd /casper/initrd +} + +menuentry "Check disc for defects" { + linux /casper/vmlinuz boot=casper integrity-check quiet splash --- + initrd /casper/initrd +} +GRUBEOF +print_success "GRUB configuration created." + + +# Create ISOLINUX configuration +cat > "$ISO_DIR/isolinux/isolinux.cfg" << 'ISOLINUXEOF' +DEFAULT live +TIMEOUT 300 +PROMPT 1 + +LABEL live + MENU LABEL Try ParticleOS without installing + KERNEL /casper/vmlinuz + APPEND boot=casper initrd=/casper/initrd quiet splash --- + +LABEL live-install + MENU LABEL Install ParticleOS + KERNEL /casper/vmlinuz + APPEND boot=casper initrd=/casper/initrd quiet splash --- + +LABEL check + MENU LABEL Check disc for defects + KERNEL /casper/vmlinuz + APPEND boot=casper integrity-check initrd=/casper/initrd quiet splash --- +ISOLINUXEOF +print_success "ISOLINUX configuration created." + +# Copy ISOLINUX boot files - more robust lookup +print_status "Copying ISOLINUX boot files..." +ISOLINUX_BIN_HOST_PATH=$(find /usr/lib/syslinux -name isolinux.bin -print -quit || find /usr/lib/ISOLINUX -name isolinux.bin -print -quit) +BOOT_CAT_HOST_PATH=$(find /usr/lib/syslinux -name boot.cat -print -quit || find /usr/lib/ISOLINUX -name boot.cat -print -quit) +ISOHDPFX_BIN_HOST_PATH=$(find /usr/lib/syslinux -name isohdpfx.bin -print -quit || find /usr/lib/ISOLINUX -name isohdpfx.bin -print -quit) + +if [ -z "$ISOLINUX_BIN_HOST_PATH" ]; then print_error "isolinux.bin not found. Install isolinux."; fi +if [ -z "$BOOT_CAT_HOST_PATH" ]; then print_error "boot.cat not found. Install isolinux."; fi +if [ -z "$ISOHDPFX_BIN_HOST_PATH" ]; then print_error "isohdpfx.bin not found. Install isolinux."; fi + + +cp "$ISOLINUX_BIN_HOST_PATH" "$ISO_DIR/isolinux/" || print_error "Failed to copy isolinux.bin." +cp "$BOOT_CAT_HOST_PATH" "$ISO_DIR/isolinux/" || print_error "Failed to copy boot.cat." +print_success "ISOLINUX boot files copied." + +# Create EFI boot image (for UEFI) using grub-mkimage +print_status "Creating EFI boot image..." +GRUB_EFI_MODULES_DIR="/usr/lib/grub/x86_64-efi" +if [ ! -d "$GRUB_EFI_MODULES_DIR" ]; then + print_error "GRUB EFI modules directory not found at $GRUB_EFI_MODULES_DIR. Cannot create EFI boot image. Check grub-efi-amd64-bin installation." +fi + +# Create a temporary directory for grub output +GRUB_EFI_TMP_DIR=$(mktemp -d) +mkdir -p "$ISO_DIR/EFI/BOOT" + +# Create efi.img for bootx64.efi +# This creates a combined EFI image that can be directly used as -e option for xorriso +grub-mkimage \ + -o "$ISO_DIR/boot/grub/efi.img" \ + -p "/boot/grub" \ + -O i386-efi \ + -m "$GRUB_EFI_TMP_DIR/grub.img" \ + --config-file="$ISO_DIR/boot/grub/grub.cfg" \ + boot linux normal configfile part_gpt part_msdos fat \ + squash4 loopback_luks test configfile search loadenv \ + efi_gop efi_uga all_video gfxterm_menu gfxterm_background \ + chain btrfs zfs iso9660 + # Include common modules, adjust as needed + +cp "$GRUB_EFI_TMP_DIR/grubx64.efi" "$ISO_DIR/EFI/BOOT/bootx64.efi" || print_error "Failed to copy grubx64.efi." +rm -rf "$GRUB_EFI_TMP_DIR" # Clean up temp directory + +print_success "EFI boot image created." + + +# Create ISO +print_status "Creating bootable ISO using xorriso..." +xorriso -as mkisofs \ + -o "$OUTPUT_DIR/${PROJECT_NAME}-${VERSION}.iso" \ + -J -joliet-long \ + -r -V "ParticleOS ${VERSION}" \ + -b isolinux/isolinux.bin \ + -c isolinux/boot.cat \ + -boot-load-size 4 -boot-info-table \ + -no-emul-boot -eltorito-alt-boot \ + -e boot/grub/efi.img -no-emul-boot \ + -isohybrid-mbr "$ISOHDPFX_BIN_HOST_PATH" \ + -partition_offset 16 \ + -part_like_isohybrid \ + "$ISO_DIR" || print_error "Failed to create ISO with xorriso." + +print_success "ISO created successfully: $OUTPUT_DIR/${PROJECT_NAME}-${VERSION}.iso" + +# Clean up temporary directories within the container +print_status "Cleaning up temporary directories in container..." +rm -rf "$CHROOT_DIR" "$ISO_DIR" || print_error "Failed to remove temporary directories in container." + +print_header "Container Build Complete!" +echo "๐ŸŽ‰ ParticleOS ISO built successfully in container!" +echo "๐Ÿ“ Location: $OUTPUT_DIR/particleos-$VERSION.iso" +EOF + + chmod +x "$BUILD_DIR/build-in-container.sh" + print_success "Container build script created" +} + +# Build the container image +build_container_image() { + print_header "Phase 5: Build Container Image" + + print_status "Building container image '$IMAGE_NAME'..." + cd "$BUILD_DIR" + + # Use || print_error instead of full if/else for cleaner code + $PODMAN_CMD build -t "$IMAGE_NAME" . || print_error "Failed to build container image '$IMAGE_NAME'." + + print_success "Container image built successfully" +} + +# Run the build in the container +run_container_build() { + print_header "Phase 6: Run Build in Container" + + print_status "Starting build in isolated container '$CONTAINER_NAME'..." + + # Run the container with volume mounts + # Added --privileged for mmdebstrap/chroot/mount/mksquashfs within container. + # --userns=host for better compatibility with privileged operations in some cases. + $PODMAN_CMD run \ + --name "$CONTAINER_NAME" \ + --rm \ + --privileged \ + --userns=host \ + -v "$OUTPUT_DIR:/output:Z" \ + "$IMAGE_NAME" || print_error "Container build failed. Check container logs for details." + + print_success "Container build completed successfully" +} + +# Cleanup function (for host-side Podman resources) +cleanup() { + print_status "Cleaning up Podman container and image..." + + # Remove container if it exists + if $PODMAN_CMD container exists "$CONTAINER_NAME" 2>/dev/null; then + print_status "Removing container: $CONTAINER_NAME" + $PODMAN_CMD container rm -f "$CONTAINER_NAME" 2>/dev/null || true + fi + + # Remove image if it exists. Be careful here, sometimes you want to keep the image. + # For a clean build process, removing it ensures fresh start next time. + if $PODMAN_CMD image exists "$IMAGE_NAME" 2>/dev/null; then + print_status "Removing image: $IMAGE_NAME" + $PODMAN_CMD image rm -f "$IMAGE_NAME" 2>/dev/null || true + fi + + print_success "Podman resources cleaned." +} + +# Signal trap for cleanup +trap cleanup EXIT INT TERM + +# Main execution +main() { + echo "๐Ÿš€ ParticleOS ISO Builder (Podman) - HARDENED ULTRA SAFE VERSION" + echo "==============================================================" + echo "Project: $PROJECT_NAME" + echo "Version: $VERSION" + echo "Build Directory: $BUILD_DIR" + echo "Tool: Podman (Containerized)" + echo "" + echo "๐Ÿ›ก๏ธ This build runs in a completely isolated container" + echo "๐Ÿ›ก๏ธ Your host system cannot be affected by this build" + echo "๐Ÿ›ก๏ธ Includes all hardening features from the analysis" + echo "๐Ÿ›ก๏ธ Firefox installed as DEB package (no snap)" + echo "" + + # Call cleanup explicitly at the start to ensure a clean slate before attempting new build + cleanup # This will also remove image from previous failed runs. + + check_podman + check_prerequisites + clean_build # This cleans host-side directories, but cleanup() handles Podman resources. + create_dockerfile + create_container_build_script + build_container_image + run_container_build + + print_header "Build Complete!" + echo "" + echo "๐ŸŽ‰ ParticleOS ISO built successfully!" + echo "๐Ÿ“ Location: $OUTPUT_DIR/particleos-$VERSION.iso" + echo "" + echo "๐Ÿงช Test the ISO:" + echo " qemu-system-x86_64 -m 4G -enable-kvm \\" + echo " -cdrom $OUTPUT_DIR/particleos-$VERSION.iso \\" + echo " -boot d" + echo "" + echo "๐Ÿ›ก๏ธ Your host system is completely safe!" +} + +# Run main function +main "$@" \ No newline at end of file diff --git a/build-iso-simple.sh b/build-iso-simple.sh index b1f5f8f..2123163 100644 --- a/build-iso-simple.sh +++ b/build-iso-simple.sh @@ -1,5 +1,6 @@ #!/bin/bash - +ehco "Do not use. NOT SAFE!" +exit # ParticleOS Simple ISO Builder # Builds a bootable ISO using traditional methods + apt-ostree integration diff --git a/test-environment.sh b/test-environment.sh new file mode 100755 index 0000000..1898ccc --- /dev/null +++ b/test-environment.sh @@ -0,0 +1,149 @@ +#!/bin/bash + +# Test Environment for ParticleOS Build +# Verifies system is ready for safe building + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +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" +} + +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}================================${NC}" +} + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_DIR="$SCRIPT_DIR/build" + +echo "๐Ÿ” ParticleOS Environment Test" +echo "==============================" +echo "Testing system readiness for safe building" +echo "" + +# Test 1: Check if we're in a safe directory +print_header "Test 1: Directory Safety" +if [[ "$SCRIPT_DIR" == "/" ]] || [[ "$SCRIPT_DIR" == "/home" ]] || [[ "$SCRIPT_DIR" == "/opt" ]]; then + print_error "Script is in a critical system directory: $SCRIPT_DIR" + exit 1 +fi +print_success "Script directory is safe: $SCRIPT_DIR" + +# Test 2: Check disk space +print_header "Test 2: Disk Space" +available_space=$(df "$SCRIPT_DIR" | awk 'NR==2 {print $4}') +available_gb=$((available_space / 1024 / 1024)) +required_gb=10 + +echo "Available space: ${available_gb}GB" +echo "Required space: ${required_gb}GB" + +if [ "$available_space" -lt $((required_gb * 1024 * 1024)) ]; then + print_error "Insufficient disk space. Need at least ${required_gb}GB free" + exit 1 +fi +print_success "Sufficient disk space available" + +# Test 3: Check for existing build artifacts +print_header "Test 3: Existing Build Artifacts" +if [ -d "$BUILD_DIR" ]; then + print_warning "Existing build directory found: $BUILD_DIR" + echo "This will be removed during the build process" +else + print_success "No existing build directory found" +fi + +# Test 4: Check for mounted filesystems +print_header "Test 4: Mounted Filesystems" +if mount | grep -q "$BUILD_DIR"; then + print_error "Found mounted filesystems in build directory" + mount | grep "$BUILD_DIR" + exit 1 +fi +print_success "No problematic mounts found" + +# Test 5: Check build prerequisites +print_header "Test 5: Build Prerequisites" +missing_packages=() + +for package in mmdebstrap squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin; do + if ! dpkg -s "$package" &>/dev/null; then + missing_packages+=("$package") + fi +done + +if [ ${#missing_packages[@]} -gt 0 ]; then + print_warning "Missing packages: ${missing_packages[*]}" + echo "These will be installed during the build process" +else + print_success "All required packages are installed" +fi + +# Test 6: Check ISOLINUX +print_header "Test 6: ISOLINUX" +if [ ! -f "/usr/lib/ISOLINUX/isohdpfx.bin" ]; then + print_warning "ISOLINUX isohdpfx.bin not found" + echo "This may be installed as part of the build process" +else + print_success "ISOLINUX found" +fi + +# Test 7: Check network connectivity +print_header "Test 7: Network Connectivity" +if ping -c 1 archive.ubuntu.com &>/dev/null; then + print_success "Can reach Ubuntu archives" +else + print_error "Cannot reach Ubuntu archives" + exit 1 +fi + +if curl -s -I "https://git.raines.xyz/robojerk/apt-ostree/raw/branch/main/apt-ostree_0.1.0-1_amd64.deb" | head -n 1 | grep "HTTP/[12] [23].." > /dev/null; then + print_success "Can reach apt-ostree repository" +else + print_error "Cannot reach apt-ostree repository" + exit 1 +fi + +# Test 8: Check sudo access +print_header "Test 8: Sudo Access" +if sudo -n true 2>/dev/null; then + print_success "Sudo access confirmed" +else + print_warning "Sudo access may require password" + echo "The build process will require sudo privileges" +fi + +echo "" +print_success "Environment test completed successfully!" +echo "" +echo "โœ… System is ready for safe building" +echo "๐Ÿš€ You can now run: ./build-iso-mmdebstrap-safe.sh" +echo "" +echo "โš ๏ธ Important safety notes:" +echo " - The build process will use sudo" +echo " - A large amount of disk space will be used" +echo " - The process may take 30-60 minutes" +echo " - You can safely interrupt with Ctrl+C at any time" \ No newline at end of file diff --git a/test-podman-environment.sh b/test-podman-environment.sh new file mode 100755 index 0000000..502e68d --- /dev/null +++ b/test-podman-environment.sh @@ -0,0 +1,183 @@ +#!/bin/bash + +# Test Podman Environment for ParticleOS Build +# Verifies system is ready for safe containerized building + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +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" +} + +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}================================${NC}" +} + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_DIR="$SCRIPT_DIR/build" + +echo "๐Ÿ” ParticleOS Podman Environment Test" +echo "=====================================" +echo "Testing system readiness for safe containerized building" +echo "" + +# Test 1: Check if we're in a safe directory +print_header "Test 1: Directory Safety" +if [[ "$SCRIPT_DIR" == "/" ]] || [[ "$SCRIPT_DIR" == "/home" ]] || [[ "$SCRIPT_DIR" == "/opt" ]]; then + print_error "Script is in a critical system directory: $SCRIPT_DIR" + exit 1 +fi +print_success "Script directory is safe: $SCRIPT_DIR" + +# Test 2: Check disk space +print_header "Test 2: Disk Space" +available_space=$(df "$SCRIPT_DIR" | awk 'NR==2 {print $4}') +available_gb=$((available_space / 1024 / 1024)) +required_gb=15 + +echo "Available space: ${available_gb}GB" +echo "Required space: ${required_gb}GB" + +if [ "$available_space" -lt $((required_gb * 1024 * 1024)) ]; then + print_error "Insufficient disk space. Need at least ${required_gb}GB free" + exit 1 +fi +print_success "Sufficient disk space available" + +# Test 3: Check for existing build artifacts +print_header "Test 3: Existing Build Artifacts" +if [ -d "$BUILD_DIR" ]; then + print_warning "Existing build directory found: $BUILD_DIR" + echo "This will be removed during the build process" +else + print_success "No existing build directory found" +fi + +# Test 4: Check Podman availability +print_header "Test 4: Podman Availability" +if ! command -v podman &> /dev/null; then + print_error "Podman is not installed" + echo "Please install Podman: sudo apt update && sudo apt install -y podman" + exit 1 +fi +print_success "Podman is installed" + +# Test 5: Check Podman permissions +print_header "Test 5: Podman Permissions" +if podman info &> /dev/null; then + PODMAN_CMD="podman" + print_success "Podman can run without sudo" +else + PODMAN_CMD="sudo podman" + print_warning "Podman requires sudo (this is normal)" +fi +echo "Podman command: $PODMAN_CMD" + +# Test 6: Test Podman functionality +print_header "Test 6: Podman Functionality" +if $PODMAN_CMD version &> /dev/null; then + print_success "Podman is working correctly" +else + print_error "Podman is not working correctly" + exit 1 +fi + +# Test 7: Check network connectivity +print_header "Test 7: Network Connectivity" +if ping -c 1 archive.ubuntu.com &>/dev/null; then + print_success "Can reach Ubuntu archives" +else + print_error "Cannot reach Ubuntu archives" + exit 1 +fi + +if curl -s -I "https://git.raines.xyz/robojerk/apt-ostree/raw/branch/main/apt-ostree_0.1.0-1_amd64.deb" | head -n 1 | grep "HTTP/[12] [23].." > /dev/null; then + print_success "Can reach apt-ostree repository" +else + print_error "Cannot reach apt-ostree repository" + exit 1 +fi + +# Test 8: Check for existing containers/images +print_header "Test 8: Existing Containers/Images" +if $PODMAN_CMD container exists particleos-builder 2>/dev/null; then + print_warning "Existing container 'particleos-builder' found" + echo "This will be removed during the build process" +else + print_success "No existing particleos-builder container found" +fi + +if $PODMAN_CMD image exists particleos-builder:latest 2>/dev/null; then + print_warning "Existing image 'particleos-builder:latest' found" + echo "This will be removed during the build process" +else + print_success "No existing particleos-builder image found" +fi + +# Test 9: Test container creation +print_header "Test 9: Container Creation Test" +if $PODMAN_CMD run --rm --name test-container ubuntu:22.04 echo "test" &> /dev/null; then + print_success "Container creation test passed" +else + print_error "Container creation test failed" + exit 1 +fi + +# Test 10: Check volume mounting +print_header "Test 10: Volume Mounting Test" +TEST_DIR="/tmp/particleos-test-$$" +mkdir -p "$TEST_DIR" +echo "test" > "$TEST_DIR/test.txt" + +if $PODMAN_CMD run --rm -v "$TEST_DIR:/test:Z" ubuntu:22.04 cat /test/test.txt 2>/dev/null | grep -q "test"; then + print_success "Volume mounting test passed" +else + print_error "Volume mounting test failed" + rm -rf "$TEST_DIR" + exit 1 +fi + +rm -rf "$TEST_DIR" + +echo "" +print_success "Podman environment test completed successfully!" +echo "" +echo "โœ… System is ready for safe containerized building" +echo "๐Ÿš€ You can now run: ./build-iso-podman.sh" +echo "" +echo "๐Ÿ›ก๏ธ Safety features of this approach:" +echo " - Complete isolation from host system" +echo " - No sudo chroot commands on host" +echo " - No filesystem mounting on host" +echo " - Container is automatically cleaned up" +echo " - Host system cannot be affected" +echo "" +echo "โš ๏ธ Important notes:" +echo " - The build process will use Podman" +echo " - A large amount of disk space will be used (15GB+)" +echo " - The process may take 30-60 minutes" +echo " - You can safely interrupt with Ctrl+C at any time" +echo " - The container will be automatically cleaned up" \ No newline at end of file diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..3ddc116 --- /dev/null +++ b/todo.md @@ -0,0 +1,125 @@ +# ParticleOS Installer - TODO List +Just remove completed tasks to keep the file tidy. + +NO snapd +remove firefox, it is a snap +Discuss removing AppArmor and use SELinux? + +## ๐Ÿš€ **High Priority** + +### Core Functionality +- [x] **Base System**: Ubuntu Noble (24.04) base +- [x] **Desktop Environment**: KDE Plasma with ParticleOS branding +- [x] **Package Management**: apt-ostree integration +- [x] **Snap Blocking**: Prevent snapd installation and usage +- [x] **ISO Building**: Create bootable live ISO +- [x] **Safety Measures**: Podman containerization for build process + +### Build System +- [x] **Containerized Build**: Use Podman for isolated builds +- [x] **Error Handling**: Comprehensive error checking and cleanup +- [x] **Safety Checks**: Validate environment before building +- [x] **Cleanup**: Proper cleanup of containers and mounts + +## ๐Ÿ”ง **Medium Priority** + +### System Configuration +- [ ] **User Setup**: Create default user with proper permissions +- [ ] **Network Configuration**: Configure networking for live system +- [ ] **Services**: Enable/disable appropriate system services +- [ ] **Locale**: Set up proper locale and timezone +- [ ] **Hostname**: Set ParticleOS hostname + +### Package Management +- [ ] **apt-ostree Repository**: Set up proper repository configuration +- [ ] **Package Selection**: Curate list of included packages +- [ ] **Dependencies**: Ensure all dependencies are properly resolved +- [ ] **Updates**: Configure update mechanism for installed system + +### ISO Features +- [ ] **Boot Options**: Multiple boot options (try, install, check) +- [ ] **Installation**: bootc-based installation process +- [ ] **Persistence**: Optional persistent storage for live system +- [ ] **Encryption**: Support for encrypted installations + +## ๐ŸŽจ **Low Priority** + +### Branding and Customization +- [ ] **Boot Splash**: Custom boot splash screen +- [ ] **Wallpaper**: ParticleOS branded wallpaper +- [ ] **Icons**: Custom application icons +- [ ] **Theme**: Consistent visual theme throughout +- [ ] **Documentation**: User and developer documentation + +### Advanced Features +- [ ] **Atomic Updates**: Implement atomic update system +- [ ] **Rollback**: System rollback functionality +- [ ] **Backup**: Automated backup system +- [ ] **Monitoring**: System health monitoring +- [ ] **Logging**: Comprehensive logging system + +## ๐Ÿงช **Testing and Quality** + +### Testing +- [ ] **ISO Testing**: Test ISO in various environments +- [ ] **Installation Testing**: Test installation process +- [ ] **Update Testing**: Test update mechanisms +- [ ] **Performance Testing**: Benchmark system performance +- [ ] **Compatibility Testing**: Test with various hardware + +### Documentation +- [ ] **README**: Comprehensive project documentation +- [ ] **Build Guide**: Step-by-step build instructions +- [ ] **User Guide**: End-user documentation +- [ ] **Developer Guide**: Developer documentation +- [ ] **Troubleshooting**: Common issues and solutions + +## ๐Ÿ”’ **Security** + +### Security Features +- [ ] **Secure Boot**: UEFI Secure Boot support +- [ ] **Disk Encryption**: Full disk encryption support +- [ ] **Firewall**: Default firewall configuration +- [ ] **Updates**: Security update mechanism +- [ ] **Audit**: Security audit and compliance + +## ๐Ÿ“ฆ **Distribution** + +### Release Management +- [ ] **Versioning**: Semantic versioning system +- [ ] **Release Notes**: Automated release notes generation +- [ ] **Checksums**: Provide checksums for downloads +- [ ] **Signing**: GPG signing of releases +- [ ] **Mirrors**: Set up download mirrors + +### CI/CD +- [ ] **Automated Builds**: GitHub Actions or similar +- [ ] **Testing Pipeline**: Automated testing +- [ ] **Release Pipeline**: Automated releases +- [ ] **Quality Gates**: Quality checks before release + +## ๐ŸŽฏ **Future Enhancements** + +### Advanced Features +- [ ] **Container Support**: Native container runtime +- [ ] **Cloud Integration**: Cloud deployment options +- [ ] **IoT Support**: Internet of Things capabilities +- [ ] **Edge Computing**: Edge computing features +- [ ] **AI/ML**: Machine learning toolchain + +### Ecosystem +- [ ] **Software Center**: Application store +- [ ] **Developer Tools**: Development environment +- [ ] **Gaming**: Gaming support and optimization +- [ ] **Multimedia**: Enhanced multimedia support +- [ ] **Accessibility**: Accessibility features + +--- + +## ๐Ÿ“ **Notes** + +- **Priority**: High priority items should be completed before medium priority +- **Dependencies**: Some items depend on others being completed first +- **Testing**: All features should be thoroughly tested before release +- **Documentation**: Documentation should be updated as features are added +- **Security**: Security should be considered for all features \ No newline at end of file