blob: 9e2be408d143a438ad5349ecb88bc45e072822e2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
#!/bin/bash
# build.sh - Build the custom Arch ZFS installation ISO
# Must be run as root
#
# Uses linux-lts kernel with zfs-dkms from archzfs.com repository.
# DKMS builds ZFS from source, ensuring it always matches the kernel version.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROFILE_DIR="$SCRIPT_DIR/profile"
WORK_DIR="$SCRIPT_DIR/work"
OUT_DIR="$SCRIPT_DIR/out"
CUSTOM_DIR="$SCRIPT_DIR/custom"
# Live ISO root password (for SSH access during testing/emergencies)
LIVE_ROOT_PASSWORD="archzfs"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
# Check root
[[ $EUID -ne 0 ]] && error "This script must be run as root"
# Check dependencies
command -v mkarchiso >/dev/null 2>&1 || {
info "Installing archiso..."
pacman -Sy --noconfirm archiso
}
# Clean previous builds
if [[ -d "$WORK_DIR" ]]; then
warn "Removing previous work directory..."
rm -rf "$WORK_DIR"
fi
# Always start fresh from releng profile
info "Copying base releng profile..."
rm -rf "$PROFILE_DIR"
cp -r /usr/share/archiso/configs/releng "$PROFILE_DIR"
# Switch from linux to linux-lts
info "Switching to linux-lts kernel..."
sed -i 's/^linux$/linux-lts/' "$PROFILE_DIR/packages.x86_64"
sed -i 's/^linux-headers$/linux-lts-headers/' "$PROFILE_DIR/packages.x86_64"
# broadcom-wl depends on linux, use DKMS version instead
sed -i 's/^broadcom-wl$/broadcom-wl-dkms/' "$PROFILE_DIR/packages.x86_64"
# Update bootloader configs to use linux-lts kernel
info "Updating bootloader configurations for linux-lts..."
# UEFI systemd-boot entries
for entry in "$PROFILE_DIR"/efiboot/loader/entries/*.conf; do
if [[ -f "$entry" ]]; then
sed -i 's/vmlinuz-linux/vmlinuz-linux-lts/g' "$entry"
sed -i 's/initramfs-linux\.img/initramfs-linux-lts.img/g' "$entry"
fi
done
# BIOS syslinux entries
for cfg in "$PROFILE_DIR"/syslinux/*.cfg; do
if [[ -f "$cfg" ]]; then
sed -i 's/vmlinuz-linux/vmlinuz-linux-lts/g' "$cfg"
sed -i 's/initramfs-linux\.img/initramfs-linux-lts.img/g' "$cfg"
fi
done
# GRUB config
if [[ -f "$PROFILE_DIR/grub/grub.cfg" ]]; then
sed -i 's/vmlinuz-linux/vmlinuz-linux-lts/g' "$PROFILE_DIR/grub/grub.cfg"
sed -i 's/initramfs-linux\.img/initramfs-linux-lts.img/g' "$PROFILE_DIR/grub/grub.cfg"
fi
# Update mkinitcpio preset for linux-lts (archiso uses custom preset)
if [[ -f "$PROFILE_DIR/airootfs/etc/mkinitcpio.d/linux.preset" ]]; then
# Rename to linux-lts.preset and update paths
mv "$PROFILE_DIR/airootfs/etc/mkinitcpio.d/linux.preset" \
"$PROFILE_DIR/airootfs/etc/mkinitcpio.d/linux-lts.preset"
sed -i 's/vmlinuz-linux/vmlinuz-linux-lts/g' \
"$PROFILE_DIR/airootfs/etc/mkinitcpio.d/linux-lts.preset"
sed -i 's/initramfs-linux/initramfs-linux-lts/g' \
"$PROFILE_DIR/airootfs/etc/mkinitcpio.d/linux-lts.preset"
sed -i "s/'linux' package/'linux-lts' package/g" \
"$PROFILE_DIR/airootfs/etc/mkinitcpio.d/linux-lts.preset"
fi
# Add archzfs repository to pacman.conf
info "Adding archzfs repository..."
cat >> "$PROFILE_DIR/pacman.conf" << 'EOF'
[archzfs]
Server = https://archzfs.com/$repo/$arch
SigLevel = Optional TrustAll
EOF
# Add ZFS and our custom packages
info "Adding ZFS and custom packages..."
cat >> "$PROFILE_DIR/packages.x86_64" << 'EOF'
# ZFS support (DKMS builds from source - always matches kernel)
zfs-dkms
zfs-utils
linux-lts-headers
# Additional networking
wget
networkmanager
# Development tools for Claude Code
nodejs
npm
jq
# Additional utilities
zsh
htop
ripgrep
eza
fd
fzf
# For installation scripts
dialog
EOF
# Update profiledef.sh with our ISO name
info "Updating ISO metadata..."
sed -i 's/^iso_name=.*/iso_name="archzfs-claude"/' "$PROFILE_DIR/profiledef.sh"
# Create airootfs directories
mkdir -p "$PROFILE_DIR/airootfs/usr/local/bin"
mkdir -p "$PROFILE_DIR/airootfs/code"
mkdir -p "$PROFILE_DIR/airootfs/etc/systemd/system/multi-user.target.wants"
# Enable SSH on live ISO
info "Enabling SSH on live ISO..."
ln -sf /usr/lib/systemd/system/sshd.service \
"$PROFILE_DIR/airootfs/etc/systemd/system/multi-user.target.wants/sshd.service"
# Set root password for live ISO
info "Setting root password for live ISO..."
mkdir -p "$PROFILE_DIR/airootfs/etc"
# Generate password hash
PASS_HASH=$(openssl passwd -6 "$LIVE_ROOT_PASSWORD")
# Create shadow file entry (will be merged with existing)
cat > "$PROFILE_DIR/airootfs/etc/shadow" << EOF
root:${PASS_HASH}:19000:0:99999:7:::
EOF
chmod 400 "$PROFILE_DIR/airootfs/etc/shadow"
# Allow root SSH login with password (for testing)
mkdir -p "$PROFILE_DIR/airootfs/etc/ssh/sshd_config.d"
cat > "$PROFILE_DIR/airootfs/etc/ssh/sshd_config.d/allow-root.conf" << 'EOF'
PermitRootLogin yes
PasswordAuthentication yes
EOF
# Copy our custom scripts
info "Copying custom scripts..."
cp "$CUSTOM_DIR/install-archzfs" "$PROFILE_DIR/airootfs/usr/local/bin/"
cp "$CUSTOM_DIR/install-claude" "$PROFILE_DIR/airootfs/usr/local/bin/"
cp "$CUSTOM_DIR/archsetup-zfs" "$PROFILE_DIR/airootfs/usr/local/bin/"
# Copy example config for unattended installs
mkdir -p "$PROFILE_DIR/airootfs/root"
cp "$CUSTOM_DIR/install-archzfs.conf.example" "$PROFILE_DIR/airootfs/root/"
# Set permissions in profiledef.sh
info "Setting file permissions..."
if grep -q "file_permissions=" "$PROFILE_DIR/profiledef.sh"; then
sed -i '/^file_permissions=(/,/)/ {
/)/ i\ ["/usr/local/bin/install-archzfs"]="0:0:755"
}' "$PROFILE_DIR/profiledef.sh"
sed -i '/^file_permissions=(/,/)/ {
/)/ i\ ["/usr/local/bin/install-claude"]="0:0:755"
}' "$PROFILE_DIR/profiledef.sh"
sed -i '/^file_permissions=(/,/)/ {
/)/ i\ ["/usr/local/bin/archsetup-zfs"]="0:0:755"
}' "$PROFILE_DIR/profiledef.sh"
sed -i '/^file_permissions=(/,/)/ {
/)/ i\ ["/etc/shadow"]="0:0:400"
}' "$PROFILE_DIR/profiledef.sh"
fi
# Copy archsetup into airootfs
if [[ -d /home/cjennings/code/archsetup ]]; then
info "Copying archsetup into ISO..."
cp -r /home/cjennings/code/archsetup "$PROFILE_DIR/airootfs/code/"
rm -rf "$PROFILE_DIR/airootfs/code/archsetup/.git"
rm -rf "$PROFILE_DIR/airootfs/code/archsetup/.claude"
fi
# Ensure scripts are executable in the profile
chmod +x "$PROFILE_DIR/airootfs/usr/local/bin/"*
# Build the ISO
info "Building ISO (this will take a while)..."
mkarchiso -v -w "$WORK_DIR" -o "$OUT_DIR" "$PROFILE_DIR"
# Report results
ISO_FILE=$(ls -t "$OUT_DIR"/*.iso 2>/dev/null | head -1)
if [[ -f "$ISO_FILE" ]]; then
echo ""
info "Build complete!"
info "ISO location: $ISO_FILE"
info "ISO size: $(du -h "$ISO_FILE" | cut -f1)"
echo ""
info "To test: ./scripts/test-vm.sh"
echo ""
info "After booting:"
echo " - ZFS is pre-loaded (no setup needed)"
echo " - SSH is enabled (root password: $LIVE_ROOT_PASSWORD)"
echo " - Run 'install-archzfs' to start installation"
echo ""
info "SSH access (from host):"
echo " ssh -p 2222 root@localhost"
else
error "Build failed - no ISO file found"
fi
|