main
 1#!/usr/bin/env bash
 2# Deploy an Alpine appliance image to a host.
 3# Usage: ./alpine/deploy.sh <hostname> [update|flash]
 4set -euo pipefail
 5
 6SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
 7HOST="${1:?Usage: $0 <hostname> [update|flash]}"
 8ACTION="${2:-update}"
 9DOMAIN="${DEPLOY_DOMAIN:-.vpn}"
10TARGET="root@${HOST}${DOMAIN}"
11IMAGE_DIR="$SCRIPT_DIR/images/$HOST"
12
13if [ ! -d "$IMAGE_DIR" ]; then
14    echo "Error: no image found for $HOST. Run build.sh first."
15    exit 1
16fi
17
18case "$ACTION" in
19    update)
20        echo "==> Deploying to $HOST via rsync"
21        echo "WARNING: This will update the boot partition. The host will need a reboot."
22        read -p "Continue? [y/N] " -n 1 -r
23        echo
24        [[ $REPLY =~ ^[Yy]$ ]] || exit 0
25
26        # Mount boot partition (diskless Alpine doesn't mount it by default)
27        ssh "${TARGET}" "mkdir -p /boot && mount /dev/mmcblk0p1 /boot 2>/dev/null || true"
28
29        # Backup current files (A/B rollback) — move instead of copy to
30        # free space before uploading the new image
31        ssh "${TARGET}" "mv /boot/initramfs /boot/initramfs.prev 2>/dev/null || true"
32        ssh "${TARGET}" "mv /boot/vmlinuz-rpi /boot/vmlinuz-rpi.prev 2>/dev/null || true"
33
34        # Deploy new files
35        rsync -Pv "$IMAGE_DIR/boot/initramfs" "${TARGET}:/boot/initramfs"
36        rsync -Pv "$IMAGE_DIR/boot/vmlinuz-rpi" "${TARGET}:/boot/vmlinuz-rpi" 2>/dev/null || true
37
38        # Unmount boot partition
39        ssh "${TARGET}" "umount /boot"
40
41        echo "==> Deployed. Reboot $HOST to activate:"
42        echo "    ssh ${TARGET} reboot"
43        echo ""
44        echo "    To rollback: ssh ${TARGET}"
45        echo "      mount -o remount,rw /boot"
46        echo "      mv /boot/initramfs.prev /boot/initramfs"
47        echo "      reboot"
48        ;;
49    flash)
50        echo "==> SD card flashing"
51        echo "Manual steps:"
52        echo "  1. Partition SD: 256MB FAT32 (boot, label=ALPINE) + 512MB ext4 (label=persist)"
53        echo "  2. Copy boot files from $IMAGE_DIR/ to FAT32 partition"
54        echo "  3. Copy SSH host key to persist: persist/ssh/ssh_host_ed25519_key"
55        echo "  4. Copy WireGuard key to persist: persist/wireguard/private.key"
56        ;;
57    *)
58        echo "Unknown action: $ACTION"
59        echo "Usage: $0 <hostname> [update|flash]"
60        exit 1
61        ;;
62esac