Files
LEDMatrix/scripts/install/install_service.sh
T
ChuckandClaude Opus 5 efc7856294 Merge origin/main (#592, #593, #594) into the September 16 core audit fixes
config.py conflict: #594 discovers plugins before /config/main matches plugin
keys; this branch routes those sections through the /plugins/config
preparation (F13). Kept both.

#594's secret-separation test posts a plugin section to /config/main, which
this branch now validates through api_v3.schema_manager; the test gets a real
SchemaManager over its temporary plugins directory instead of the helper's
mock. It still fails if the discovery call is reverted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 12:46:26 -04:00

205 lines
8.0 KiB
Bash
Executable File

#!/bin/bash
# Exit on error
set -e
usage() {
cat <<'USAGE'
Usage: sudo ./scripts/install/install_service.sh [-h|--help]
Installs (or reinstalls) the LEDMatrix systemd units from the templates in
systemd/, then enables and starts them:
- ledmatrix.service main display (runs as root)
- ledmatrix-web.service web interface (runs as the invoking user)
- ledmatrix-update-verify.service automatic-update health check
- ledmatrix-update-verify.path
Existing unit files in /etc/systemd/system are overwritten. The script takes
no other options; run it with no arguments to install.
Options:
-h, --help Show this help and exit without changing anything.
USAGE
}
# Parse arguments before touching anything: this script rewrites and restarts
# services, so an unrecognised option must not fall through to a full install.
for arg in "$@"; do
case "$arg" in
-h|--help)
usage
exit 0
;;
*)
echo "ERROR: unknown option: $arg" >&2
usage >&2
exit 2
;;
esac
done
# Get the actual user who invoked sudo
if [ -n "$SUDO_USER" ]; then
ACTUAL_USER="$SUDO_USER"
else
ACTUAL_USER=$(whoami)
fi
# Get the home directory of the actual user
USER_HOME=$(eval echo ~$ACTUAL_USER)
# Determine the Project Root Directory (parent of scripts/install/)
PROJECT_ROOT_DIR=$(cd "$(dirname "$0")/../.." && pwd)
# shellcheck source=scripts/install/lib_systemd_render.sh
source "$PROJECT_ROOT_DIR/scripts/install/lib_systemd_render.sh"
echo "Installing LED Matrix Display Service for user: $ACTUAL_USER"
echo "Using home directory: $USER_HOME"
echo "Project root directory: $PROJECT_ROOT_DIR"
# Render the main display unit from its template. The display service runs as
# root (it needs GPIO), so __USER__ is always root here -- unlike the web unit
# below, which runs as whoever installed it.
#
# A missing template or a failed render is fatal: falling through would leave
# whatever unit already sits at /etc/systemd/system/ledmatrix.service (from a
# previous install) untouched, and the enable/start step below would then
# silently reuse that stale unit instead of the one this run was asked to
# install.
if [ -f "$PROJECT_ROOT_DIR/systemd/ledmatrix.service" ]; then
ESCAPED_PROJECT_ROOT_DIR=$(sed_escape_replacement "$PROJECT_ROOT_DIR")
MAIN_UNIT_TMP=$(mktemp)
trap 'rm -f "$MAIN_UNIT_TMP"' EXIT
if ! sed "s|__PROJECT_ROOT_DIR__|$ESCAPED_PROJECT_ROOT_DIR|g; s|__USER__|root|g" \
"$PROJECT_ROOT_DIR/systemd/ledmatrix.service" > "$MAIN_UNIT_TMP"; then
echo "ERROR: failed to render ledmatrix.service from its template." >&2
exit 1
fi
# Copy the service file to the systemd directory
sudo cp "$MAIN_UNIT_TMP" /etc/systemd/system/ledmatrix.service
# Clean up
rm -f "$MAIN_UNIT_TMP"
trap - EXIT
else
echo "ERROR: ledmatrix.service template not found at $PROJECT_ROOT_DIR/systemd/ledmatrix.service." >&2
exit 1
fi
# Reload systemd to recognize the new service (or modified service)
sudo systemctl daemon-reload
if [ -f "/etc/systemd/system/ledmatrix.service" ]; then
echo "Enabling ledmatrix.service (main display) to start on boot..."
sudo systemctl enable ledmatrix.service
echo "Starting ledmatrix.service (main display)..."
sudo systemctl start ledmatrix.service
else
echo "Skipping enable/start for ledmatrix.service as it was not configured."
fi
# === LEDMatrix Web Interface service (ledmatrix-web.service) ===
echo "Installing LEDMatrix Web Interface service (ledmatrix-web.service)..."
# Rendered from systemd/ledmatrix-web.service, the same template
# install_web_service.sh uses. This was an inline heredoc until it drifted from
# the template: it had lost Wants=network-online.target, RestartSec,
# SyslogIdentifier and Environment=USE_THREADING. Because
# src/startup_validator.py compares the installed unit against the template,
# every boot warned "re-run install_service.sh" -- and doing so reinstalled the
# same stale copy, so the warning could never clear.
#
# As with the main unit above, a missing template or a failed render is
# fatal -- otherwise the enable/start check below would fall back to
# whatever unit (possibly stale) already exists at the destination path.
if [ -f "$PROJECT_ROOT_DIR/systemd/ledmatrix-web.service" ]; then
ESCAPED_ACTUAL_USER=$(sed_escape_replacement "$ACTUAL_USER")
WEB_UNIT_TMP=$(mktemp)
trap 'rm -f "$WEB_UNIT_TMP"' EXIT
if ! sed "s|__PROJECT_ROOT_DIR__|$ESCAPED_PROJECT_ROOT_DIR|g; s|__USER__|$ESCAPED_ACTUAL_USER|g" \
"$PROJECT_ROOT_DIR/systemd/ledmatrix-web.service" > "$WEB_UNIT_TMP"; then
echo "ERROR: failed to render ledmatrix-web.service from its template." >&2
exit 1
fi
sudo cp "$WEB_UNIT_TMP" /etc/systemd/system/ledmatrix-web.service
rm -f "$WEB_UNIT_TMP"
trap - EXIT
else
echo "ERROR: ledmatrix-web.service template not found at $PROJECT_ROOT_DIR/systemd/ledmatrix-web.service." >&2
exit 1
fi
# Health check / rollback units for automatic updates; see install_web_service.sh.
for VERIFY_UNIT in ledmatrix-update-verify.service ledmatrix-update-verify.path; do
if [ -f "$PROJECT_ROOT_DIR/systemd/$VERIFY_UNIT" ]; then
VERIFY_UNIT_TMP=$(mktemp)
if sed "s|__PROJECT_ROOT_DIR__|$ESCAPED_PROJECT_ROOT_DIR|g; s|__USER__|$ESCAPED_ACTUAL_USER|g" "$PROJECT_ROOT_DIR/systemd/$VERIFY_UNIT" > "$VERIFY_UNIT_TMP"; then
sudo cp "$VERIFY_UNIT_TMP" "/etc/systemd/system/$VERIFY_UNIT"
else
echo "WARNING: failed to render $VERIFY_UNIT; automatic code updates will stay paused." >&2
fi
rm -f "$VERIFY_UNIT_TMP"
fi
done
echo "Reloading systemd daemon for web service..."
sudo systemctl daemon-reload
if [ -f "/etc/systemd/system/ledmatrix-web.service" ]; then
echo "Enabling ledmatrix-web.service to start on boot..."
sudo systemctl enable ledmatrix-web.service
if [ -f /etc/systemd/system/ledmatrix-update-verify.path ]; then
echo "Enabling ledmatrix-update-verify.path (automatic update health check)..."
sudo systemctl enable --now ledmatrix-update-verify.path || echo "WARNING: could not enable ledmatrix-update-verify.path; automatic code updates will stay paused" >&2
fi
echo "Starting ledmatrix-web.service..."
sudo systemctl start ledmatrix-web.service
echo "LEDMatrix Web Interface service (ledmatrix-web.service) installation complete."
echo "It will start based on the 'web_display_autostart' setting in config/config.json."
else
echo "Skipping enable/start for ledmatrix-web.service as it was not configured."
fi
# === End of LEDMatrix Web Interface service ===
# Check the status
echo "Service status for main display (ledmatrix.service):"
sudo systemctl status ledmatrix.service || echo "ledmatrix.service not found or failed to get status."
echo "Service status for web interface (ledmatrix-web.service):"
sudo systemctl status ledmatrix-web.service || echo "ledmatrix-web.service not found or failed to get status."
echo ""
echo "LED Matrix Services have been processed."
echo ""
echo "To stop the main display when you SSH in:"
echo " sudo systemctl stop ledmatrix.service"
echo "To stop the web interface:"
echo " sudo systemctl stop ledmatrix-web.service"
echo ""
echo "To check if the main display service is running:"
echo " sudo systemctl status ledmatrix.service"
echo "To check if the web interface service is running:"
echo " sudo systemctl status ledmatrix-web.service"
echo ""
echo "To restart the main display service:"
echo " sudo systemctl restart ledmatrix.service"
echo "To restart the web interface service:"
echo " sudo systemctl restart ledmatrix-web.service"
echo ""
echo "To view logs for the main display:"
echo " journalctl -u ledmatrix.service"
echo "To view logs for the web interface:"
echo " journalctl -u ledmatrix-web.service"
echo ""
echo "To disable autostart for the main display:"
echo " sudo systemctl disable ledmatrix.service"
echo "To disable autostart for the web interface:"
echo " sudo systemctl disable ledmatrix-web.service"