Files
Omarchy-Stream/lib/verify.sh
Levi Woodard ee1379d5be Add Debian/Ubuntu support via a thin distro dispatch layer
Adds a parallel install path for Debian/Ubuntu hosts alongside the existing
Arch/Omarchy/Hyprland one. The Arch path is untouched at runtime; everything
new is gated on $DISTRO and (for headless) $COMPOSITOR.

Highlights:
- lib/distro.sh: detect_distro + pkg_install/pkg_remove/ca_anchor_path/
  ca_update_trust dispatch helpers
- lib/packages.sh: Ubuntu sunshine install pulls LizardByte's official .deb
  from GitHub releases (override via SUNSHINE_DEB_URL/SUNSHINE_DEB_VERSION);
  GPU encoder packages branch per $DISTRO:$GPU_VENDOR
- bin/sunshine-stream-{do,undo,prestart}-sway.sh + files/sway-headless.*:
  swaymsg-based headless capture path for hosts without Hyprland. sway runs
  under a systemd-user unit that sunshine.service depends on via drop-in.
- lib/preflight.sh: clearer NVIDIA driver guidance on Ubuntu (we don't install
  the driver - too many branch/kernel/Secure-Boot variants); sway-aware
  headless preflight
- lib/certs.sh + lib/verify.sh + uninstall.sh: distro-aware CA trust anchor
  (Arch: /etc/ca-certificates/trust-source/anchors + update-ca-trust;
   Debian: /usr/local/share/ca-certificates + update-ca-certificates)

Verified on Ubuntu 24.04: ./install.sh --doctor --headless loads cleanly,
distro/GPU/compositor detection report the right values, all pre-install
failures correspond to the actual missing pieces.
2026-05-23 01:17:42 +00:00

148 lines
4.9 KiB
Bash

#!/usr/bin/env bash
# Post-install verification — confirm each piece is actually wired up.
# Prints a checklist; non-fatal so the user sees the whole picture.
VERIFY_FAILURES=0
_check() {
local name="$1"; shift
if "$@" >/dev/null 2>&1; then
ok "$name"
else
err "$name"
VERIFY_FAILURES=$((VERIFY_FAILURES + 1))
fi
}
verify_install() {
step "Verifying install"
_check "sunshine binary on PATH" command -v sunshine
local bin
bin="$(command -v sunshine 2>/dev/null || true)"
if [[ -n "$bin" ]]; then
bin="$(readlink -f "$bin")"
if getcap "$bin" 2>/dev/null | grep -q cap_sys_admin; then
ok "sunshine has cap_sys_admin (KMS capture ready)"
else
err "sunshine missing cap_sys_admin — KMS capture will fail"
VERIFY_FAILURES=$((VERIFY_FAILURES + 1))
fi
fi
if id -nG "$USER" | tr ' ' '\n' | grep -qx input; then
ok "user '$USER' resolves with 'input' group in current shell"
else
warn "user '$USER' is NOT in 'input' group in this shell session."
warn " /etc/group is correct; you need to log out + back in (or 'newgrp input')."
fi
if grep -rqs 'KERNEL=="uinput"' /etc/udev/rules.d /usr/lib/udev/rules.d /run/udev/rules.d 2>/dev/null; then
ok "uinput udev rule present"
else
err "uinput udev rule missing"
VERIFY_FAILURES=$((VERIFY_FAILURES + 1))
fi
if [[ -c /dev/uinput ]]; then
ok "/dev/uinput exists"
else
warn "/dev/uinput not present yet — may appear on next reboot or 'modprobe uinput'"
fi
case "$GPU_VENDOR" in
nvidia)
if nvidia-smi --query-gpu=encoder.stats.sessionCount --format=csv,noheader >/dev/null 2>&1; then
ok "NVENC interface reachable via nvidia-smi"
else
warn "Could not query NVENC via nvidia-smi (driver may need a reboot after install)"
fi
;;
amd)
if command -v vainfo >/dev/null 2>&1 && vainfo 2>/dev/null | grep -qi 'VAEntrypointEncSlice\|VAProfileH264'; then
ok "VAAPI encoder profiles available"
else
warn "VAAPI encoder profiles not confirmed (install libva-utils to verify with 'vainfo')"
fi
;;
esac
if [[ "${STREAM_MODE:-}" == "headless" ]]; then
local do_script="$HOME/.local/share/omarchy-moonlight/bin/sunshine-stream-do.sh"
local undo_script="$HOME/.local/share/omarchy-moonlight/bin/sunshine-stream-undo.sh"
local conf="$HOME/.config/sunshine/sunshine.conf"
if [[ -x "$do_script" ]]; then
ok "headless do-hook present and executable"
else
err "headless do-hook missing or not executable: $do_script"
VERIFY_FAILURES=$((VERIFY_FAILURES + 1))
fi
if [[ -x "$undo_script" ]]; then
ok "headless undo-hook present and executable"
else
err "headless undo-hook missing or not executable: $undo_script"
VERIFY_FAILURES=$((VERIFY_FAILURES + 1))
fi
if [[ -f "$conf" ]] && grep -q '^capture = wlr' "$conf"; then
ok "sunshine.conf has capture = wlr"
else
err "sunshine.conf missing 'capture = wlr'"
VERIFY_FAILURES=$((VERIFY_FAILURES + 1))
fi
if [[ -f "$conf" ]] && grep -q '^global_prep_cmd' "$conf"; then
ok "sunshine.conf has global_prep_cmd"
else
err "sunshine.conf missing 'global_prep_cmd'"
VERIFY_FAILURES=$((VERIFY_FAILURES + 1))
fi
fi
local sunshine_cert="$HOME/.config/sunshine/credentials/cacert.pem"
if [[ -f "$sunshine_cert" ]]; then
local issuer
issuer="$(openssl x509 -in "$sunshine_cert" -noout -issuer 2>/dev/null || true)"
if grep -qF 'omarchy-stream' <<<"$issuer"; then
ok "Sunshine cert is signed by the omarchy-stream CA"
if openssl x509 -in "$sunshine_cert" -checkend $((30 * 86400)) -noout >/dev/null 2>&1; then
ok "Sunshine cert valid for >30 days"
else
warn "Sunshine cert expires within 30 days — re-run install.sh to renew"
fi
else
info "Sunshine cert is Sunshine's self-signed default (no CA chain)"
fi
else
info "Sunshine cert not present yet (will be generated on first start)"
fi
local _anchor
_anchor="$(ca_anchor_path 2>/dev/null || true)"
if [[ -n "$_anchor" && -f "$_anchor" ]]; then
ok "omarchy-stream CA installed in system trust store ($_anchor)"
else
info "omarchy-stream CA not in system trust store (only matters if --no-certs was used)"
fi
if systemctl --user is-active --quiet sunshine.service; then
ok "sunshine.service is active"
if ss -ltn 2>/dev/null | grep -q ':47990 '; then
ok "web UI listening on :47990"
else
warn "web UI port 47990 not yet listening (service may still be starting)"
fi
else
warn "sunshine.service is not active"
warn " Inspect: journalctl --user -u sunshine -n 50 --no-pager"
fi
if [[ $VERIFY_FAILURES -gt 0 ]]; then
warn "$VERIFY_FAILURES check(s) failed — see ${BOLD}README.md${RESET}${YELLOW} 'Diagnostics' for fixes."
else
ok "All checks passed."
fi
}