Monorepo for Aesthetic.Computer
aesthetic.computer
1#!/bin/bash
2# patch-usb.sh — Patch a Fedora live USB into a FedAC auto-installer
3#
4# After flashing a standard Fedora Workstation ISO to USB, run this to:
5# 1. Mount the EFI partition
6# 2. Copy the FedAC kickstart onto it
7# 3. Replace GRUB config with FedAC-branded auto-boot
8#
9# Usage:
10# sudo bash fedac/scripts/patch-usb.sh /dev/sdX
11#
12# The USB must already have a Fedora live ISO written to it (via dd or flash-usb.sh).
13
14set -euo pipefail
15
16RED='\033[0;31m'
17GREEN='\033[0;32m'
18YELLOW='\033[1;33m'
19CYAN='\033[0;36m'
20PURPLE='\033[0;35m'
21NC='\033[0m'
22
23SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
24FEDAC_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
25
26usage() {
27 echo "Usage: sudo $0 <device>"
28 echo ""
29 echo "Example: sudo $0 /dev/sdb"
30 echo ""
31 echo "The device must be a Fedora live USB (already flashed with dd)."
32 exit 1
33}
34
35DEVICE="${1:-}"
36[ -n "$DEVICE" ] || usage
37[ -b "$DEVICE" ] || { echo -e "${RED}Not a block device: $DEVICE${NC}"; exit 1; }
38
39# Must be root
40if [ "$(id -u)" -ne 0 ]; then
41 echo -e "${RED}Error: Must run as root (sudo)${NC}"
42 exit 1
43fi
44
45# Safety
46case "$DEVICE" in
47 /dev/sda|/dev/nvme0n1|/dev/vda)
48 echo -e "${RED}REFUSED: $DEVICE looks like a system disk${NC}"
49 exit 1
50 ;;
51esac
52
53# Find the EFI partition (usually partition 2 on Fedora live USB, ~30M FAT)
54EFI_PART=""
55for part in "${DEVICE}2" "${DEVICE}p2"; do
56 if [ -b "$part" ]; then
57 EFI_PART="$part"
58 break
59 fi
60done
61
62if [ -z "$EFI_PART" ]; then
63 echo -e "${RED}Could not find EFI partition (tried ${DEVICE}2, ${DEVICE}p2)${NC}"
64 echo "Partitions on $DEVICE:"
65 lsblk "$DEVICE"
66 exit 1
67fi
68
69echo -e "${CYAN}=== FedAC USB Patcher ===${NC}"
70echo -e "Device: ${YELLOW}$DEVICE${NC}"
71echo -e "EFI part: ${YELLOW}$EFI_PART${NC}"
72echo ""
73
74# Mount EFI partition
75MOUNT_DIR=$(mktemp -d /tmp/fedac-efi-XXXX)
76echo -e "${CYAN}Mounting $EFI_PART...${NC}"
77mount "$EFI_PART" "$MOUNT_DIR"
78
79# Verify this looks like a Fedora EFI partition
80if [ ! -d "$MOUNT_DIR/EFI/BOOT" ]; then
81 echo -e "${RED}No EFI/BOOT directory found — doesn't look like a Fedora live USB${NC}"
82 umount "$MOUNT_DIR"
83 rmdir "$MOUNT_DIR"
84 exit 1
85fi
86
87echo -e "${GREEN}EFI partition mounted at $MOUNT_DIR${NC}"
88echo ""
89
90# ── 1. Copy kickstart ──
91echo -e "${CYAN}[1/3] Copying kickstart...${NC}"
92KS_SRC="$FEDAC_DIR/kickstart/fedac-thinkpad.ks"
93if [ ! -f "$KS_SRC" ]; then
94 echo -e "${RED}Kickstart not found: $KS_SRC${NC}"
95 umount "$MOUNT_DIR"
96 rmdir "$MOUNT_DIR"
97 exit 1
98fi
99cp "$KS_SRC" "$MOUNT_DIR/fedac.ks"
100echo -e " Copied to ${GREEN}$MOUNT_DIR/fedac.ks${NC}"
101
102# ── 2. Install GRUB theme ──
103echo -e "${CYAN}[2/4] Installing GRUB theme...${NC}"
104
105THEME_SRC="$FEDAC_DIR/grub-theme"
106THEME_DST="$MOUNT_DIR/EFI/BOOT/fedac-theme"
107
108mkdir -p "$THEME_DST"
109
110# Copy theme.txt (always from repo)
111if [ -f "$THEME_SRC/theme.txt" ]; then
112 cp "$THEME_SRC/theme.txt" "$THEME_DST/"
113 echo -e " theme.txt"
114fi
115
116# Copy generated assets if they exist, otherwise generate on the fly
117NEED_GENERATE=false
118for asset in background.png DejaVuSansBold36.pf2 DejaVuSans18.pf2 DejaVuSans10.pf2 select_c.png menu_c.png; do
119 if [ -f "$THEME_SRC/$asset" ]; then
120 cp "$THEME_SRC/$asset" "$THEME_DST/"
121 echo -e " $asset"
122 else
123 NEED_GENERATE=true
124 fi
125done
126
127if [ "$NEED_GENERATE" = true ]; then
128 echo -e " ${YELLOW}Some theme assets missing — generating...${NC}"
129 if [ -x "$THEME_SRC/prepare-theme.sh" ]; then
130 bash "$THEME_SRC/prepare-theme.sh"
131 # Re-copy generated files
132 for asset in background.png DejaVuSansBold36.pf2 DejaVuSans18.pf2 DejaVuSans10.pf2 select_c.png menu_c.png; do
133 if [ -f "$THEME_SRC/$asset" ]; then
134 cp "$THEME_SRC/$asset" "$THEME_DST/"
135 fi
136 done
137 else
138 echo -e " ${YELLOW}Warning: prepare-theme.sh not found, theme may be incomplete${NC}"
139 fi
140fi
141
142echo -e " ${GREEN}Theme installed to EFI${NC}"
143
144# ── 3. Patch GRUB config ──
145echo -e "${CYAN}[3/4] Patching GRUB config...${NC}"
146
147GRUB_CFG="$MOUNT_DIR/EFI/BOOT/grub.cfg"
148if [ ! -f "$GRUB_CFG" ]; then
149 echo -e "${RED}No EFI/BOOT/grub.cfg found${NC}"
150 umount "$MOUNT_DIR"
151 rmdir "$MOUNT_DIR"
152 exit 1
153fi
154
155# Back up original
156cp "$GRUB_CFG" "${GRUB_CFG}.orig"
157echo -e " Backed up original grub.cfg"
158
159CDLABEL="Fedora-WS-Live-43"
160
161echo -e "${CYAN}[4/4] Writing FedAC GRUB config...${NC}"
162
163cat > "$GRUB_CFG" << 'GRUBEOF'
164# FedAC — Fedora Boot-to-Aesthetic-Computer
165# Auto-patched by fedac/scripts/patch-usb.sh
166
167set default=0
168set timeout=5
169
170# ── Graphics modules ──
171if [ "$grub_platform" == "efi" ]; then
172 insmod efi_gop
173 insmod efi_uga
174fi
175insmod all_video
176insmod gzio
177insmod part_gpt
178insmod ext2
179insmod png
180insmod font
181
182# ── Save EFI partition root before search changes it ──
183set efi_root=$root
184
185# ── Load fonts from EFI partition (before $root changes) ──
186loadfont ($efi_root)/EFI/BOOT/fedac-theme/DejaVuSansBold36.pf2
187loadfont ($efi_root)/EFI/BOOT/fedac-theme/DejaVuSans18.pf2
188loadfont ($efi_root)/EFI/BOOT/fedac-theme/DejaVuSans10.pf2
189
190# ── Switch to graphical terminal ──
191set gfxmode=auto
192set gfxpayload=keep
193terminal_input console
194terminal_output gfxterm
195
196# ── Load theme from EFI partition ──
197if [ -f ($efi_root)/EFI/BOOT/fedac-theme/theme.txt ]; then
198 set theme=($efi_root)/EFI/BOOT/fedac-theme/theme.txt
199else
200 set color_normal=magenta/black
201 set color_highlight=white/magenta
202fi
203
204# ── Find Fedora live partition (changes $root) ──
205search --file --set=root /boot/0x4da30161
206
207menuentry " FedAC — Install Aesthetic Computer" --class fedora {
208 linux ($root)/boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=FEDAC_CDLABEL rd.live.image inst.ks=https://raw.githubusercontent.com/whistlegraph/aesthetic-computer/main/fedac/kickstart/fedac-thinkpad.ks
209 initrd ($root)/boot/x86_64/loader/initrd
210}
211
212menuentry " FedAC — Live Desktop (no install)" --class fedora {
213 linux ($root)/boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=FEDAC_CDLABEL rd.live.image
214 initrd ($root)/boot/x86_64/loader/initrd
215}
216
217menuentry " Boot from local drive" {
218 exit
219}
220GRUBEOF
221
222# Substitute the CDLABEL placeholder
223sed -i "s/FEDAC_CDLABEL/${CDLABEL}/g" "$GRUB_CFG"
224
225echo -e " ${GREEN}GRUB config written (graphical theme)${NC}"
226echo ""
227
228# ── Done ──
229sync
230umount "$MOUNT_DIR"
231rmdir "$MOUNT_DIR"
232
233echo -e "${GREEN}=== USB patched ===${NC}"
234echo ""
235echo -e "Boot menu will show (with pals logo + large text):"
236echo -e " ${PURPLE}1. FedAC — Install Aesthetic Computer${NC} (auto-selected after 5s)"
237echo -e " 2. FedAC — Live Desktop (no install)"
238echo -e " 3. Boot from local drive"
239echo ""
240echo -e "The kickstart at ${GREEN}/fedac.ks${NC} on the EFI partition will automate the install."
241echo -e "Pull the USB and boot the target machine."