server: safer gadget bring-up + kernel upgrade hook
This commit is contained in:
parent
a939dfcc77
commit
06bc0cd98d
@ -106,6 +106,7 @@ cleanup() {
|
||||
|
||||
DISABLE_UAC=${LESAVKA_DISABLE_UAC:-}
|
||||
DISABLE_UVC=${LESAVKA_DISABLE_UVC:-}
|
||||
ALLOW_RESET=${LESAVKA_ALLOW_GADGET_RESET:-}
|
||||
UVC_FALLBACK=${LESAVKA_UVC_FALLBACK:-1}
|
||||
UVC_STREAMING_INTERVAL=${LESAVKA_UVC_STREAMING_INTERVAL:-1}
|
||||
UVC_MAXPACKET=${LESAVKA_UVC_MAXPACKET:-1024}
|
||||
@ -155,7 +156,9 @@ grep -q 'dtoverlay=dwc2,dr_mode=peripheral' "$CFG" || echo 'dtoverlay=dwc2,dr_mo
|
||||
modprobe dwc2 || { echo "dwc2 not in kernel; abort" >&2; exit 1; }
|
||||
modprobe libcomposite || { echo "libcomposite not in kernel; abort" >&2; exit 1; }
|
||||
|
||||
modprobe -r uvcvideo 2>/dev/null || true
|
||||
if [[ -n ${LESAVKA_RELOAD_UVCVIDEO:-} ]]; then
|
||||
modprobe -r uvcvideo 2>/dev/null || true
|
||||
fi
|
||||
modprobe uvcvideo || { echo "uvcvideo not in kernel; abort" >&2; exit 1; }
|
||||
|
||||
udevadm control --reload
|
||||
@ -192,12 +195,22 @@ fi
|
||||
[[ -n $UDC ]] || { log "❌ UDC not present after manual bind"; exit 1; }
|
||||
log "✅ UDC detected: $UDC"
|
||||
|
||||
# If a gadget is already configured, avoid tearing it down unless forced.
|
||||
if [[ -d $G && -z $ALLOW_RESET ]]; then
|
||||
if [[ -s $G/UDC || -d $G/configs/c.1 ]]; then
|
||||
log "🔒 gadget already configured; skipping reset."
|
||||
log " Set LESAVKA_ALLOW_GADGET_RESET=1 to force rebuild."
|
||||
attach_gadget || true
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Guard against lockups: if the gadget is already bound, don't reset unless forced.
|
||||
BOUND_UDC=""
|
||||
if [[ -r $G/UDC ]]; then
|
||||
BOUND_UDC=$(cat "$G/UDC" 2>/dev/null || true)
|
||||
fi
|
||||
if [[ -n $BOUND_UDC && -z ${LESAVKA_ALLOW_GADGET_RESET:-} ]]; then
|
||||
if [[ -n $BOUND_UDC && -z $ALLOW_RESET ]]; then
|
||||
log "🔒 gadget already bound to '$BOUND_UDC' - refusing reset."
|
||||
log " Set LESAVKA_ALLOW_GADGET_RESET=1 to force."
|
||||
exit 0
|
||||
@ -205,7 +218,7 @@ fi
|
||||
|
||||
# Guard against lockups: don't reset gadget while host is attached unless forced.
|
||||
UDC_STATE="$(udc_state "$UDC")"
|
||||
if [[ -z ${LESAVKA_ALLOW_GADGET_RESET:-} ]] && is_attached_state "$UDC_STATE"; then
|
||||
if [[ -z $ALLOW_RESET ]] && is_attached_state "$UDC_STATE"; then
|
||||
log "🔒 UDC state is '$UDC_STATE' - refusing gadget reset while host attached."
|
||||
log " Set LESAVKA_ALLOW_GADGET_RESET=1 to force."
|
||||
exit 0
|
||||
|
||||
@ -149,7 +149,14 @@ else
|
||||
sudo -u "$ORIG_USER" git -C "$SRC_DIR" checkout --force "$REF"
|
||||
fi
|
||||
|
||||
echo "==> 4b. Source build"
|
||||
echo "==> 4b. Kernel upgrade (optional)"
|
||||
if [[ "${LESAVKA_KERNEL_UPDATE:-1}" != "0" ]]; then
|
||||
sudo LESAVKA_KERNEL_BUILD_USER="$ORIG_USER" "$SRC_DIR/scripts/kernel/build-linux-rpi.sh"
|
||||
else
|
||||
echo "⚠️ skipping kernel upgrade (LESAVKA_KERNEL_UPDATE=0)"
|
||||
fi
|
||||
|
||||
echo "==> 4c. Source build"
|
||||
sudo -u "$ORIG_USER" bash -c "cd '$SRC_DIR/server' && cargo clean && cargo build --release --bins"
|
||||
|
||||
echo "==> 5. Install binaries"
|
||||
|
||||
110
scripts/kernel/build-linux-rpi.sh
Normal file
110
scripts/kernel/build-linux-rpi.sh
Normal file
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
# build-linux-rpi.sh - build/install a newer linux-rpi from rpi-6.18.y
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${EUID:-0} -ne 0 ]]; then
|
||||
echo "run as root (sudo) to install build deps and kernel packages" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUILD_USER=${LESAVKA_KERNEL_BUILD_USER:-${SUDO_USER:-$(id -un)}}
|
||||
if [[ -z $BUILD_USER || $BUILD_USER == root ]]; then
|
||||
echo "missing non-root build user; set LESAVKA_KERNEL_BUILD_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KERNEL_REPO=${LESAVKA_KERNEL_REPO:-https://github.com/raspberrypi/linux.git}
|
||||
KERNEL_BRANCH=${LESAVKA_KERNEL_BRANCH:-rpi-6.18.y}
|
||||
KERNEL_COMMIT=${LESAVKA_KERNEL_COMMIT:-}
|
||||
PKGBUILD_REPO=${LESAVKA_KERNEL_PKG_REPO:-https://github.com/archlinuxarm/PKGBUILDs.git}
|
||||
BUILD_ROOT=${LESAVKA_KERNEL_BUILD_ROOT:-/var/tmp/lesavka-linux-rpi}
|
||||
PKGREL=${LESAVKA_KERNEL_PKGREL:-2}
|
||||
JOBS=${LESAVKA_KERNEL_JOBS:-2}
|
||||
|
||||
HEARTBEAT=/etc/lesavka/watchdog.touch
|
||||
if [[ -w $HEARTBEAT && -z ${LESAVKA_DISABLE_KEEPALIVE:-} ]]; then
|
||||
(while true; do touch "$HEARTBEAT"; sleep 600; done) &
|
||||
KEEPALIVE_PID=$!
|
||||
trap 'kill $KEEPALIVE_PID' EXIT
|
||||
fi
|
||||
|
||||
if [[ -z $KERNEL_COMMIT ]]; then
|
||||
KERNEL_COMMIT=$(git ls-remote "$KERNEL_REPO" "refs/heads/$KERNEL_BRANCH" | awk '{print $1}')
|
||||
fi
|
||||
if [[ -z $KERNEL_COMMIT ]]; then
|
||||
echo "failed to resolve kernel commit for $KERNEL_BRANCH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KERNEL_VERSION=$(
|
||||
curl -fsSL "https://raw.githubusercontent.com/raspberrypi/linux/$KERNEL_COMMIT/Makefile" |
|
||||
awk -F' = ' '
|
||||
/^VERSION =/ {v=$2}
|
||||
/^PATCHLEVEL =/ {p=$2}
|
||||
/^SUBLEVEL =/ {s=$2}
|
||||
END { if (v && p && s) print v "." p "." s }'
|
||||
)
|
||||
if [[ -z $KERNEL_VERSION ]]; then
|
||||
echo "failed to determine kernel version from $KERNEL_COMMIT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_VERSION="${KERNEL_VERSION}-${PKGREL}"
|
||||
INSTALLED_VERSION=$(pacman -Qi linux-rpi 2>/dev/null | awk -F': ' '/Version/{print $2}')
|
||||
if [[ -n $INSTALLED_VERSION && $INSTALLED_VERSION == "$TARGET_VERSION"* ]]; then
|
||||
echo "linux-rpi already at $TARGET_VERSION"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "==> Building linux-rpi $KERNEL_VERSION ($KERNEL_COMMIT) pkgrel=$PKGREL"
|
||||
|
||||
pacman -Sy --needed --noconfirm git bc kmod inetutils base-devel
|
||||
|
||||
rm -rf "$BUILD_ROOT"
|
||||
mkdir -p "$BUILD_ROOT"
|
||||
chown "$BUILD_USER":"$BUILD_USER" "$BUILD_ROOT"
|
||||
|
||||
sudo -u "$BUILD_USER" git clone --depth 1 "$PKGBUILD_REPO" "$BUILD_ROOT/PKGBUILDs"
|
||||
cp -a "$BUILD_ROOT/PKGBUILDs/core/linux-rpi" "$BUILD_ROOT/linux-rpi"
|
||||
chown -R "$BUILD_USER":"$BUILD_USER" "$BUILD_ROOT/linux-rpi"
|
||||
|
||||
sudo -u "$BUILD_USER" bash -c "
|
||||
set -euo pipefail
|
||||
cd '$BUILD_ROOT/linux-rpi'
|
||||
sed -i 's/^pkgver=.*/pkgver=$KERNEL_VERSION/' PKGBUILD
|
||||
sed -i 's/^pkgrel=.*/pkgrel=$PKGREL/' PKGBUILD
|
||||
sed -i 's/^_commit=.*/_commit=$KERNEL_COMMIT/' PKGBUILD
|
||||
makepkg -g > /tmp/lesavka-kernel.sums
|
||||
"
|
||||
|
||||
sudo -u "$BUILD_USER" BUILD_ROOT="$BUILD_ROOT" python - <<'PY'
|
||||
import re
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
root = Path(os.environ["BUILD_ROOT"])
|
||||
pkgbuild = root / "linux-rpi" / "PKGBUILD"
|
||||
sums = Path("/tmp/lesavka-kernel.sums").read_text().splitlines()
|
||||
text = pkgbuild.read_text()
|
||||
for line in sums:
|
||||
if not line.startswith("sha256sums"):
|
||||
continue
|
||||
key = line.split("=", 1)[0]
|
||||
text = re.sub(rf"^{re.escape(key)}=.*$", line, text, flags=re.M)
|
||||
pkgbuild.write_text(text)
|
||||
PY
|
||||
|
||||
sudo -u "$BUILD_USER" bash -c "
|
||||
set -euo pipefail
|
||||
cd '$BUILD_ROOT/linux-rpi'
|
||||
MAKEFLAGS='-j$JOBS' makepkg -s --noconfirm
|
||||
"
|
||||
|
||||
mapfile -t PKGS < <(ls "$BUILD_ROOT/linux-rpi"/*.pkg.tar.* 2>/dev/null)
|
||||
if [[ ${#PKGS[@]} -eq 0 ]]; then
|
||||
echo "no kernel packages built" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pacman -U --noconfirm "${PKGS[@]}"
|
||||
echo "✅ linux-rpi upgraded to $TARGET_VERSION (reboot required)"
|
||||
Loading…
x
Reference in New Issue
Block a user