Monorepo for Aesthetic.Computer
aesthetic.computer
1#!/bin/bash
2# flash-usb.sh — Write a FedAC ISO (or any ISO) to USB with verification
3#
4# Usage:
5# bash fedac/scripts/flash-usb.sh <iso-path> <device>
6# bash fedac/scripts/flash-usb.sh fedac-thinkpad.iso /dev/sdb
7#
8# Safety:
9# - Refuses to write to /dev/sda or /dev/nvme0n1 (likely system disks)
10# - Shows device info before writing
11# - Requires explicit confirmation
12# - Verifies write integrity after completion
13
14set -euo pipefail
15
16RED='\033[0;31m'
17GREEN='\033[0;32m'
18YELLOW='\033[1;33m'
19CYAN='\033[0;36m'
20NC='\033[0m'
21
22usage() {
23 echo "Usage: $0 <iso-path> <device>"
24 echo ""
25 echo "Examples:"
26 echo " $0 fedac-thinkpad.iso /dev/sdb"
27 echo " $0 Fedora-Workstation-Live-x86_64-41.iso /dev/sdc"
28 echo ""
29 echo "Options:"
30 echo " --yes Skip confirmation prompt"
31 echo " --help Show this help"
32 exit 1
33}
34
35# Parse args
36ISO=""
37DEVICE=""
38SKIP_CONFIRM=false
39
40for arg in "$@"; do
41 case "$arg" in
42 --yes) SKIP_CONFIRM=true ;;
43 --help|-h) usage ;;
44 *)
45 if [ -z "$ISO" ]; then
46 ISO="$arg"
47 elif [ -z "$DEVICE" ]; then
48 DEVICE="$arg"
49 fi
50 ;;
51 esac
52done
53
54[ -n "$ISO" ] || { echo -e "${RED}Error: No ISO specified${NC}"; usage; }
55[ -n "$DEVICE" ] || { echo -e "${RED}Error: No device specified${NC}"; usage; }
56
57# Validate ISO exists
58[ -f "$ISO" ] || { echo -e "${RED}Error: ISO not found: $ISO${NC}"; exit 1; }
59
60# Validate device is a block device
61[ -b "$DEVICE" ] || { echo -e "${RED}Error: Not a block device: $DEVICE${NC}"; exit 1; }
62
63# Safety: refuse to write to common system disks
64DANGEROUS_DEVICES="/dev/sda /dev/nvme0n1 /dev/vda /dev/xvda"
65for dangerous in $DANGEROUS_DEVICES; do
66 if [ "$DEVICE" = "$dangerous" ]; then
67 echo -e "${RED}REFUSED: $DEVICE is likely your system disk.${NC}"
68 echo "If you really want to write to this device, use dd manually."
69 exit 1
70 fi
71done
72
73# Show what we're about to do
74echo -e "${CYAN}=== FedAC USB Flasher ===${NC}"
75echo ""
76echo -e "ISO: ${GREEN}$ISO${NC}"
77echo -e "Device: ${YELLOW}$DEVICE${NC}"
78echo ""
79
80# Show device details
81echo -e "${CYAN}Device info:${NC}"
82lsblk "$DEVICE" 2>/dev/null || true
83echo ""
84
85# Show ISO size
86ISO_SIZE=$(stat -c%s "$ISO" 2>/dev/null || stat -f%z "$ISO" 2>/dev/null)
87ISO_SIZE_MB=$((ISO_SIZE / 1048576))
88echo -e "ISO size: ${GREEN}${ISO_SIZE_MB} MB${NC}"
89echo ""
90
91# Verify ISO checksum if .sha256 file exists
92if [ -f "${ISO}.sha256" ]; then
93 echo -e "${CYAN}Verifying ISO checksum...${NC}"
94 if sha256sum -c "${ISO}.sha256" 2>/dev/null; then
95 echo -e "${GREEN}Checksum OK${NC}"
96 else
97 echo -e "${RED}CHECKSUM FAILED — ISO may be corrupted${NC}"
98 echo "Aborting. Re-download the ISO and try again."
99 exit 1
100 fi
101 echo ""
102fi
103
104# Confirm
105if [ "$SKIP_CONFIRM" = false ]; then
106 echo -e "${RED}WARNING: ALL DATA ON $DEVICE WILL BE DESTROYED${NC}"
107 read -p "Continue? [y/N] " confirm
108 if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
109 echo "Aborted."
110 exit 0
111 fi
112fi
113
114# Unmount any mounted partitions on the device
115echo -e "${CYAN}Unmounting partitions...${NC}"
116for part in "${DEVICE}"*; do
117 umount "$part" 2>/dev/null || true
118done
119
120# Write ISO to device
121echo -e "${CYAN}Writing ISO to $DEVICE...${NC}"
122echo "(This may take several minutes)"
123echo ""
124
125if command -v pv &>/dev/null; then
126 # Use pv for progress if available
127 sudo sh -c "pv '$ISO' | dd of='$DEVICE' bs=4M oflag=sync"
128else
129 # Fall back to dd with status=progress
130 sudo dd if="$ISO" of="$DEVICE" bs=4M status=progress oflag=sync
131fi
132
133echo ""
134echo -e "${CYAN}Syncing...${NC}"
135sync
136
137# Verify the write
138echo -e "${CYAN}Verifying write...${NC}"
139BLOCKS=$((ISO_SIZE / 4194304))
140[ "$BLOCKS" -lt 1 ] && BLOCKS=1
141
142ISO_HASH=$(sha256sum "$ISO" | cut -d' ' -f1)
143DEVICE_HASH=$(sudo dd if="$DEVICE" bs=4M count="$BLOCKS" 2>/dev/null | sha256sum | cut -d' ' -f1)
144
145if [ "$ISO_HASH" = "$DEVICE_HASH" ]; then
146 echo -e "${GREEN}VERIFIED — write matches ISO${NC}"
147else
148 echo -e "${YELLOW}WARNING: Verification mismatch!${NC}"
149 echo "ISO hash: $ISO_HASH"
150 echo "Device hash: $DEVICE_HASH"
151 echo "The USB may still work, but re-flash if you have issues."
152fi
153
154# Eject
155echo ""
156sync
157sudo eject "$DEVICE" 2>/dev/null || true
158echo -e "${GREEN}Done. Remove USB and boot the target machine.${NC}"