Skip to content

Commit 45bc6b6

Browse files
Improve user experience with setup live usb
1 parent 5ef8dc6 commit 45bc6b6

1 file changed

Lines changed: 107 additions & 28 deletions

File tree

scripts/head/setup-live-usb.sh

Lines changed: 107 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,164 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
# ─── COLORS & LOG FUNCTIONS ──────────────────────────────────────────────────
4+
# COLORS & LOG FUNCTIONS
55
GREEN="\e[32m"; YELLOW="\e[33m"; RED="\e[31m"; RESET="\e[0m"
66
log() { echo -e "${GREEN}[+]${RESET} $1"; }
77
warn() { echo -e "${YELLOW}[!]${RESET} $1"; }
88
error() { echo -e "${RED}[-]${RESET} $1"; exit 1; }
99

10-
# ─── ENSURE ROOT & ENABLE TAB COMPLETION ─────────────────────────────────────
10+
log "Live USB creator utility"
11+
12+
# ENSURE ROOT & ENABLE TAB COMPLETION
1113
(( EUID == 0 )) || error "Run as root: sudo $0"
12-
bind 'TAB:complete'
14+
if [[ $- == *i* ]]; then
15+
bind 'TAB:complete'
16+
fi
17+
18+
# DISPLAY BLOCKS
19+
# GLOBAL ASSOCIATIVE ARRAY to store device mappings (index -> device path)
20+
declare -A DEVICES_MAP
21+
# Array to hold raw lsblk output lines, used to avoid subshell issues with DEVICES_MAP
22+
DEVICES_INFO=()
23+
24+
# FUNCTION TO LIST AVAILABLE BLOCK DEVICES WITH INDEXES
25+
list_devices() {
26+
log "Finding devices"
27+
printf "%3s %-8s %-6s %-12s %-8s %-7s %-10s %s\n" "Idx" "Name" "Size" "Model" "Vendor" "Type" "Mountpoint" "RO"
28+
printf "%3s %-8s %-6s %-12s %-8s %-7s %-10s %s\n" "---" "--------" "------" "------------" "--------" "-------" "----------" "--"
29+
30+
local i=1 # Start index from 1
31+
32+
# Populate DEVICES_INFO with lines from lsblk directly into the parent shell.
33+
# We exclude common non-physical/ephemeral device types by their major device numbers.
34+
# -d lists devices only (not partitions).
35+
# -n suppresses headers.
36+
mapfile -t DEVICES_INFO < <(lsblk -o NAME,SIZE,MODEL,VENDOR,TRAN,TYPE,MOUNTPOINT,RO -d -n -e 7,11,9,2,259,1)
37+
38+
# Iterate over the captured lines to print and store mappings
39+
for line in "${DEVICES_INFO[@]}"; do
40+
# Use 'read' with a 'here string' to parse each line
41+
read -r name size model vendor tran type mountpoint ro <<< "$line"
42+
43+
# Remove '/dev/' prefix if present, though lsblk -o NAME usually gives just sda, sdb etc.
44+
local clean_name=$(echo "$name" | sed 's|^/dev/||')
45+
local full_path="/dev/$clean_name"
46+
47+
# Store the mapping: index -> full device path
48+
DEVICES_MAP[$i]="$full_path"
49+
50+
# Print the indexed device information in a formatted way
51+
printf "%3d %-8s %-6s %-12s %-8s %-7s %-10s %s\n" \
52+
"$i" "$clean_name" "$size" "$model" "$vendor" "$type" "$mountpoint" "$ro"
53+
((i++))
54+
done
55+
echo "" # Add a newline for better readability
56+
echo "Enter 0 to quit."
57+
echo ""
58+
}
59+
60+
list_devices
61+
62+
63+
# PROMPT FOR INPUTS
64+
SELECTED_INDEX=""
65+
66+
while true; do
67+
read -p "Select USB device by Idx (e.g., 1): " SELECTED_INDEX
68+
# Check if input is a number
69+
if [[ "$SELECTED_INDEX" =~ ^[0-9]+$ ]]; then
70+
if (( SELECTED_INDEX == 0 )); then
71+
error "Aborted."
72+
exit 0 # Exit if user chooses to quit
73+
elif [[ -n "${DEVICES_MAP[$SELECTED_INDEX]}" ]]; then
74+
# If a valid index is provided, retrieve the full device path
75+
DEV="${DEVICES_MAP[$SELECTED_INDEX]}"
76+
break # Valid selection, exit the loop
77+
else
78+
warn "Invalid index. Please enter a number from the list or 0 to quit."
79+
fi
80+
else
81+
warn "Invalid input. Please enter a number."
82+
fi
83+
done
1384

14-
# ─── PROMPT FOR INPUTS ────────────────────────────────────────────────────────
15-
read -e -p "Path to Ubuntu ISO: " ISO_PATH
16-
[[ -f "$ISO_PATH" ]] || error "ISO not found at '$ISO_PATH'"
85+
# Double-check if the selected device exists, though it should if selected from the list
86+
[[ -b "$DEV" ]] || error "Selected block device '$DEV' not found unexpectedly."
87+
USB_PART="${DEV}1"
1788

18-
read -e -p "Path to autoinstall YAML: " YAML_PATH
19-
[[ -f "$YAML_PATH" ]] || error "YAML not found at '$YAML_PATH'"
89+
read -e -p "Path to ISO: " ISO_PATH
90+
[[ -f "$ISO_PATH" ]] || error "ISO not found at '$ISO_PATH'"
2091

21-
read -e -p "USB device (e.g. /dev/sda): " DEV
22-
[[ -b "$DEV" ]] || error "Block device '$DEV' not found"
23-
USB_PART="${DEV}1"
92+
read -e -p "Optional path to autoinstall YAML (press Enter to skip): " YAML_PATH
93+
if [[ -n "$YAML_PATH" && ! -f "$YAML_PATH" ]]; then
94+
error "YAML not found at '$YAML_PATH'"
95+
fi
2496

2597
cat <<EOF
2698
2799
You are about to:
28100
29-
Wipe & reformat ➜ $DEV
30-
Copy ISO ➜ $ISO_PATH
31-
Copy autoinstall ➜ $YAML_PATH
101+
- Wipe & reformat ➜ $DEV
102+
- Copy ISO ➜ $ISO_PATH
103+
- Copy autoinstall ➜ ${YAML_PATH:-Skipped}
32104
33105
EOF
34106

35107
read -p "Proceed? (yes/[no]) " CONFIRM
36108
[[ "$CONFIRM" == "yes" ]] || { log "Aborted."; exit 0; }
37109

38-
# ─── PREP: UNMOUNT ───────────────────────────────────────────────────────────
110+
# PREP: UNMOUNT
39111
log "Unmounting partitions on $DEV if mounted..."
40112
for p in $(lsblk -lnpo NAME,MOUNTPOINT "${DEV}"* | awk '$2!=""{print $1}'); do
41113
warn " umount $p"
42114
umount "$p" || warn "Could not unmount $p, continuing"
43115
done
44116

45-
# ─── PARTITION & FORMAT ──────────────────────────────────────────────────────
117+
# PARTITION & FORMAT
46118
log "Creating single FAT32 partition on $DEV..."
47119
parted --script "$DEV" \
48120
mklabel msdos \
49121
mkpart primary fat32 1MiB 100% \
50122
set 1 boot on
51123

52124
log "Formatting ${USB_PART} as FAT32..."
53-
mkfs.vfat -F32 "$USB_PART"
125+
mkfs.vfat -F32 "$USB_PART" > /dev/null 2>&1
54126

55-
# ─── MOUNTS ───────────────────────────────────────────────────────────────────
127+
# MOUNTS
56128
MNT_ISO=$(mktemp -d)
57129
MNT_USB=$(mktemp -d)
58130

59131
log "Mounting ISO -> $MNT_ISO"
60-
mount -o loop "$ISO_PATH" "$MNT_ISO"
132+
mount -o loop "$ISO_PATH" "$MNT_ISO" > /dev/null 2>&1
61133

62134
log "Mounting USB -> $MNT_USB"
63135
mount "$USB_PART" "$MNT_USB"
64136

65-
# ─── COPY FILES (follow symlinks) ────────────────────────────────────────────
137+
# COPY FILES
66138
log "Copying ISO contents to USB..."
67-
warn "Symbolic link errors are okay"
68139

69140
set +e
70-
cp -aT "${MNT_ISO}/." "${MNT_USB}/"
141+
cp -aT "${MNT_ISO}/." "${MNT_USB}/" > /dev/null 2>&1
71142
CP_STATUS=$?
72143
set -e
73144

74-
log "Adding autoinstall.yaml to USB root..."
75-
cp "$YAML_PATH" "${MNT_USB}/autoinstall.yaml"
145+
if [[ -n "$YAML_PATH" ]]; then
146+
log "Adding autoinstall.yaml to USB root..."
147+
cp "$YAML_PATH" "${MNT_USB}/autoinstall.yaml"
148+
else
149+
log "Skipping autoinstall.yaml copy."
150+
fi
76151

77-
# ─── CLEANUP ─────────────────────────────────────────────────────────────────
78-
log "Syncing disks..."
152+
# CLEANUP
153+
log "Syncing and unmounting USB..."
79154
sync "$MNT_USB"
155+
umount "$MNT_USB"
156+
157+
# Force unmount ISO, as it's read-only and doesn't require flushing
158+
log "Unmounting ISO..."
159+
umount -f "$MNT_ISO"
80160

81-
log "Unmounting mounts..."
82-
umount "$MNT_ISO" "$MNT_USB"
161+
log "Cleaning up mounts..."
83162
rmdir "$MNT_ISO" "$MNT_USB"
84163

85164
log "USB is ready!"

0 commit comments

Comments
 (0)