migrate ISO build from Alpine to Debian 12 (Bookworm)
Replace the entire live CD build pipeline: - Alpine SDK + mkimage + genapkovl → Debian live-build (lb config/build) - OpenRC init scripts → systemd service units - dropbear → openssh-server (native to Debian live) - udhcpc → dhclient for DHCP - apk → apt-get in setup-builder.sh and build-nvidia-module.sh - Add auto/config (lb config options) and auto/build wrapper - Add config/package-lists/bee.list.chroot replacing Alpine apks - Add config/hooks/normal/9000-bee-setup.hook.chroot to enable services - Add bee-nvidia-load and bee-sshsetup helper scripts - Keep NVIDIA pre-compile pipeline (Option B): compile on builder VM against pinned Debian kernel headers (DEBIAN_KERNEL_ABI), inject .ko into includes.chroot - Fixes: native glibc (no gcompat shims), proper udev, writable /lib/modules, no Alpine modloop read-only constraint, no stale apk cache issues Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +0,0 @@
|
||||
DROPBEAR_OPTS="-p 22 -R -B"
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="Bee: run hardware audit"
|
||||
|
||||
depend() {
|
||||
need localmount
|
||||
after bee-network bee-nvidia
|
||||
}
|
||||
|
||||
start() {
|
||||
ebegin "Running hardware audit"
|
||||
/usr/local/bin/audit --output "file:/var/log/bee-audit.json" 2>/var/log/bee-audit.log
|
||||
local rc=$?
|
||||
if [ $rc -eq 0 ]; then
|
||||
einfo "Audit complete: /var/log/bee-audit.json"
|
||||
einfo "SSH in and inspect results. Dropbear is running."
|
||||
else
|
||||
ewarn "Audit finished with errors — check /var/log/bee-audit.log"
|
||||
fi
|
||||
eend 0
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="Bee: bring up network interfaces via DHCP"
|
||||
|
||||
depend() {
|
||||
need localmount
|
||||
before bee-audit
|
||||
}
|
||||
|
||||
start() {
|
||||
ebegin "Bringing up network interfaces"
|
||||
/usr/local/bin/bee-network.sh >> /var/log/bee-network.log 2>&1
|
||||
eend 0
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="Bee: load NVIDIA kernel modules"
|
||||
|
||||
NVIDIA_KO_DIR="/usr/local/lib/nvidia"
|
||||
|
||||
depend() {
|
||||
need localmount
|
||||
before bee-audit
|
||||
}
|
||||
|
||||
start() {
|
||||
ebegin "Loading NVIDIA modules"
|
||||
einfo "kernel: $(uname -r)"
|
||||
|
||||
if [ ! -d "$NVIDIA_KO_DIR" ]; then
|
||||
ewarn "NVIDIA module dir missing: $NVIDIA_KO_DIR"
|
||||
eend 1
|
||||
return 1
|
||||
fi
|
||||
|
||||
einfo "module dir: $NVIDIA_KO_DIR"
|
||||
ls "$NVIDIA_KO_DIR"/*.ko 2>/dev/null | sed 's/^/ /' || true
|
||||
|
||||
# Create libnvidia-ml soname symlinks needed by nvidia-smi (glibc binary on Alpine/musl)
|
||||
for lib in libnvidia-ml libcuda; do
|
||||
versioned=$(ls /usr/lib/${lib}.so.[0-9]* 2>/dev/null | head -1)
|
||||
[ -n "$versioned" ] || continue
|
||||
base=$(basename "$versioned")
|
||||
ln -sf "$base" "/usr/lib/${lib}.so.1" 2>/dev/null || true
|
||||
ln -sf "${lib}.so.1" "/usr/lib/${lib}.so" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# Load modules via insmod (bypasses modules.dep — modloop squashfs is read-only)
|
||||
for mod in nvidia nvidia-modeset nvidia-uvm; do
|
||||
ko="$NVIDIA_KO_DIR/${mod}.ko"
|
||||
[ -f "$ko" ] || ko="$NVIDIA_KO_DIR/${mod//-/_}.ko"
|
||||
if [ -f "$ko" ]; then
|
||||
if insmod "$ko" 2>/dev/null; then
|
||||
einfo "loaded: $mod"
|
||||
else
|
||||
ewarn "failed to load: $mod"
|
||||
dmesg | tail -n 5 | sed 's/^/ dmesg: /' || true
|
||||
fi
|
||||
else
|
||||
ewarn "not found: $ko"
|
||||
fi
|
||||
done
|
||||
|
||||
# Create /dev/nvidia* device nodes — mdev on Alpine does not have NVIDIA rules,
|
||||
# so the kernel hotplug events are not handled and nodes are never created.
|
||||
# Without /dev/nvidiactl nvidia-smi returns NVML_ERROR_LIBRARY_NOT_FOUND (exit 12).
|
||||
nvidia_major=$(grep -m1 ' nvidiactl$' /proc/devices 2>/dev/null | awk '{print $1}')
|
||||
if [ -n "$nvidia_major" ]; then
|
||||
mknod -m 666 /dev/nvidiactl c "$nvidia_major" 255 2>/dev/null \
|
||||
&& einfo "created /dev/nvidiactl (major $nvidia_major)" \
|
||||
|| ewarn "/dev/nvidiactl already exists or mknod failed"
|
||||
for i in 0 1 2 3 4 5 6 7; do
|
||||
mknod -m 666 "/dev/nvidia$i" c "$nvidia_major" "$i" 2>/dev/null || true
|
||||
done
|
||||
einfo "created /dev/nvidia{0-7}"
|
||||
else
|
||||
ewarn "/dev/nvidiactl: nvidia not in /proc/devices — no GPU hardware present?"
|
||||
eend 0
|
||||
return 0
|
||||
fi
|
||||
|
||||
uvm_major=$(grep -m1 ' nvidia-uvm$' /proc/devices 2>/dev/null | awk '{print $1}')
|
||||
if [ -n "$uvm_major" ]; then
|
||||
mknod -m 666 /dev/nvidia-uvm c "$uvm_major" 0 2>/dev/null \
|
||||
&& einfo "created /dev/nvidia-uvm (major $uvm_major)" \
|
||||
|| ewarn "/dev/nvidia-uvm already exists or mknod failed"
|
||||
mknod -m 666 /dev/nvidia-uvm-tools c "$uvm_major" 1 2>/dev/null || true
|
||||
else
|
||||
ewarn "/dev/nvidia-uvm: nvidia-uvm not in /proc/devices"
|
||||
fi
|
||||
|
||||
eend 0
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="Bee: configure SSH access (keys or password fallback)"
|
||||
|
||||
depend() {
|
||||
need localmount
|
||||
before dropbear
|
||||
}
|
||||
|
||||
start() {
|
||||
# Always create dedicated 'bee' user for password fallback.
|
||||
# If no SSH keys embedded: login with bee / eeb
|
||||
if ! id bee > /dev/null 2>&1; then
|
||||
adduser -D -s /bin/sh bee > /dev/null 2>&1
|
||||
fi
|
||||
printf 'eeb\neeb\n' | passwd bee > /dev/null 2>&1
|
||||
|
||||
if [ -f /etc/bee-ssh-password-fallback ]; then
|
||||
ebegin "SSH key auth unavailable — password fallback active"
|
||||
ewarn "Login: bee / eeb"
|
||||
ewarn "Generate a key: sh keys/scripts/keygen.sh <name>"
|
||||
eend 0
|
||||
else
|
||||
ebegin "SSH key auth configured"
|
||||
# bee user exists but password login less useful when keys work
|
||||
eend 0
|
||||
fi
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="Dropbear SSH server"
|
||||
|
||||
depend() {
|
||||
need localmount
|
||||
after bee-sshsetup
|
||||
use logger
|
||||
}
|
||||
|
||||
check_config() {
|
||||
if [ ! -e /etc/dropbear/dropbear_rsa_host_key ]; then
|
||||
einfo "Generating RSA host key..."
|
||||
/usr/bin/dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
|
||||
fi
|
||||
if [ ! -e /etc/dropbear/dropbear_ecdsa_host_key ]; then
|
||||
einfo "Generating ECDSA host key..."
|
||||
/usr/bin/dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key
|
||||
fi
|
||||
if [ ! -e /etc/dropbear/dropbear_ed25519_host_key ]; then
|
||||
einfo "Generating ED25519 host key..."
|
||||
/usr/bin/dropbearkey -t ed25519 -f /etc/dropbear/dropbear_ed25519_host_key
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
check_config || return 1
|
||||
ebegin "Starting dropbear"
|
||||
/usr/sbin/dropbear ${DROPBEAR_OPTS}
|
||||
eend $?
|
||||
}
|
||||
|
||||
stop() {
|
||||
ebegin "Stopping dropbear"
|
||||
start-stop-daemon --stop --pidfile /var/run/dropbear.pid
|
||||
eend $?
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
::sysinit:/sbin/openrc sysinit
|
||||
::sysinit:/sbin/openrc boot
|
||||
::wait:/sbin/openrc default
|
||||
|
||||
# Autologin on tty1
|
||||
tty1::respawn:/sbin/agetty --autologin root --noclear tty1 linux
|
||||
tty2::respawn:/sbin/getty 38400 tty2
|
||||
tty3::respawn:/sbin/getty 38400 tty3
|
||||
|
||||
ttyS0::respawn:/sbin/getty -L 115200 ttyS0 vt100
|
||||
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
::shutdown:/sbin/openrc shutdown
|
||||
14
iso/overlay/etc/systemd/system/bee-audit.service
Normal file
14
iso/overlay/etc/systemd/system/bee-audit.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Bee: run hardware audit
|
||||
After=bee-network.service bee-nvidia.service network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/audit --output file:/var/log/bee-audit.json
|
||||
StandardOutput=append:/var/log/bee-audit.log
|
||||
StandardError=append:/var/log/bee-audit.log
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
14
iso/overlay/etc/systemd/system/bee-network.service
Normal file
14
iso/overlay/etc/systemd/system/bee-network.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Bee: bring up network interfaces via DHCP
|
||||
After=local-fs.target
|
||||
Before=network-online.target bee-audit.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/bee-network.sh
|
||||
StandardOutput=append:/var/log/bee-network.log
|
||||
StandardError=append:/var/log/bee-network.log
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
14
iso/overlay/etc/systemd/system/bee-nvidia.service
Normal file
14
iso/overlay/etc/systemd/system/bee-nvidia.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Bee: load NVIDIA kernel modules and create device nodes
|
||||
After=local-fs.target udev.service
|
||||
Before=bee-audit.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/bee-nvidia-load
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
12
iso/overlay/etc/systemd/system/bee-sshsetup.service
Normal file
12
iso/overlay/etc/systemd/system/bee-sshsetup.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Bee: configure SSH access (keys or password fallback)
|
||||
After=local-fs.target
|
||||
Before=ssh.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/bee-sshsetup
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -22,9 +22,8 @@ for iface in $interfaces; do
|
||||
log "bringing up $iface"
|
||||
ip link set "$iface" up 2>/dev/null || { log "WARN: could not bring up $iface"; continue; }
|
||||
|
||||
# DHCP in background: -b forks if no immediate lease, & ensures non-blocking always.
|
||||
# -t 0: unlimited retries, -T 3: 3s per attempt. No -q: stay running to renew lease.
|
||||
udhcpc -i "$iface" -b -t 0 -T 3 &
|
||||
# DHCP in background — non-blocking, retries indefinitely
|
||||
dhclient -nw "$iface" 2>/dev/null &
|
||||
log "DHCP started for $iface (pid $!)"
|
||||
done
|
||||
|
||||
|
||||
59
iso/overlay/usr/local/bin/bee-nvidia-load
Executable file
59
iso/overlay/usr/local/bin/bee-nvidia-load
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
# bee-nvidia-load — load NVIDIA kernel modules and create device nodes
|
||||
# Called by bee-nvidia.service at boot.
|
||||
|
||||
NVIDIA_KO_DIR="/usr/local/lib/nvidia"
|
||||
|
||||
log() { echo "[bee-nvidia] $*"; }
|
||||
|
||||
log "kernel: $(uname -r)"
|
||||
|
||||
if [ ! -d "$NVIDIA_KO_DIR" ]; then
|
||||
log "ERROR: NVIDIA module dir missing: $NVIDIA_KO_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "module dir: $NVIDIA_KO_DIR"
|
||||
ls "$NVIDIA_KO_DIR"/*.ko 2>/dev/null | sed 's/^/ /' || true
|
||||
|
||||
# Load modules via insmod (direct load — no depmod needed)
|
||||
for mod in nvidia nvidia-modeset nvidia-uvm; do
|
||||
ko="$NVIDIA_KO_DIR/${mod}.ko"
|
||||
[ -f "$ko" ] || ko="$NVIDIA_KO_DIR/${mod//-/_}.ko"
|
||||
if [ -f "$ko" ]; then
|
||||
if insmod "$ko" 2>/dev/null; then
|
||||
log "loaded: $mod"
|
||||
else
|
||||
log "WARN: failed to load: $mod"
|
||||
dmesg | tail -n 5 | sed 's/^/ dmesg: /' || true
|
||||
fi
|
||||
else
|
||||
log "WARN: not found: $ko"
|
||||
fi
|
||||
done
|
||||
|
||||
# Create /dev/nvidia* device nodes (udev rules absent since we use .run installer)
|
||||
nvidia_major=$(grep -m1 ' nvidiactl$' /proc/devices 2>/dev/null | awk '{print $1}')
|
||||
if [ -n "$nvidia_major" ]; then
|
||||
mknod -m 666 /dev/nvidiactl c "$nvidia_major" 255 2>/dev/null \
|
||||
&& log "created /dev/nvidiactl (major $nvidia_major)" \
|
||||
|| log "WARN: /dev/nvidiactl already exists or mknod failed"
|
||||
for i in 0 1 2 3 4 5 6 7; do
|
||||
mknod -m 666 "/dev/nvidia$i" c "$nvidia_major" "$i" 2>/dev/null || true
|
||||
done
|
||||
log "created /dev/nvidia{0-7}"
|
||||
else
|
||||
log "WARN: nvidiactl not in /proc/devices — no GPU hardware present?"
|
||||
fi
|
||||
|
||||
uvm_major=$(grep -m1 ' nvidia-uvm$' /proc/devices 2>/dev/null | awk '{print $1}')
|
||||
if [ -n "$uvm_major" ]; then
|
||||
mknod -m 666 /dev/nvidia-uvm c "$uvm_major" 0 2>/dev/null \
|
||||
&& log "created /dev/nvidia-uvm (major $uvm_major)" \
|
||||
|| log "WARN: /dev/nvidia-uvm already exists"
|
||||
mknod -m 666 /dev/nvidia-uvm-tools c "$uvm_major" 1 2>/dev/null || true
|
||||
else
|
||||
log "WARN: nvidia-uvm not in /proc/devices"
|
||||
fi
|
||||
|
||||
log "done"
|
||||
18
iso/overlay/usr/local/bin/bee-sshsetup
Executable file
18
iso/overlay/usr/local/bin/bee-sshsetup
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
# bee-sshsetup — configure SSH access
|
||||
# Called by bee-sshsetup.service before SSH starts.
|
||||
|
||||
log() { echo "[bee-sshsetup] $*"; }
|
||||
|
||||
# Always create dedicated 'bee' user for password fallback.
|
||||
if ! id bee > /dev/null 2>&1; then
|
||||
useradd -m -s /bin/sh bee > /dev/null 2>&1
|
||||
fi
|
||||
echo "bee:eeb" | chpasswd > /dev/null 2>&1
|
||||
|
||||
if [ -f /etc/bee-ssh-password-fallback ]; then
|
||||
log "SSH key auth unavailable — password fallback active"
|
||||
log "Login: bee / eeb"
|
||||
else
|
||||
log "SSH key auth configured"
|
||||
fi
|
||||
Reference in New Issue
Block a user