Phase 5 — RPi Kiosk: - setup_kiosk.sh: full RPi OS Lite setup (X11, Chromium kiosk mode, auto-login, DPMS disabled, GPU memory split, screen rotation) - kiosk.service: systemd unit for reliable auto-start - update_kiosk.sh: reconfigure URL/rotation/resolution without re-setup - Handles both Bullseye and Bookworm RPi OS versions Phase 9 — Hardening + Deployment: - install.sh: full server setup (apt/pacman, vigilar user, venv, directories, permissions, mosquitto config, systemd units) - gen_cert.sh: TLS cert via mkcert or openssl fallback - gen_vapid_keys.sh: VAPID keys for Web Push notifications - setup_nut.sh: NUT configuration with USB UPS auto-detection - backup.sh: SQLite snapshot + config archive, cron-ready - uninstall.sh: clean removal with data preservation option - vigilar.service: hardened systemd unit (ProtectSystem, NoNewPrivileges, PrivateTmp, syscall filtering) - vigilar-mosquitto.conf: localhost-only MQTT broker config All scripts idempotent, bash -n validated, support Debian + Arch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
204 lines
5.6 KiB
Bash
Executable File
204 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Vigilar — NUT (Network UPS Tools) configuration helper
|
|
# Detects USB UPS devices and configures NUT for standalone monitoring.
|
|
|
|
info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; }
|
|
ok() { printf '\033[1;32m[ OK ]\033[0m %s\n' "$*"; }
|
|
warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; }
|
|
fail() { printf '\033[1;31m[FAIL]\033[0m %s\n' "$*" >&2; exit 1; }
|
|
|
|
detect_pkg_manager() {
|
|
if command -v apt-get &>/dev/null; then
|
|
echo "apt"
|
|
elif command -v pacman &>/dev/null; then
|
|
echo "pacman"
|
|
else
|
|
fail "Unsupported package manager."
|
|
fi
|
|
}
|
|
|
|
install_nut() {
|
|
if command -v upsc &>/dev/null; then
|
|
ok "NUT already installed"
|
|
return
|
|
fi
|
|
|
|
info "Installing NUT"
|
|
local pkg_mgr
|
|
pkg_mgr="$(detect_pkg_manager)"
|
|
|
|
case "$pkg_mgr" in
|
|
apt)
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq nut nut-client nut-server
|
|
;;
|
|
pacman)
|
|
sudo pacman -Sy --needed --noconfirm nut
|
|
;;
|
|
esac
|
|
ok "NUT installed"
|
|
}
|
|
|
|
detect_ups() {
|
|
info "Scanning for USB UPS devices..."
|
|
|
|
local driver=""
|
|
local port=""
|
|
local desc=""
|
|
|
|
# Try nut-scanner first
|
|
if command -v nut-scanner &>/dev/null; then
|
|
local scan_output
|
|
scan_output="$(sudo nut-scanner -U 2>/dev/null)" || true
|
|
if [[ -n "$scan_output" ]]; then
|
|
driver="$(echo "$scan_output" | grep -oP 'driver\s*=\s*"\K[^"]+' | head -1)" || true
|
|
port="$(echo "$scan_output" | grep -oP 'port\s*=\s*"\K[^"]+' | head -1)" || true
|
|
desc="$(echo "$scan_output" | grep -oP 'desc\s*=\s*"\K[^"]+' | head -1)" || true
|
|
fi
|
|
fi
|
|
|
|
# Fallback: check for common USB UPS vendor IDs
|
|
if [[ -z "$driver" ]]; then
|
|
if lsusb 2>/dev/null | grep -qi "051d"; then
|
|
driver="usbhid-ups"
|
|
port="auto"
|
|
desc="APC UPS (auto-detected via lsusb)"
|
|
elif lsusb 2>/dev/null | grep -qi "0764"; then
|
|
driver="usbhid-ups"
|
|
port="auto"
|
|
desc="CyberPower UPS (auto-detected via lsusb)"
|
|
elif lsusb 2>/dev/null | grep -qi "0463"; then
|
|
driver="usbhid-ups"
|
|
port="auto"
|
|
desc="Eaton UPS (auto-detected via lsusb)"
|
|
elif lsusb 2>/dev/null | grep -qi "06da"; then
|
|
driver="usbhid-ups"
|
|
port="auto"
|
|
desc="Phoenixtec/Tripp Lite UPS (auto-detected via lsusb)"
|
|
fi
|
|
fi
|
|
|
|
if [[ -z "$driver" ]]; then
|
|
warn "No USB UPS detected. Using generic usbhid-ups driver with auto port."
|
|
warn "You may need to edit /etc/nut/ups.conf manually."
|
|
driver="usbhid-ups"
|
|
port="auto"
|
|
desc="UPS (not auto-detected)"
|
|
else
|
|
ok "Detected UPS: ${desc:-unknown}"
|
|
fi
|
|
|
|
# Export for use in config generation
|
|
UPS_DRIVER="$driver"
|
|
UPS_PORT="$port"
|
|
UPS_DESC="${desc:-UPS}"
|
|
}
|
|
|
|
generate_configs() {
|
|
info "Generating NUT configuration"
|
|
|
|
# /etc/nut/nut.conf — standalone mode
|
|
sudo tee /etc/nut/nut.conf > /dev/null <<'NUTCONF'
|
|
# Vigilar NUT configuration — standalone mode
|
|
MODE=standalone
|
|
NUTCONF
|
|
|
|
# /etc/nut/ups.conf — UPS definition
|
|
sudo tee /etc/nut/ups.conf > /dev/null <<UPSCONF
|
|
# Vigilar UPS configuration
|
|
# Generated by setup_nut.sh
|
|
|
|
[ups]
|
|
driver = ${UPS_DRIVER}
|
|
port = ${UPS_PORT}
|
|
desc = "${UPS_DESC}"
|
|
pollinterval = 15
|
|
UPSCONF
|
|
|
|
# /etc/nut/upsd.conf — daemon config (localhost only)
|
|
sudo tee /etc/nut/upsd.conf > /dev/null <<'UPSDCONF'
|
|
# Vigilar upsd configuration
|
|
LISTEN 127.0.0.1 3493
|
|
UPSDCONF
|
|
|
|
# /etc/nut/upsd.users — local monitoring user
|
|
sudo tee /etc/nut/upsd.users > /dev/null <<'USERSCONF'
|
|
[vigilar]
|
|
password = vigilar_local
|
|
upsmon master
|
|
USERSCONF
|
|
|
|
# /etc/nut/upsmon.conf — monitoring config
|
|
sudo tee /etc/nut/upsmon.conf > /dev/null <<'MONCONF'
|
|
# Vigilar upsmon configuration
|
|
MONITOR ups@localhost 1 vigilar vigilar_local master
|
|
MINSUPPLIES 1
|
|
SHUTDOWNCMD "/sbin/shutdown -h +0"
|
|
POLLFREQ 15
|
|
POLLFREQALERT 5
|
|
HOSTSYNC 15
|
|
DEADTIME 45
|
|
RBWARNTIME 43200
|
|
NOCOMMWARNTIME 600
|
|
FINALDELAY 5
|
|
MONCONF
|
|
|
|
# Secure the config files
|
|
sudo chmod 0640 /etc/nut/ups.conf /etc/nut/upsd.conf /etc/nut/upsd.users /etc/nut/upsmon.conf
|
|
sudo chown root:nut /etc/nut/ups.conf /etc/nut/upsd.conf /etc/nut/upsd.users /etc/nut/upsmon.conf 2>/dev/null || true
|
|
|
|
ok "NUT configuration files written"
|
|
}
|
|
|
|
enable_services() {
|
|
info "Enabling and starting NUT services"
|
|
|
|
# Service names vary by distro
|
|
local driver_svc="nut-driver"
|
|
local server_svc="nut-server"
|
|
local monitor_svc="nut-monitor"
|
|
|
|
# On Arch, the services may be named differently
|
|
if ! systemctl list-unit-files "${server_svc}.service" &>/dev/null; then
|
|
if systemctl list-unit-files "upsd.service" &>/dev/null; then
|
|
server_svc="upsd"
|
|
monitor_svc="upsmon"
|
|
driver_svc="nut-driver-enumerator"
|
|
fi
|
|
fi
|
|
|
|
# Enable and start
|
|
for svc in "$driver_svc" "$server_svc" "$monitor_svc"; do
|
|
if systemctl list-unit-files "${svc}.service" &>/dev/null; then
|
|
sudo systemctl enable "${svc}.service" 2>/dev/null || true
|
|
sudo systemctl restart "${svc}.service" 2>/dev/null || warn "Could not start ${svc}.service — check UPS connection"
|
|
fi
|
|
done
|
|
|
|
ok "NUT services enabled"
|
|
}
|
|
|
|
main() {
|
|
info "=== Vigilar NUT Setup ==="
|
|
echo
|
|
|
|
install_nut
|
|
|
|
UPS_DRIVER=""
|
|
UPS_PORT=""
|
|
UPS_DESC=""
|
|
detect_ups
|
|
|
|
generate_configs
|
|
enable_services
|
|
|
|
echo
|
|
ok "=== NUT setup complete ==="
|
|
info "Test with: upsc ups@localhost"
|
|
info "Vigilar will monitor UPS at 127.0.0.1:3493 (ups name: 'ups')"
|
|
}
|
|
|
|
main "$@"
|