Files
radar_system/deploy/install-daemon.sh
T
2026-06-04 18:33:38 +03:00

93 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Install and enable the radar headless daemon (systemd system service), plus a
# passwordless sudoers rule that lets the service user stop/start it (start.sh
# stops the daemon before launching the interactive GUI).
#
# Run once as root, from anywhere inside the project:
# sudo bash deploy/install-daemon.sh
#
# Re-running is safe: it overwrites the unit/sudoers with current paths.
set -euo pipefail
if [[ "${EUID}" -ne 0 ]]; then
echo "Must run as root: sudo bash $0" >&2
exit 1
fi
PROJECT_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
SERVICE_USER="${SUDO_USER:-root}"
START_SH="${PROJECT_ROOT}/start.sh"
SERVICE_NAME="radar.service"
UNIT_PATH="/etc/systemd/system/${SERVICE_NAME}"
SUDOERS_PATH="/etc/sudoers.d/radar"
SYSTEMCTL="$(command -v systemctl)"
if [[ -z "${SYSTEMCTL}" ]]; then
echo "systemctl not found; this installer requires systemd." >&2
exit 1
fi
if [[ ! -x "${START_SH}" ]]; then
echo "start.sh not found or not executable: ${START_SH}" >&2
exit 1
fi
if [[ "${SERVICE_USER}" == "root" ]]; then
echo "Run via sudo from your normal login user (got SUDO_USER=root)." >&2
echo "Example: sudo bash deploy/install-daemon.sh" >&2
exit 1
fi
echo "[install] project_root = ${PROJECT_ROOT}"
echo "[install] service_user = ${SERVICE_USER}"
# --- systemd unit -----------------------------------------------------------
# No network-online dependency: the appliance runs offline and the radar is on
# USB/loopback. Restart=on-failure self-heals crashes but leaves an intentional
# `systemctl stop` (done by start.sh for GUI handover) deactivated.
cat > "${UNIT_PATH}" <<EOF
[Unit]
Description=Radar system (headless autonomous mode)
# Ensure the project filesystem is mounted before start; no network-online
# dependency (offline appliance, radar on USB/loopback). USB device readiness is
# handled by the producer's wait-for-device retry, not a boot-time gate.
After=local-fs.target
RequiresMountsFor=${PROJECT_ROOT}
[Service]
Type=simple
User=${SERVICE_USER}
WorkingDirectory=${PROJECT_ROOT}
ExecStart=${START_SH} --headless --skip-build
Restart=on-failure
RestartSec=3
TimeoutStopSec=25
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
echo "[install] wrote ${UNIT_PATH}"
# --- sudoers: passwordless stop/start/restart for the service user ----------
TMP_SUDO="$(mktemp)"
cat > "${TMP_SUDO}" <<EOF
# Allow ${SERVICE_USER} to control ${SERVICE_NAME} without a password so
# start.sh can stop the headless daemon before launching the interactive GUI.
${SERVICE_USER} ALL=(root) NOPASSWD: ${SYSTEMCTL} stop ${SERVICE_NAME}, ${SYSTEMCTL} start ${SERVICE_NAME}, ${SYSTEMCTL} restart ${SERVICE_NAME}
EOF
visudo -cf "${TMP_SUDO}"
install -m 0440 -o root -g root "${TMP_SUDO}" "${SUDOERS_PATH}"
rm -f "${TMP_SUDO}"
echo "[install] wrote ${SUDOERS_PATH}"
# --- enable -----------------------------------------------------------------
"${SYSTEMCTL}" daemon-reload
"${SYSTEMCTL}" enable "${SERVICE_NAME}"
echo
echo "[install] Done. The daemon will start headless on every boot."
echo "[install] Start now: sudo systemctl start ${SERVICE_NAME}"
echo "[install] Status: systemctl status ${SERVICE_NAME}"
echo "[install] Live log: journalctl -u ${SERVICE_NAME} -f"
echo "[install] Launch GUI: ./start.sh (auto-stops the daemon first)"
echo "[install] Uninstall: sudo systemctl disable --now ${SERVICE_NAME} && sudo rm ${UNIT_PATH} ${SUDOERS_PATH} && sudo systemctl daemon-reload"