#!/usr/bin/env bash set -eEuo pipefail readonly REPO_DIR="/opt/fapg/fapg-daq" readonly DASHBOARD_SCRIPT="${REPO_DIR}/roles/dashboard/script/dashboard" readonly WEATHER_SCRIPT="${REPO_DIR}/roles/dashboard/script/fetch-weather" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly SCRIPT_DIR readonly SERVICE_NAME="fapg-daq-dashboard.service" readonly WEATHER_SERVICE_NAME="fapg-daq-dashboard-weather.service" readonly WEATHER_TIMER_NAME="fapg-daq-dashboard-weather.timer" readonly SERVICE_SOURCE="${SCRIPT_DIR}/etc/systemd/system/${SERVICE_NAME}" readonly WEATHER_SERVICE_SOURCE="${SCRIPT_DIR}/etc/systemd/system/${WEATHER_SERVICE_NAME}" readonly WEATHER_TIMER_SOURCE="${SCRIPT_DIR}/etc/systemd/system/${WEATHER_TIMER_NAME}" readonly SYSTEMD_DIR="/etc/systemd/system" readonly NGINX_GZIP_SOURCE="${SCRIPT_DIR}/etc/nginx/conf.d/fapg-daq-dashboard-gzip.conf" readonly NGINX_GZIP_FILE="/etc/nginx/conf.d/fapg-daq-dashboard-gzip.conf" readonly STATE_DIR="/var/lib/fapg-daq" readonly SECRET_FILE="${STATE_DIR}/dashboard.secret" readonly LEGACY_SECRET_FILE="${REPO_DIR}/roles/dashboard/.mojo-secrets" readonly RUN_USER="fapg-daq" readonly RUN_GROUP="fapg-daq" function die() { echo "ERROR: $*" >&2 exit 1 } function require_root() { if [[ "$(id -u)" -ne 0 ]]; then die "$0 requires superuser privileges." fi } function install_os_dependencies() { apt-get update apt-get install -y \ perl \ nginx \ libdbd-sqlite3-perl \ libexcel-writer-xlsx-perl \ libmojolicious-perl \ libmojo-sqlite-perl } function create_runtime_user() { if ! getent group "${RUN_GROUP}" > /dev/null; then addgroup --system "${RUN_GROUP}" fi if ! id "${RUN_USER}" > /dev/null 2>&1; then adduser \ --system \ --ingroup "${RUN_GROUP}" \ --home "${STATE_DIR}" \ --no-create-home \ --disabled-login \ "${RUN_USER}" fi mkdir -p "${STATE_DIR}" chown "${RUN_USER}:${RUN_GROUP}" "${STATE_DIR}" } function migrate_application_secret() { if [[ ! -e "${SECRET_FILE}" && -f "${LEGACY_SECRET_FILE}" ]]; then install -m 0600 -o "${RUN_USER}" -g "${RUN_GROUP}" \ "${LEGACY_SECRET_FILE}" \ "${SECRET_FILE}" fi } function check_repo_layout() { [[ -d "${REPO_DIR}" ]] || die "Repo not found at ${REPO_DIR}." [[ -f "${DASHBOARD_SCRIPT}" ]] || die "${DASHBOARD_SCRIPT} does not exist." [[ -x "${WEATHER_SCRIPT}" ]] || die "${WEATHER_SCRIPT} is not executable." [[ -f "${SERVICE_SOURCE}" ]] || die "${SERVICE_SOURCE} does not exist." [[ -f "${WEATHER_SERVICE_SOURCE}" ]] || die "${WEATHER_SERVICE_SOURCE} does not exist." [[ -f "${WEATHER_TIMER_SOURCE}" ]] || die "${WEATHER_TIMER_SOURCE} does not exist." [[ -f "${NGINX_GZIP_SOURCE}" ]] || die "${NGINX_GZIP_SOURCE} does not exist." } function write_systemd_services() { install -m 0644 -o root -g root \ "${SERVICE_SOURCE}" \ "${WEATHER_SERVICE_SOURCE}" \ "${WEATHER_TIMER_SOURCE}" \ "${SYSTEMD_DIR}/" } function configure_nginx_compression() { install -m 0644 -o root -g root \ "${NGINX_GZIP_SOURCE}" \ "${NGINX_GZIP_FILE}" sudo nginx -t systemctl enable --now nginx systemctl reload nginx } function enable_services() { systemctl daemon-reload systemctl enable "${SERVICE_NAME}" systemctl enable --now "${WEATHER_TIMER_NAME}" systemctl restart "${SERVICE_NAME}" } function show_status() { cat <<"EOF" Deployment complete. Current service state: EOF systemctl --no-pager --full status \ "${SERVICE_NAME}" \ "${WEATHER_TIMER_NAME}" } function main() { require_root install_os_dependencies create_runtime_user check_repo_layout migrate_application_secret write_systemd_services configure_nginx_compression enable_services show_status } main "$@"