Compare commits
2 Commits
d952e10dbb
...
fa553c3f20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa553c3f20 | ||
|
|
345a93512a |
@@ -1,4 +1,5 @@
|
||||
ALPINE_VERSION=3.21
|
||||
DEBIAN_VERSION=12
|
||||
DEBIAN_KERNEL_ABI=6.1.0-43
|
||||
NVIDIA_DRIVER_VERSION=590.48.01
|
||||
GO_VERSION=1.23.6
|
||||
AUDIT_VERSION=0.1.0
|
||||
|
||||
5
iso/builder/auto/build
Executable file
5
iso/builder/auto/build
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
# auto/build — live-build build wrapper for bee ISO
|
||||
set -e
|
||||
|
||||
lb build noauto "${@}" 2>&1
|
||||
30
iso/builder/auto/config
Executable file
30
iso/builder/auto/config
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
# auto/config — live-build configuration for bee ISO
|
||||
# Runs automatically when lb config is called.
|
||||
# See: man lb_config
|
||||
|
||||
set -e
|
||||
|
||||
. "$(dirname "$0")/../VERSIONS"
|
||||
|
||||
lb config noauto \
|
||||
--distribution bookworm \
|
||||
--architectures amd64 \
|
||||
--binary-images iso-hybrid \
|
||||
--bootloaders "grub-efi,syslinux" \
|
||||
--debian-installer none \
|
||||
--archive-areas "main contrib non-free non-free-firmware" \
|
||||
--mirror-bootstrap "https://deb.debian.org/debian" \
|
||||
--mirror-chroot "https://deb.debian.org/debian" \
|
||||
--mirror-binary "https://deb.debian.org/debian" \
|
||||
--security true \
|
||||
--linux-flavours "amd64" \
|
||||
--linux-packages "linux-image-${DEBIAN_KERNEL_ABI}" \
|
||||
--memtest none \
|
||||
--iso-volume "BEE-DEBUG" \
|
||||
--iso-application "Bee Hardware Audit" \
|
||||
--hostname "bee-debug" \
|
||||
--username "root" \
|
||||
--bootappend-live "boot=live components quiet splash" \
|
||||
--apt-recommends false \
|
||||
"${@}"
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# build-nvidia-module.sh — install NVIDIA proprietary driver into ISO overlay
|
||||
# build-nvidia-module.sh — compile NVIDIA proprietary driver modules for Debian 12
|
||||
#
|
||||
# Downloads the official NVIDIA .run installer, extracts kernel modules and
|
||||
# userspace tools (nvidia-smi, libnvidia-ml). Everything is proprietary NVIDIA.
|
||||
@@ -16,33 +16,25 @@ set -e
|
||||
|
||||
NVIDIA_VERSION="$1"
|
||||
DIST_DIR="$2"
|
||||
ALPINE_VERSION="$3"
|
||||
DEBIAN_KERNEL_ABI="$3"
|
||||
|
||||
[ -n "$NVIDIA_VERSION" ] || { echo "usage: $0 <nvidia-version> <dist-dir> <alpine-version>"; exit 1; }
|
||||
[ -n "$DIST_DIR" ] || { echo "usage: $0 <nvidia-version> <dist-dir> <alpine-version>"; exit 1; }
|
||||
[ -n "$ALPINE_VERSION" ] || { echo "usage: $0 <nvidia-version> <dist-dir> <alpine-version>"; exit 1; }
|
||||
[ -n "$NVIDIA_VERSION" ] || { echo "usage: $0 <nvidia-version> <dist-dir> <debian-kernel-abi>"; exit 1; }
|
||||
[ -n "$DIST_DIR" ] || { echo "usage: $0 <nvidia-version> <dist-dir> <debian-kernel-abi>"; exit 1; }
|
||||
[ -n "$DEBIAN_KERNEL_ABI" ] || { echo "usage: $0 <nvidia-version> <dist-dir> <debian-kernel-abi>"; exit 1; }
|
||||
|
||||
# Install linux-lts-dev (no version pin — always use whatever is current in Alpine 3.21 main).
|
||||
# This ensures modules are compiled for the same kernel that mkimage will install in the ISO.
|
||||
# Both use dl-cdn.alpinelinux.org, so they see the same package state at build time.
|
||||
echo "=== installing linux-lts-dev (latest from dl-cdn) ==="
|
||||
apk add --quiet --update \
|
||||
--repository "https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/main" \
|
||||
linux-lts-dev
|
||||
|
||||
# Detect kernel version from installed headers (pick highest version if multiple).
|
||||
detect_kver() {
|
||||
ls /usr/src/ 2>/dev/null \
|
||||
| grep '^linux-headers-' \
|
||||
| sed 's/linux-headers-//' \
|
||||
| sort -V \
|
||||
| tail -1
|
||||
}
|
||||
|
||||
KVER="$(detect_kver)"
|
||||
KVER="${DEBIAN_KERNEL_ABI}-amd64"
|
||||
KDIR="/usr/src/linux-headers-${KVER}"
|
||||
|
||||
echo "=== NVIDIA ${NVIDIA_VERSION} (proprietary) for kernel ${KVER} ==="
|
||||
|
||||
if [ ! -d "$KDIR" ]; then
|
||||
echo "=== installing linux-headers-${KVER} ==="
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
"linux-headers-${KVER}" \
|
||||
gcc make perl
|
||||
fi
|
||||
echo "kernel headers: $KDIR"
|
||||
|
||||
CACHE_DIR="${DIST_DIR}/nvidia-${NVIDIA_VERSION}-${KVER}"
|
||||
if [ -d "$CACHE_DIR/modules" ] && [ -f "$CACHE_DIR/bin/nvidia-smi" ]; then
|
||||
echo "=== NVIDIA cached, skipping build ==="
|
||||
@@ -51,12 +43,7 @@ if [ -d "$CACHE_DIR/modules" ] && [ -f "$CACHE_DIR/bin/nvidia-smi" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install build dependencies (linux-lts-dev already at correct version from above)
|
||||
apk add --quiet \
|
||||
--repository "https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/main" \
|
||||
gcc make perl linux-lts-dev wget
|
||||
|
||||
# Download official NVIDIA .run installer (proprietary) with sha256 verification
|
||||
# Download official NVIDIA .run installer with sha256 verification
|
||||
BASE_URL="https://download.nvidia.com/XFree86/Linux-x86_64/${NVIDIA_VERSION}"
|
||||
RUN_FILE="/var/tmp/NVIDIA-Linux-x86_64-${NVIDIA_VERSION}.run"
|
||||
SHA_FILE="/var/tmp/NVIDIA-Linux-x86_64-${NVIDIA_VERSION}.run.sha256sum"
|
||||
@@ -96,7 +83,7 @@ done
|
||||
[ -n "$KERNEL_SRC" ] || { echo "ERROR: kernel source dir not found in:"; ls "$EXTRACT_DIR/"; exit 1; }
|
||||
echo "kernel source: $KERNEL_SRC"
|
||||
|
||||
# Build kernel modules from extracted source
|
||||
# Build kernel modules
|
||||
echo "=== building kernel modules ($(nproc) cores) ==="
|
||||
cd "$KERNEL_SRC"
|
||||
make -j$(nproc) KERNEL_UNAME="$KVER" SYSSRC="$KDIR" modules 2>&1 | tail -5
|
||||
@@ -112,32 +99,31 @@ done
|
||||
cp "$EXTRACT_DIR/nvidia-smi" "$CACHE_DIR/bin/"
|
||||
cp "$EXTRACT_DIR/nvidia-bug-report.sh" "$CACHE_DIR/bin/" 2>/dev/null || true
|
||||
|
||||
# Copy userspace libraries — use find to handle any versioning scheme (libnvidia-ml.so.X.Y.Z or .so.1)
|
||||
# Copy ALL userspace library files
|
||||
for lib in libnvidia-ml libcuda; do
|
||||
found=$(find "$EXTRACT_DIR" -maxdepth 1 -name "${lib}.so.*" | head -1)
|
||||
if [ -z "$found" ]; then
|
||||
count=0
|
||||
for f in $(find "$EXTRACT_DIR" -maxdepth 1 -name "${lib}.so.*" 2>/dev/null); do
|
||||
cp "$f" "$CACHE_DIR/lib/" && count=$((count+1))
|
||||
done
|
||||
if [ "$count" -eq 0 ]; then
|
||||
echo "ERROR: ${lib}.so.* not found in $EXTRACT_DIR"
|
||||
ls "$EXTRACT_DIR/"*.so* 2>/dev/null | head -20 || true
|
||||
exit 1
|
||||
fi
|
||||
cp "$found" "$CACHE_DIR/lib/"
|
||||
done
|
||||
|
||||
# Verify .ko files were actually built
|
||||
# Verify .ko files were built
|
||||
ko_count=$(ls "$CACHE_DIR/modules/"*.ko 2>/dev/null | wc -l)
|
||||
[ "$ko_count" -gt 0 ] || { echo "ERROR: no .ko files built in $CACHE_DIR/modules/"; exit 1; }
|
||||
|
||||
# Create soname symlinks required by nvidia-smi on Alpine (musl/glibc via gcompat + libc6-compat)
|
||||
# Create soname symlinks: use [0-9][0-9]* to avoid circular symlink (.so.1 has single digit)
|
||||
for lib in libnvidia-ml libcuda; do
|
||||
versioned=$(ls "$CACHE_DIR/lib/${lib}.so."* 2>/dev/null | grep -v '\.so\.1$' | head -1)
|
||||
[ -n "$versioned" ] || versioned=$(ls "$CACHE_DIR/lib/${lib}.so."* 2>/dev/null | head -1)
|
||||
versioned=$(ls "$CACHE_DIR/lib/${lib}.so."[0-9][0-9]* 2>/dev/null | head -1)
|
||||
[ -n "$versioned" ] || continue
|
||||
base=$(basename "$versioned")
|
||||
# Only create .so.1 if versioned file is not already named .so.1
|
||||
if [ "$base" != "${lib}.so.1" ]; then
|
||||
ln -sf "$base" "$CACHE_DIR/lib/${lib}.so.1"
|
||||
fi
|
||||
ln -sf "$base" "$CACHE_DIR/lib/${lib}.so.1"
|
||||
ln -sf "${lib}.so.1" "$CACHE_DIR/lib/${lib}.so" 2>/dev/null || true
|
||||
echo "${lib}: .so.1 -> $base"
|
||||
done
|
||||
|
||||
echo "=== NVIDIA build complete ==="
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/sh
|
||||
# build.sh — build bee ISO
|
||||
# build.sh — build bee ISO (Debian 12 / live-build)
|
||||
#
|
||||
# Single build script. Produces a bootable live ISO with SSH access, TUI, NVIDIA drivers.
|
||||
#
|
||||
# Run on Alpine builder VM as root after setup-builder.sh.
|
||||
# Run on Debian 12 builder VM as root after setup-builder.sh.
|
||||
# Usage:
|
||||
# sh iso/builder/build.sh [--authorized-keys /path/to/authorized_keys]
|
||||
|
||||
@@ -27,15 +27,11 @@ done
|
||||
. "${BUILDER_DIR}/VERSIONS"
|
||||
export PATH="$PATH:/usr/local/go/bin"
|
||||
|
||||
# NOTE: lz4 compression for modloop is disabled — Alpine initramfs may not support lz4 squashfs.
|
||||
# Default xz compression is used until lz4 support is confirmed.
|
||||
|
||||
echo "=== bee ISO build ==="
|
||||
echo "Alpine: ${ALPINE_VERSION}, Go: ${GO_VERSION}"
|
||||
echo "Debian: ${DEBIAN_VERSION}, Kernel ABI: ${DEBIAN_KERNEL_ABI}, Go: ${GO_VERSION}"
|
||||
echo ""
|
||||
|
||||
# --- compile audit binary (static, Linux amd64) ---
|
||||
# Skip rebuild if binary is newer than all Go source files.
|
||||
AUDIT_BIN="${DIST_DIR}/bee-audit-linux-amd64"
|
||||
NEED_BUILD=1
|
||||
if [ -f "$AUDIT_BIN" ]; then
|
||||
@@ -58,8 +54,6 @@ else
|
||||
fi
|
||||
|
||||
# --- inject authorized_keys for SSH access ---
|
||||
# Uses the same Ed25519 keys as release signing (from git.mchus.pro/mchus/keys).
|
||||
# SSH public keys are stored alongside signing keys as ~/.keys/<name>.key.pub
|
||||
AUTHORIZED_KEYS_FILE="${OVERLAY_DIR}/root/.ssh/authorized_keys"
|
||||
mkdir -p "${OVERLAY_DIR}/root/.ssh"
|
||||
|
||||
@@ -68,7 +62,6 @@ if [ -n "$AUTH_KEYS" ]; then
|
||||
chmod 600 "$AUTHORIZED_KEYS_FILE"
|
||||
echo "SSH authorized_keys: installed from $AUTH_KEYS"
|
||||
else
|
||||
# auto-collect all developer SSH public keys from ~/.keys/*.key.pub
|
||||
> "$AUTHORIZED_KEYS_FILE"
|
||||
FOUND=0
|
||||
for ssh_pub in "$HOME"/.keys/*.key.pub; do
|
||||
@@ -82,15 +75,15 @@ else
|
||||
echo "SSH authorized_keys: $FOUND key(s) from ~/.keys/*.key.pub"
|
||||
else
|
||||
echo "WARNING: no SSH public keys found — falling back to password auth"
|
||||
echo " SSH login: bee / eeb (user created by bee-sshsetup at boot)"
|
||||
echo " (generate a key with: sh keys/scripts/keygen.sh <your-name>)"
|
||||
echo " SSH login: bee / eeb"
|
||||
USE_PASSWORD_FALLBACK=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- password fallback: write marker file read by init script ---
|
||||
if [ "${USE_PASSWORD_FALLBACK:-0}" = "1" ]; then
|
||||
touch "${OVERLAY_DIR}/etc/bee-ssh-password-fallback"
|
||||
else
|
||||
rm -f "${OVERLAY_DIR}/etc/bee-ssh-password-fallback"
|
||||
fi
|
||||
|
||||
# --- copy audit binary into overlay ---
|
||||
@@ -113,20 +106,15 @@ for tool in storcli64 sas2ircu sas3ircu mstflint; do
|
||||
fi
|
||||
done
|
||||
|
||||
# --- build NVIDIA kernel modules and inject into overlay ---
|
||||
# --- build NVIDIA kernel modules ---
|
||||
echo ""
|
||||
echo "=== building NVIDIA ${NVIDIA_DRIVER_VERSION} modules ==="
|
||||
sh "${BUILDER_DIR}/build-nvidia-module.sh" "${NVIDIA_DRIVER_VERSION}" "${DIST_DIR}" "${ALPINE_VERSION}"
|
||||
|
||||
# Detect kernel version from installed headers (set by build-nvidia-module.sh above)
|
||||
KVER=$(ls /usr/src/ 2>/dev/null | grep '^linux-headers-' | sed 's/linux-headers-//' | sort -V | tail -1)
|
||||
[ -n "$KVER" ] || { echo "ERROR: linux-lts-dev not installed — no headers in /usr/src/"; exit 1; }
|
||||
echo "=== kernel version: ${KVER} ==="
|
||||
sh "${BUILDER_DIR}/build-nvidia-module.sh" "${NVIDIA_DRIVER_VERSION}" "${DIST_DIR}" "${DEBIAN_KERNEL_ABI}"
|
||||
|
||||
KVER="${DEBIAN_KERNEL_ABI}-amd64"
|
||||
NVIDIA_CACHE="${DIST_DIR}/nvidia-${NVIDIA_DRIVER_VERSION}-${KVER}"
|
||||
|
||||
# Inject .ko files into overlay at /usr/local/lib/nvidia/ (not /lib/modules/ — modloop squashfs
|
||||
# mounts over that path at boot and makes it read-only, so overlay content there is inaccessible)
|
||||
# Inject .ko files into overlay at /usr/local/lib/nvidia/
|
||||
OVERLAY_KMOD_DIR="${OVERLAY_DIR}/usr/local/lib/nvidia"
|
||||
mkdir -p "${OVERLAY_KMOD_DIR}"
|
||||
cp "${NVIDIA_CACHE}/modules/"*.ko "${OVERLAY_KMOD_DIR}/"
|
||||
@@ -139,7 +127,6 @@ cp "${NVIDIA_CACHE}/bin/nvidia-bug-report.sh" "${OVERLAY_DIR}/usr/local/bin/" 2>
|
||||
chmod +x "${OVERLAY_DIR}/usr/local/bin/nvidia-bug-report.sh" 2>/dev/null || true
|
||||
cp "${NVIDIA_CACHE}/lib/"* "${OVERLAY_DIR}/usr/lib/" 2>/dev/null || true
|
||||
|
||||
|
||||
# --- embed build metadata ---
|
||||
mkdir -p "${OVERLAY_DIR}/etc"
|
||||
BUILD_DATE="$(date +%Y-%m-%d)"
|
||||
@@ -149,60 +136,54 @@ BEE_ISO_VERSION=${AUDIT_VERSION}
|
||||
BEE_AUDIT_VERSION=${AUDIT_VERSION}
|
||||
BUILD_DATE=${BUILD_DATE}
|
||||
GIT_COMMIT=${GIT_COMMIT}
|
||||
ALPINE_VERSION=${ALPINE_VERSION}
|
||||
DEBIAN_VERSION=${DEBIAN_VERSION}
|
||||
DEBIAN_KERNEL_ABI=${DEBIAN_KERNEL_ABI}
|
||||
NVIDIA_DRIVER_VERSION=${NVIDIA_DRIVER_VERSION}
|
||||
EOF
|
||||
|
||||
# --- export build info for genapkovl to inject into motd ---
|
||||
BUILD_DATE=$(date +%Y-%m-%d)
|
||||
GIT_COMMIT=$(git -C "${REPO_ROOT}" rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
||||
export BEE_BUILD_INFO="${BUILD_DATE} git:${GIT_COMMIT} alpine:${ALPINE_VERSION} nvidia:${NVIDIA_DRIVER_VERSION}"
|
||||
|
||||
# --- build ISO using mkimage ---
|
||||
mkdir -p "${DIST_DIR}"
|
||||
echo ""
|
||||
echo "=== building ISO ==="
|
||||
|
||||
# Install our mkimage profile where mkimage.sh can find it.
|
||||
# ~/.mkimage is the user plugin directory loaded by mkimage.sh.
|
||||
# Clear ~/.mkimage to avoid stale profiles from previous builds being picked up
|
||||
rm -rf "${HOME}/.mkimage"
|
||||
mkdir -p "${HOME}/.mkimage"
|
||||
cp "${BUILDER_DIR}/mkimg.bee.sh" "${HOME}/.mkimage/"
|
||||
cp "${BUILDER_DIR}/genapkovl-bee.sh" "${HOME}/.mkimage/"
|
||||
|
||||
# Export overlay dir so the profile script can find it regardless of SRCDIR.
|
||||
export BEE_OVERLAY_DIR="${OVERLAY_DIR}"
|
||||
|
||||
# Clean workdir: always nuke apks_* (stale packages from old mirror/version cause "unable to select" errors).
|
||||
# Keep kernel_*, syslinux_*, grub_* — these are large but stable; they only change when KERNEL_PKG_VERSION changes.
|
||||
if [ -d /var/tmp/bee-iso-work ]; then
|
||||
find /var/tmp/bee-iso-work -maxdepth 1 -mindepth 1 \
|
||||
-not -name 'kernel_*' \
|
||||
-not -name 'syslinux_*' -not -name 'grub_*' \
|
||||
-exec rm -rf {} + 2>/dev/null || true
|
||||
# Patch motd with build info
|
||||
BEE_BUILD_INFO="${BUILD_DATE} git:${GIT_COMMIT} debian:${DEBIAN_VERSION} nvidia:${NVIDIA_DRIVER_VERSION}"
|
||||
if [ -f "${OVERLAY_DIR}/etc/motd" ]; then
|
||||
sed "s/%%BUILD_INFO%%/${BEE_BUILD_INFO}/" "${OVERLAY_DIR}/etc/motd" \
|
||||
> "${OVERLAY_DIR}/etc/motd.patched"
|
||||
mv "${OVERLAY_DIR}/etc/motd.patched" "${OVERLAY_DIR}/etc/motd"
|
||||
fi
|
||||
|
||||
# Run from /var/tmp: mkimage.sh calls git internally; running from inside /root/bee causes
|
||||
# "outside repository" errors. /var/tmp is outside the git repo and has enough scratch space.
|
||||
# genapkovl-bee.sh is found by mkimage via ~/.mkimage/.
|
||||
# Remove any stale genapkovl from /var/tmp — mkimage checks CWD first, stale files override ~/.mkimage/.
|
||||
rm -f /var/tmp/genapkovl-*.sh
|
||||
export TMPDIR=/var/tmp
|
||||
cd /var/tmp
|
||||
sh /usr/share/aports/scripts/mkimage.sh \
|
||||
--tag "v${ALPINE_VERSION}" \
|
||||
--outdir "${DIST_DIR}" \
|
||||
--arch x86_64 \
|
||||
--repository "https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/main" \
|
||||
--repository "https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community" \
|
||||
--workdir /var/tmp/bee-iso-work \
|
||||
--profile bee
|
||||
# --- sync overlay into live-build includes.chroot ---
|
||||
LB_DIR="${BUILDER_DIR}"
|
||||
LB_INCLUDES="${LB_DIR}/config/includes.chroot"
|
||||
mkdir -p "${LB_INCLUDES}"
|
||||
rsync -a "${OVERLAY_DIR}/" "${LB_INCLUDES}/"
|
||||
|
||||
ISO="${DIST_DIR}/alpine-bee-${ALPINE_VERSION}-x86_64.iso"
|
||||
# Ensure SSH authorized_keys perms are correct (rsync may alter)
|
||||
if [ -f "${LB_INCLUDES}/root/.ssh/authorized_keys" ]; then
|
||||
chmod 700 "${LB_INCLUDES}/root/.ssh"
|
||||
chmod 600 "${LB_INCLUDES}/root/.ssh/authorized_keys"
|
||||
fi
|
||||
|
||||
# --- build ISO using live-build ---
|
||||
mkdir -p "${DIST_DIR}"
|
||||
echo ""
|
||||
echo "=== done ==="
|
||||
echo "ISO: $ISO"
|
||||
echo "Size: $(du -sh "$ISO" 2>/dev/null | cut -f1 || echo 'not found')"
|
||||
echo "=== building ISO (live-build) ==="
|
||||
|
||||
cd "${LB_DIR}"
|
||||
lb clean 2>&1 | tail -3
|
||||
lb config 2>&1 | tail -5
|
||||
lb build 2>&1
|
||||
|
||||
# live-build outputs live-image-amd64.hybrid.iso in LB_DIR
|
||||
ISO_RAW="${LB_DIR}/live-image-amd64.hybrid.iso"
|
||||
ISO_OUT="${DIST_DIR}/bee-debian${DEBIAN_VERSION}-v${AUDIT_VERSION}-amd64.iso"
|
||||
if [ -f "$ISO_RAW" ]; then
|
||||
cp "$ISO_RAW" "$ISO_OUT"
|
||||
echo ""
|
||||
echo "=== done ==="
|
||||
echo "ISO: $ISO_OUT"
|
||||
echo "Size: $(du -sh "$ISO_OUT" | cut -f1)"
|
||||
else
|
||||
echo "ERROR: ISO not found at $ISO_RAW"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Boot via BMC virtual media and SSH to the server IP on port 22 as root."
|
||||
|
||||
29
iso/builder/config/hooks/normal/9000-bee-setup.hook.chroot
Executable file
29
iso/builder/config/hooks/normal/9000-bee-setup.hook.chroot
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
# 9000-bee-setup.hook.chroot — runs inside Debian chroot during live-build
|
||||
# Enables bee systemd services and configures the live environment.
|
||||
set -e
|
||||
|
||||
echo "=== bee chroot setup ==="
|
||||
|
||||
# Enable bee services
|
||||
systemctl enable bee-network.service
|
||||
systemctl enable bee-nvidia.service
|
||||
systemctl enable bee-audit.service
|
||||
systemctl enable bee-sshsetup.service
|
||||
systemctl enable ssh.service
|
||||
|
||||
# Ensure scripts are executable
|
||||
chmod +x /usr/local/bin/bee-network.sh 2>/dev/null || true
|
||||
chmod +x /usr/local/bin/bee-nvidia-load 2>/dev/null || true
|
||||
chmod +x /usr/local/bin/bee-sshsetup 2>/dev/null || true
|
||||
chmod +x /usr/local/bin/bee-smoketest 2>/dev/null || true
|
||||
chmod +x /usr/local/bin/bee-tui 2>/dev/null || true
|
||||
chmod +x /usr/local/bin/audit 2>/dev/null || true
|
||||
|
||||
# Reload udev rules
|
||||
udevadm control --reload-rules 2>/dev/null || true
|
||||
|
||||
# Create log directory
|
||||
mkdir -p /var/log
|
||||
|
||||
echo "=== bee chroot setup complete ==="
|
||||
12
iso/builder/config/includes.chroot/.gitignore
vendored
Normal file
12
iso/builder/config/includes.chroot/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Generated at build time — do not commit
|
||||
usr/local/bin/audit
|
||||
usr/local/bin/bee-smoketest
|
||||
usr/local/bin/nvidia-smi
|
||||
usr/local/bin/nvidia-bug-report.sh
|
||||
usr/local/lib/
|
||||
usr/lib/libnvidia-ml*
|
||||
usr/lib/libcuda*
|
||||
root/.ssh/authorized_keys
|
||||
etc/bee-release
|
||||
etc/bee-ssh-password-fallback
|
||||
etc/motd
|
||||
35
iso/builder/config/package-lists/bee.list.chroot
Normal file
35
iso/builder/config/package-lists/bee.list.chroot
Normal file
@@ -0,0 +1,35 @@
|
||||
# Hardware audit tools
|
||||
dmidecode
|
||||
smartmontools
|
||||
nvme-cli
|
||||
pciutils
|
||||
ipmitool
|
||||
util-linux
|
||||
e2fsprogs
|
||||
lshw
|
||||
lsblk
|
||||
|
||||
# Network
|
||||
iproute2
|
||||
dhclient
|
||||
iputils-ping
|
||||
|
||||
# SSH
|
||||
openssh-server
|
||||
|
||||
# Utilities
|
||||
procps
|
||||
lsof
|
||||
file
|
||||
less
|
||||
vim-tiny
|
||||
dialog
|
||||
|
||||
# QR codes (for displaying audit results)
|
||||
qrencode
|
||||
|
||||
# Firmware
|
||||
firmware-linux-free
|
||||
|
||||
# glibc compat helpers (for any external binaries that need it)
|
||||
libc6
|
||||
@@ -1,108 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
HOSTNAME="$1"
|
||||
[ -n "$HOSTNAME" ] || { echo "usage: $0 hostname"; exit 1; }
|
||||
OVERLAY="${BEE_OVERLAY_DIR}"
|
||||
[ -n "$OVERLAY" ] || { echo "ERROR: BEE_OVERLAY_DIR not set"; exit 1; }
|
||||
|
||||
cleanup() { rm -rf "$tmp"; }
|
||||
tmp="$(mktemp -d)"
|
||||
trap cleanup EXIT
|
||||
|
||||
makefile() { OWNER="$1" PERMS="$2" FILENAME="$3"; cat > "$FILENAME"; chown "$OWNER" "$FILENAME"; chmod "$PERMS" "$FILENAME"; }
|
||||
rc_add() { mkdir -p "$tmp/etc/runlevels/$2"; ln -sf /etc/init.d/"$1" "$tmp/etc/runlevels/$2/$1"; }
|
||||
|
||||
mkdir -p "$tmp/etc"
|
||||
makefile root:root 0644 "$tmp/etc/hostname" <<EOF
|
||||
$HOSTNAME
|
||||
EOF
|
||||
|
||||
# Empty interfaces file — prevents ifupdown from erroring, bee-network handles DHCP
|
||||
mkdir -p "$tmp/etc/network"
|
||||
makefile root:root 0644 "$tmp/etc/network/interfaces" <<EOF
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
EOF
|
||||
|
||||
mkdir -p "$tmp/etc/apk"
|
||||
makefile root:root 0644 "$tmp/etc/apk/world" <<EOF
|
||||
alpine-base
|
||||
dmidecode
|
||||
smartmontools
|
||||
nvme-cli
|
||||
pciutils
|
||||
ipmitool
|
||||
util-linux
|
||||
lsblk
|
||||
e2fsprogs
|
||||
lshw
|
||||
dropbear
|
||||
libqrencode-tools
|
||||
tzdata
|
||||
ca-certificates
|
||||
strace
|
||||
procps
|
||||
lsof
|
||||
file
|
||||
less
|
||||
vim
|
||||
dialog
|
||||
gcompat
|
||||
libc6-compat
|
||||
EOF
|
||||
|
||||
rc_add devfs sysinit
|
||||
rc_add dmesg sysinit
|
||||
rc_add mdev sysinit
|
||||
rc_add hwdrivers sysinit
|
||||
rc_add modloop sysinit
|
||||
|
||||
rc_add hwclock boot
|
||||
rc_add modules boot
|
||||
rc_add sysctl boot
|
||||
rc_add hostname boot
|
||||
rc_add bootmisc boot
|
||||
rc_add syslog boot
|
||||
|
||||
rc_add mount-ro shutdown
|
||||
rc_add killprocs shutdown
|
||||
rc_add savecache shutdown
|
||||
|
||||
rc_add bee-sshsetup default
|
||||
rc_add bee-network default
|
||||
rc_add dropbear default
|
||||
rc_add bee-nvidia default
|
||||
rc_add bee-audit default
|
||||
|
||||
if [ -d "$OVERLAY/etc" ]; then
|
||||
cp -r "$OVERLAY/etc/." "$tmp/etc/"
|
||||
chmod +x "$tmp/etc/init.d/"* 2>/dev/null || true
|
||||
[ -n "$BEE_BUILD_INFO" ] && sed -i "s/%%BUILD_INFO%%/${BEE_BUILD_INFO}/" "$tmp/etc/motd" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
mkdir -p "$tmp/usr"
|
||||
if [ -d "$OVERLAY/usr" ]; then
|
||||
cp -r "$OVERLAY/usr/." "$tmp/usr/"
|
||||
chmod +x "$tmp/usr/local/bin/"* 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -d "$OVERLAY/root" ]; then
|
||||
mkdir -p "$tmp/root"
|
||||
cp -r "$OVERLAY/root/." "$tmp/root/"
|
||||
chmod 700 "$tmp/root/.ssh" 2>/dev/null || true
|
||||
chmod 600 "$tmp/root/.ssh/authorized_keys" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -d "$OVERLAY/lib" ]; then
|
||||
mkdir -p "$tmp/lib"
|
||||
cp -r "$OVERLAY/lib/." "$tmp/lib/"
|
||||
fi
|
||||
|
||||
mkdir -p "$tmp/etc/dropbear" "$tmp/etc/conf.d"
|
||||
# -R: auto-generate host keys if missing
|
||||
# no dependency on networking service — bee-network handles DHCP independently
|
||||
makefile root:root 0644 "$tmp/etc/conf.d/dropbear" <<EOF
|
||||
DROPBEAR_OPTS="-R -B"
|
||||
EOF
|
||||
|
||||
|
||||
tar -c -C "$tmp" etc usr root lib 2>/dev/null | gzip -9n > "$HOSTNAME.apkovl.tar.gz"
|
||||
@@ -1,58 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Alpine mkimage profile: bee
|
||||
|
||||
profile_bee() {
|
||||
title="Bee Hardware Audit"
|
||||
desc="Hardware audit LiveCD"
|
||||
arch="x86_64"
|
||||
hostname="alpine-bee"
|
||||
apkovl="genapkovl-bee.sh"
|
||||
image_ext="iso"
|
||||
output_format="iso"
|
||||
kernel_flavors="lts"
|
||||
kernel_addons=""
|
||||
initfs_cmdline="modules=loop,squashfs,sd-mod,usb-storage modloop=/boot/modloop-lts quiet"
|
||||
initfs_features="ata base cdrom ext4 mmc nvme raid scsi squashfs usb virtio nfit"
|
||||
grub_mod="all_video disk part_gpt part_msdos linux normal configfile search search_label efi_gop fat iso9660 cat echo ls test true help gzio multiboot2 efi_uga"
|
||||
syslinux_serial="0 115200"
|
||||
apks="
|
||||
alpine-base
|
||||
linux-firmware-none
|
||||
linux-firmware-rtl_nic
|
||||
linux-firmware-bnx2
|
||||
linux-firmware-bnx2x
|
||||
linux-firmware-tigon
|
||||
linux-firmware-qlogic
|
||||
linux-firmware-netronome
|
||||
linux-firmware-mellanox
|
||||
linux-firmware-intel
|
||||
linux-firmware-other
|
||||
|
||||
dmidecode
|
||||
smartmontools
|
||||
nvme-cli
|
||||
pciutils
|
||||
ipmitool
|
||||
util-linux
|
||||
lsblk
|
||||
e2fsprogs
|
||||
lshw
|
||||
|
||||
dropbear
|
||||
openrc
|
||||
libqrencode-tools
|
||||
tzdata
|
||||
ca-certificates
|
||||
|
||||
strace
|
||||
procps
|
||||
lsof
|
||||
file
|
||||
less
|
||||
vim
|
||||
dialog
|
||||
|
||||
gcompat
|
||||
libc6-compat
|
||||
"
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
#!/bin/sh
|
||||
# setup-builder.sh — prepare Alpine VM as bee ISO builder
|
||||
# setup-builder.sh — prepare Debian 12 VM as bee ISO builder
|
||||
#
|
||||
# Run once on a fresh Alpine 3.21 VM as root.
|
||||
# After this script completes, the VM can build ISO images.
|
||||
# Run once on a fresh Debian 12 (Bookworm) VM as root.
|
||||
# After this script completes, the VM can build bee ISO images.
|
||||
#
|
||||
# Usage (on Alpine VM):
|
||||
# Usage (on Debian VM):
|
||||
# wget -O- https://git.mchus.pro/mchus/bee/raw/branch/main/iso/builder/setup-builder.sh | sh
|
||||
# or: sh setup-builder.sh
|
||||
|
||||
@@ -12,65 +12,41 @@ set -e
|
||||
|
||||
. "$(dirname "$0")/VERSIONS" 2>/dev/null || true
|
||||
GO_VERSION="${GO_VERSION:-1.23.6}"
|
||||
DEBIAN_VERSION="${DEBIAN_VERSION:-12}"
|
||||
DEBIAN_KERNEL_ABI="${DEBIAN_KERNEL_ABI:-6.1.0-28}"
|
||||
|
||||
echo "=== bee builder setup ==="
|
||||
echo "Alpine: $(cat /etc/alpine-release)"
|
||||
echo "Debian: $(cat /etc/debian_version)"
|
||||
echo "Go target: ${GO_VERSION}"
|
||||
echo "Kernel ABI: ${DEBIAN_KERNEL_ABI}"
|
||||
echo ""
|
||||
|
||||
# --- system packages ---
|
||||
apk update
|
||||
# enable community repo if not already enabled
|
||||
sed -i 's|^#\(.*community\)|\1|' /etc/apk/repositories
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
|
||||
apk update
|
||||
apk add \
|
||||
alpine-sdk \
|
||||
abuild \
|
||||
apt-get install -y \
|
||||
live-build \
|
||||
debootstrap \
|
||||
squashfs-tools \
|
||||
xorriso \
|
||||
grub-pc-bin \
|
||||
grub-efi-amd64-bin \
|
||||
mtools \
|
||||
grub \
|
||||
grub-efi \
|
||||
grub-bios \
|
||||
git \
|
||||
wget \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
screen
|
||||
xz-utils \
|
||||
screen \
|
||||
rsync \
|
||||
build-essential \
|
||||
gcc \
|
||||
make \
|
||||
perl \
|
||||
"linux-headers-${DEBIAN_KERNEL_ABI}-amd64"
|
||||
|
||||
# --- audit runtime packages (verify they exist in Alpine repos) ---
|
||||
echo ""
|
||||
echo "=== verifying audit runtime packages ==="
|
||||
RUNTIME_PKGS="
|
||||
dmidecode
|
||||
smartmontools
|
||||
nvme-cli
|
||||
pciutils
|
||||
ipmitool
|
||||
util-linux
|
||||
e2fsprogs
|
||||
qrencode
|
||||
dropbear
|
||||
udhcpc
|
||||
pciutils-libs
|
||||
lshw
|
||||
"
|
||||
MISSING=""
|
||||
for pkg in $RUNTIME_PKGS; do
|
||||
if apk info --quiet "$pkg" 2>/dev/null || apk search --quiet "$pkg" 2>/dev/null | grep -q "^${pkg}-"; then
|
||||
echo " OK: $pkg"
|
||||
else
|
||||
echo " MISSING: $pkg"
|
||||
MISSING="$MISSING $pkg"
|
||||
fi
|
||||
done
|
||||
if [ -n "$MISSING" ]; then
|
||||
echo ""
|
||||
echo "WARNING: missing packages:$MISSING"
|
||||
echo "These will not be available in the ISO."
|
||||
fi
|
||||
echo "linux-headers installed: $(dpkg -l "linux-headers-${DEBIAN_KERNEL_ABI}-amd64" | awk '/^ii/{print $3}')"
|
||||
|
||||
# --- Go toolchain ---
|
||||
echo ""
|
||||
@@ -93,38 +69,6 @@ fi
|
||||
export PATH="$PATH:/usr/local/go/bin"
|
||||
echo "Go: $(go version)"
|
||||
|
||||
# --- alpine-conf for mkimage ---
|
||||
apk add alpine-conf
|
||||
|
||||
# --- aports for mkimage.sh ---
|
||||
if [ ! -d /usr/share/aports ]; then
|
||||
echo ""
|
||||
echo "=== cloning aports ==="
|
||||
git clone --depth=1 --branch "v${ALPINE_VERSION:-3.21}.0" \
|
||||
https://gitlab.alpinelinux.org/alpine/aports.git \
|
||||
/usr/share/aports
|
||||
fi
|
||||
|
||||
# --- abuild signing key (required by mkimage.sh) ---
|
||||
if [ ! -f "${HOME}/.abuild/abuild.conf" ]; then
|
||||
echo ""
|
||||
echo "=== generating abuild signing key ==="
|
||||
mkdir -p "${HOME}/.abuild"
|
||||
abuild-keygen -a -n 2>/dev/null || true
|
||||
# abuild-keygen requires doas to install the key system-wide; do it manually
|
||||
PUB=$(ls "${HOME}/.abuild/"*.pub 2>/dev/null | head -1)
|
||||
if [ -n "$PUB" ]; then
|
||||
cp "$PUB" /etc/apk/keys/
|
||||
PRIV="${PUB%.pub}"
|
||||
echo "PACKAGER_PRIVKEY=\"${PRIV}\"" > "${HOME}/.abuild/abuild.conf"
|
||||
echo "abuild key: $PRIV"
|
||||
else
|
||||
echo "WARNING: abuild key generation failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# NOTE: lz4 compression for modloop is disabled — Alpine initramfs may not support lz4 squashfs.
|
||||
|
||||
echo ""
|
||||
echo "=== builder setup complete ==="
|
||||
echo "Next: sh iso/builder/build-debug.sh"
|
||||
echo "Next: sh iso/builder/build.sh"
|
||||
|
||||
@@ -24,11 +24,10 @@ echo " date: $(date -u)"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# --- kernel version ---
|
||||
KVER=$(uname -r)
|
||||
info "kernel: $KVER"
|
||||
|
||||
# --- PATH ---
|
||||
# --- PATH & binaries ---
|
||||
echo "-- PATH & binaries --"
|
||||
for tool in dmidecode smartctl nvme ipmitool lspci audit; do
|
||||
if p=$(PATH="/usr/local/bin:$PATH" command -v "$tool" 2>/dev/null); then
|
||||
@@ -96,30 +95,21 @@ for lib in libnvidia-ml libcuda; do
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "-- gcompat (glibc compat for nvidia-smi) --"
|
||||
if [ -L /lib64/ld-linux-x86-64.so.2 ] || [ -f /lib64/ld-linux-x86-64.so.2 ]; then
|
||||
ok "gcompat: /lib64/ld-linux-x86-64.so.2 present"
|
||||
else
|
||||
fail "gcompat: /lib64/ld-linux-x86-64.so.2 MISSING — nvidia-smi will fail to exec"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "-- openrc services --"
|
||||
echo "-- systemd services --"
|
||||
for svc in bee-nvidia bee-network bee-audit; do
|
||||
if rc-service "$svc" status >/dev/null 2>&1; then
|
||||
ok "service running: $svc"
|
||||
if systemctl is-active --quiet "$svc" 2>/dev/null; then
|
||||
ok "service active: $svc"
|
||||
else
|
||||
fail "service NOT running: $svc"
|
||||
fail "service NOT active: $svc"
|
||||
fi
|
||||
done
|
||||
|
||||
for svc in dropbear bee-sshsetup; do
|
||||
if [ -f "/etc/init.d/$svc" ]; then
|
||||
if rc-service "$svc" status >/dev/null 2>&1; then
|
||||
ok "service running: $svc"
|
||||
else
|
||||
warn "service not running: $svc (may be one-shot)"
|
||||
fi
|
||||
for svc in ssh bee-sshsetup; do
|
||||
if systemctl is-active --quiet "$svc" 2>/dev/null \
|
||||
|| systemctl show "$svc" --property=ActiveState 2>/dev/null | grep -q "inactive\|exited"; then
|
||||
ok "service ok: $svc"
|
||||
else
|
||||
warn "service status unknown: $svc"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -136,8 +126,6 @@ fi
|
||||
|
||||
echo ""
|
||||
echo "-- audit last run --"
|
||||
# audit binary logs via slog to stderr (bee-audit.log); JSON output goes to bee-audit.json.
|
||||
# slog format: time=... level=INFO msg="audit output written" path=...
|
||||
if [ -f /var/log/bee-audit.json ] && [ -s /var/log/bee-audit.json ]; then
|
||||
ok "audit: bee-audit.json present and non-empty"
|
||||
info "size: $(du -sh /var/log/bee-audit.json | cut -f1)"
|
||||
@@ -148,13 +136,11 @@ fi
|
||||
if [ -f /var/log/bee-audit.log ]; then
|
||||
last_line=$(tail -1 /var/log/bee-audit.log)
|
||||
info "last log line: $last_line"
|
||||
# slog writes: msg="audit output written" on success
|
||||
if grep -q "audit output written" /var/log/bee-audit.log 2>/dev/null; then
|
||||
ok "audit: completed successfully"
|
||||
else
|
||||
warn "audit: 'audit output written' not found in log — may have failed"
|
||||
fi
|
||||
# check for nvidia enrichment skip (slog message from nvidia collector)
|
||||
if grep -q "nvidia: enrichment skipped\|nvidia.*skipped\|enrichment skipped" /var/log/bee-audit.log 2>/dev/null; then
|
||||
reason=$(grep -E "nvidia.*skipped|enrichment skipped" /var/log/bee-audit.log | tail -1)
|
||||
fail "audit: nvidia enrichment skipped — $reason"
|
||||
|
||||
@@ -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