we did stuff I guess

This commit is contained in:
robojerk 2025-07-22 08:20:05 +00:00
parent b057d003fb
commit 370df6255d
9 changed files with 2103 additions and 8 deletions

108
.gitignore vendored Normal file
View file

@ -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

View file

@ -66,13 +66,7 @@ packages:
- fonts-noto - fonts-noto
- fonts-noto-cjk - fonts-noto-cjk
# Additional applications
- firefox
- thunderbird
- libreoffice
- gimp
- vlc
- transmission-gtk
# Package exclusions (conflicts or unwanted packages) # Package exclusions (conflicts or unwanted packages)
exclude: exclude:

553
build-iso-mmdebstrap-hardened.sh Executable file
View file

@ -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 "$@"

324
build-iso-mmdebstrap-safe.sh Executable file
View file

@ -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 "$@"

658
build-iso-podman.sh Executable file
View file

@ -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 "$@"

View file

@ -1,5 +1,6 @@
#!/bin/bash #!/bin/bash
ehco "Do not use. NOT SAFE!"
exit
# ParticleOS Simple ISO Builder # ParticleOS Simple ISO Builder
# Builds a bootable ISO using traditional methods + apt-ostree integration # Builds a bootable ISO using traditional methods + apt-ostree integration

149
test-environment.sh Executable file
View file

@ -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"

183
test-podman-environment.sh Executable file
View file

@ -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"

125
todo.md Normal file
View file

@ -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