#!/bin/bash # Fix Alpine Boot for Automatic Backup set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color 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_status "Fixing Alpine Boot Configuration for Automatic Backup" echo "========================================================" USB_DRIVE="/dev/sda" # Mount USB partitions BOOT_MOUNT="/tmp/fix_boot_$$" DATA_MOUNT="/tmp/fix_data_$$" mkdir -p "$BOOT_MOUNT" "$DATA_MOUNT" sudo mount "${USB_DRIVE}1" "$BOOT_MOUNT" sudo mount "${USB_DRIVE}2" "$DATA_MOUNT" print_status "Creating proper GRUB configuration..." # Create a better GRUB configuration sudo tee "$BOOT_MOUNT/boot/grub/grub.cfg" > /dev/null << 'EOF' set timeout=10 set default=0 menuentry "Automatic System Backup" { linux /boot/vmlinuz-lts modules=loop,squashfs,sd-mod,usb-storage quiet nomodeset console=tty0 alpine_dev=sda2:ext4 alpine_repo=http://dl-cdn.alpinelinux.org/alpine/v3.18/main/ modloop=/boot/modloop-lts apkovl=/backup-tools/alpine.apkovl.tar.gz autobackup=yes initrd /boot/initramfs-lts } menuentry "Manual Backup Shell" { linux /boot/vmlinuz-lts modules=loop,squashfs,sd-mod,usb-storage console=tty0 alpine_dev=sda2:ext4 alpine_repo=http://dl-cdn.alpinelinux.org/alpine/v3.18/main/ modloop=/boot/modloop-lts apkovl=/backup-tools/alpine.apkovl.tar.gz initrd /boot/initramfs-lts } menuentry "Alpine Linux Recovery" { linux /boot/vmlinuz-lts modules=loop,squashfs,sd-mod,usb-storage console=tty0 initrd /boot/initramfs-lts } EOF print_status "Creating improved Alpine overlay..." # Create a new overlay with better startup script OVERLAY_DIR="/tmp/overlay_$$" mkdir -p "$OVERLAY_DIR"/{etc/init.d,etc/runlevels/default,usr/local/bin,root} # Create the main backup script sudo tee "$OVERLAY_DIR/usr/local/bin/backup-system" > /dev/null << 'EOF' #!/bin/sh # Main backup system script export PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin clear echo "========================================" echo " BOOTABLE BACKUP SYSTEM" echo "========================================" echo # Function to detect drives detect_drives() { echo "Detecting drives..." sleep 3 # Get all block devices echo "Available drives:" echo "==================" lsblk -d -o NAME,SIZE,TYPE,TRAN | head -20 echo # Auto-detect candidates echo "Drive candidates:" echo "Internal drives (non-USB):" lsblk -d -n -o NAME,SIZE,TRAN | grep -v usb | grep -v sda | nl -v 1 echo echo "External drives (USB, excluding boot drive):" lsblk -d -n -o NAME,SIZE,TRAN | grep usb | grep -v sda | nl -v 1 echo } # Function to get user choice get_drives() { # Source drive selection echo "SELECT SOURCE DRIVE (internal drive to backup):" echo "================================================" INTERNAL_LIST=$(lsblk -d -n -o NAME | grep -v sda | grep -v loop) echo "$INTERNAL_LIST" | nl -v 1 echo read -p "Enter source drive number or full path (e.g., /dev/nvme0n1): " SOURCE_INPUT if echo "$SOURCE_INPUT" | grep -q "^[0-9]"; then SOURCE_DRIVE="/dev/$(echo "$INTERNAL_LIST" | sed -n "${SOURCE_INPUT}p")" else SOURCE_DRIVE="$SOURCE_INPUT" fi # Target drive selection echo echo "SELECT TARGET DRIVE (external drive, will be OVERWRITTEN):" echo "==========================================================" EXTERNAL_LIST=$(lsblk -d -n -o NAME | grep -v sda | grep -v loop) echo "$EXTERNAL_LIST" | nl -v 1 echo read -p "Enter target drive number or full path: " TARGET_INPUT if echo "$TARGET_INPUT" | grep -q "^[0-9]"; then TARGET_DRIVE="/dev/$(echo "$EXTERNAL_LIST" | sed -n "${TARGET_INPUT}p")" else TARGET_DRIVE="$TARGET_INPUT" fi } # Function to confirm and backup run_backup() { echo echo "BACKUP CONFIGURATION:" echo "====================" echo "Source: $SOURCE_DRIVE (will be copied FROM)" echo "Target: $TARGET_DRIVE (will be OVERWRITTEN)" echo # Show drive sizes if [ -b "$SOURCE_DRIVE" ]; then SOURCE_SIZE=$(blockdev --getsize64 "$SOURCE_DRIVE" 2>/dev/null || echo "unknown") if [ "$SOURCE_SIZE" != "unknown" ]; then SOURCE_GB=$((SOURCE_SIZE / 1024 / 1024 / 1024)) echo "Source size: ${SOURCE_GB}GB" fi fi if [ -b "$TARGET_DRIVE" ]; then TARGET_SIZE=$(blockdev --getsize64 "$TARGET_DRIVE" 2>/dev/null || echo "unknown") if [ "$TARGET_SIZE" != "unknown" ]; then TARGET_GB=$((TARGET_SIZE / 1024 / 1024 / 1024)) echo "Target size: ${TARGET_GB}GB" fi fi echo echo "⚠️ ALL DATA ON $TARGET_DRIVE WILL BE DESTROYED! ⚠️" echo read -p "Continue with backup? (yes/no): " CONFIRM if [ "$CONFIRM" != "yes" ]; then echo "Backup cancelled" return 1 fi echo echo "Starting backup..." echo "==================" # Check if pv is available for progress if command -v pv >/dev/null 2>&1; then echo "Using pv for progress display" dd if="$SOURCE_DRIVE" bs=4M 2>/dev/null | pv -s "$SOURCE_SIZE" | dd of="$TARGET_DRIVE" bs=4M conv=fdatasync 2>/dev/null else echo "Using dd with status=progress" dd if="$SOURCE_DRIVE" of="$TARGET_DRIVE" bs=4M status=progress conv=fdatasync fi RESULT=$? echo if [ $RESULT -eq 0 ]; then echo "========================================" echo " BACKUP COMPLETED SUCCESSFULLY!" echo "========================================" else echo "========================================" echo " BACKUP FAILED!" echo "========================================" fi echo echo "System will shutdown in 30 seconds..." echo "(Press Ctrl+C to cancel)" # Countdown for i in 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1; do echo -n "$i " sleep 1 done echo echo "Shutting down..." poweroff } # Main execution detect_drives get_drives run_backup EOF chmod +x "$OVERLAY_DIR/usr/local/bin/backup-system" # Create init script that runs on boot sudo tee "$OVERLAY_DIR/etc/init.d/autobackup" > /dev/null << 'EOF' #!/sbin/openrc-run name="autobackup" description="Automatic backup system" depend() { need localmount after bootmisc } start() { # Check if autobackup parameter was passed if grep -q "autobackup=yes" /proc/cmdline; then ebegin "Starting automatic backup system" # Wait for devices to settle sleep 5 # Run backup system /usr/local/bin/backup-system eend $? fi } EOF chmod +x "$OVERLAY_DIR/etc/init.d/autobackup" # Enable the service ln -sf /etc/init.d/autobackup "$OVERLAY_DIR/etc/runlevels/default/autobackup" # Create profile for manual shell access sudo tee "$OVERLAY_DIR/root/.profile" > /dev/null << 'EOF' export PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin echo "========================================" echo " BACKUP SYSTEM SHELL ACCESS" echo "========================================" echo echo "Available commands:" echo " backup-system - Start interactive backup" echo " lsblk - List block devices" echo " fdisk -l - List partitions" echo echo "Manual backup example:" echo " dd if=/dev/nvme0n1 of=/dev/sdb bs=4M status=progress" echo EOF # Create the overlay archive cd "$OVERLAY_DIR" tar czf "$DATA_MOUNT/alpine.apkovl.tar.gz" * cd - # Copy backup tools SCRIPT_DIR=$(dirname "$(realpath "$0")") sudo cp "$SCRIPT_DIR"/*.sh "$DATA_MOUNT/" 2>/dev/null || true # Cleanup sudo umount "$BOOT_MOUNT" "$DATA_MOUNT" rmdir "$BOOT_MOUNT" "$DATA_MOUNT" rm -rf "$OVERLAY_DIR" print_success "Alpine boot configuration fixed!" print_success "USB: $USB_DRIVE" echo print_success "Fixed Issues:" print_success "✅ Proper GRUB kernel parameters" print_success "✅ Correct Alpine overlay loading" print_success "✅ Automatic backup service startup" print_success "✅ Interactive drive selection" print_success "✅ Manual shell access option" echo print_warning "Now test by booting from USB and selecting 'Automatic System Backup'"