aboutsummaryrefslogtreecommitdiff
path: root/build.sh
blob: 012455ed994ad7f7d7059350b086697518b2aeed (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
#!/bin/bash
# build.sh - Build the custom Arch ZFS installation ISO
# Must be run as root

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"
ZFS_PKG_DIR="$SCRIPT_DIR/zfs-packages"

# 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
}

# Get current kernel version
KERNEL_VER=$(pacman -Si linux | grep Version | awk '{print $3}')
info "Current Arch kernel version: $KERNEL_VER"

# Download ZFS packages from GitHub releases
info "Downloading ZFS packages for kernel $KERNEL_VER..."
mkdir -p "$ZFS_PKG_DIR"

# Find matching ZFS packages from experimental release
ZFS_LINUX_URL=$(curl -s https://api.github.com/repos/archzfs/archzfs/releases/tags/experimental | \
    jq -r ".assets[] | select(.name | contains(\"zfs-linux-\") and contains(\"${KERNEL_VER}\") and (contains(\"-headers\") | not) and contains(\".pkg.tar.zst\") and (contains(\".sig\") | not)) | .browser_download_url" | head -1)

ZFS_UTILS_URL=$(curl -s https://api.github.com/repos/archzfs/archzfs/releases/tags/experimental | \
    jq -r '.assets[] | select(.name | contains("zfs-utils-") and contains(".pkg.tar.zst") and (contains(".sig") | not) and (contains("debug") | not)) | .browser_download_url' | head -1)

if [[ -z "$ZFS_LINUX_URL" ]]; then
    warn "No ZFS package found for kernel $KERNEL_VER in experimental"
    warn "Checking other releases..."

    # Try to find any recent zfs-linux package
    ZFS_LINUX_URL=$(curl -s https://api.github.com/repos/archzfs/archzfs/releases | \
        jq -r ".[].assets[] | select(.name | contains(\"zfs-linux-\") and contains(\"6.18\") and (contains(\"-headers\") | not) and contains(\".pkg.tar.zst\") and (contains(\".sig\") | not)) | .browser_download_url" | head -1)
fi

if [[ -z "$ZFS_LINUX_URL" || -z "$ZFS_UTILS_URL" ]]; then
    error "Could not find matching ZFS packages. The archzfs repo may not have packages for kernel $KERNEL_VER yet."
fi

info "Downloading: $(basename "$ZFS_LINUX_URL")"
wget -q -N -P "$ZFS_PKG_DIR" "$ZFS_LINUX_URL" || error "Failed to download zfs-linux"

info "Downloading: $(basename "$ZFS_UTILS_URL")"
wget -q -N -P "$ZFS_PKG_DIR" "$ZFS_UTILS_URL" || error "Failed to download zfs-utils"

# 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"

# Add our custom packages (NOT zfs - we'll install that separately)
info "Adding custom packages..."
cat >> "$PROFILE_DIR/packages.x86_64" << 'EOF'

# Additional networking
wget

# 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/var/cache/zfs-packages"

# Copy ZFS packages to airootfs for installation during boot
info "Copying ZFS packages to ISO..."
cp "$ZFS_PKG_DIR"/*.pkg.tar.zst "$PROFILE_DIR/airootfs/var/cache/zfs-packages/"

# 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/"

# Create ZFS setup script that runs on boot
cat > "$PROFILE_DIR/airootfs/usr/local/bin/zfs-setup" << 'ZFSSETUP'
#!/bin/bash
# Install ZFS packages and load module
# Run this first after booting the ISO

set -e

echo "Installing ZFS packages..."
pacman -U --noconfirm /var/cache/zfs-packages/*.pkg.tar.zst

echo "Loading ZFS module..."
modprobe zfs

echo ""
echo "ZFS is ready! You can now run:"
echo "  install-archzfs"
echo ""
ZFSSETUP

# 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\  ["/usr/local/bin/zfs-setup"]="0:0:755"
    }' "$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, run:"
    echo "  zfs-setup        # Install ZFS and load module"
    echo "  install-archzfs  # Run the installer"
else
    error "Build failed - no ISO file found"
fi