276 lines
9.7 KiB
Bash
276 lines
9.7 KiB
Bash
#!/bin/bash
|
|
# =============================================================================
|
|
# ns8-backup-monitor - Installer / Uninstaller
|
|
# =============================================================================
|
|
# Usage:
|
|
# install.sh - install (interactive)
|
|
# install.sh --uninstall - remove everything installed by this script
|
|
#
|
|
# Requires: root, python3, curl (no git needed)
|
|
# Tested on: AlmaLinux 8/9, Rocky Linux 8/9 (NS8 supported distros)
|
|
#
|
|
# ns8-sendmail is NOT in the standard root PATH on NS8 nodes.
|
|
# The installer checks for it via 'runagent' (the NS8 agent runner) instead of
|
|
# relying on PATH lookup. This is the correct way to invoke NS8 built-in tools.
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
# --- constants ----------------------------------------------------------------
|
|
SERVICE_NAME="ns8-backup-monitor"
|
|
INSTALL_DIR="/opt/ns8-backup-monitor"
|
|
CONFIG_DIR="/etc/ns8-backup-monitor"
|
|
CONFIG_FILE="${CONFIG_DIR}/config.yml"
|
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
|
|
|
# Gitea raw base URL for downloading individual files
|
|
RAW_BASE="https://repo.lelekaos.com/admin/ns8-backup-monitor/raw/branch/main"
|
|
# Gitea archive URL (no git needed - just curl)
|
|
ARCHIVE_URL="https://repo.lelekaos.com/admin/ns8-backup-monitor/archive/main.tar.gz"
|
|
|
|
PYTHON=$(command -v python3 || true)
|
|
|
|
# --- colours ------------------------------------------------------------------
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'; BOLD='\033[1m'; RESET='\033[0m'
|
|
|
|
info() { echo -e "${BLUE}[INFO]${RESET} $*"; }
|
|
ok() { echo -e "${GREEN}[OK]${RESET} $*"; }
|
|
warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; }
|
|
error() { echo -e "${RED}[ERROR]${RESET} $*" >&2; exit 1; }
|
|
|
|
# =============================================================================
|
|
# CHECK NS8-SENDMAIL
|
|
# On NS8 nodes, ns8-sendmail is not in the standard root PATH.
|
|
# The canonical way to verify it is available is to check that 'runagent'
|
|
# exists (the NS8 agent runner), since ns8-sendmail is always provided by the
|
|
# NS8 environment that also provides runagent.
|
|
# =============================================================================
|
|
check_ns8_sendmail() {
|
|
# First try direct PATH lookup (covers non-standard installs)
|
|
if command -v ns8-sendmail &>/dev/null; then
|
|
return 0
|
|
fi
|
|
# On NS8 nodes, ns8-sendmail is invoked through the NS8 environment.
|
|
# If runagent is present, ns8-sendmail is available at runtime.
|
|
if command -v runagent &>/dev/null; then
|
|
return 0
|
|
fi
|
|
# Neither found: genuine warning
|
|
return 1
|
|
}
|
|
|
|
# =============================================================================
|
|
# UNINSTALL
|
|
# =============================================================================
|
|
do_uninstall() {
|
|
echo -e "${BOLD}=== ns8-backup-monitor UNINSTALL ===${RESET}"
|
|
warn "This will stop and remove the service, code and config."
|
|
read -rp "Continue? [y/N] " confirm
|
|
[[ "$confirm" =~ ^[Yy]$ ]] || { info "Aborted."; exit 0; }
|
|
|
|
if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
|
|
info "Stopping service..."
|
|
systemctl stop "$SERVICE_NAME"
|
|
fi
|
|
if systemctl is-enabled --quiet "$SERVICE_NAME" 2>/dev/null; then
|
|
info "Disabling service..."
|
|
systemctl disable "$SERVICE_NAME"
|
|
fi
|
|
|
|
if [[ -f "$SERVICE_FILE" ]]; then
|
|
info "Removing systemd unit..."
|
|
rm -f "$SERVICE_FILE"
|
|
systemctl daemon-reload
|
|
ok "Systemd unit removed."
|
|
fi
|
|
|
|
if [[ -d "$INSTALL_DIR" ]]; then
|
|
info "Removing ${INSTALL_DIR}..."
|
|
rm -rf "$INSTALL_DIR"
|
|
ok "Install directory removed."
|
|
fi
|
|
|
|
if [[ -d "$CONFIG_DIR" ]]; then
|
|
read -rp "Remove config directory ${CONFIG_DIR}? [y/N] " rmcfg
|
|
if [[ "$rmcfg" =~ ^[Yy]$ ]]; then
|
|
rm -rf "$CONFIG_DIR"
|
|
ok "Config directory removed."
|
|
else
|
|
warn "Config kept at ${CONFIG_DIR}."
|
|
fi
|
|
fi
|
|
|
|
echo -e "${GREEN}${BOLD}Uninstall complete.${RESET}"
|
|
}
|
|
|
|
# =============================================================================
|
|
# DOWNLOAD SOURCE
|
|
# =============================================================================
|
|
download_source() {
|
|
# BUG FIX: declare and assign on the same line so that 'set -u' never sees
|
|
# an unset variable, even if the trap fires before mktemp succeeds.
|
|
local tmpdir; tmpdir=$(mktemp -d)
|
|
# The trap now always has a valid $tmpdir value.
|
|
trap 'rm -rf "$tmpdir"' RETURN
|
|
|
|
info "Downloading source archive..."
|
|
curl -fsSL "$ARCHIVE_URL" -o "${tmpdir}/archive.tar.gz" \
|
|
|| error "Failed to download archive from ${ARCHIVE_URL}"
|
|
|
|
info "Extracting..."
|
|
mkdir -p "$INSTALL_DIR"
|
|
# Gitea archives extract to a subdirectory named <repo>-<branch>/
|
|
tar -xzf "${tmpdir}/archive.tar.gz" -C "${tmpdir}"
|
|
local extracted_dir
|
|
extracted_dir=$(find "${tmpdir}" -mindepth 1 -maxdepth 1 -type d | head -n1)
|
|
[[ -n "$extracted_dir" ]] || error "Could not find extracted directory in archive."
|
|
|
|
# Sync into INSTALL_DIR (rsync-style, pure bash)
|
|
cp -a "${extracted_dir}/." "$INSTALL_DIR/"
|
|
ok "Source ready at ${INSTALL_DIR}."
|
|
}
|
|
|
|
# =============================================================================
|
|
# INSTALL
|
|
# =============================================================================
|
|
do_install() {
|
|
echo -e "${BOLD}=== ns8-backup-monitor INSTALLER ===${RESET}\n"
|
|
|
|
# --- pre-flight -----------------------------------------------------------
|
|
[[ $EUID -eq 0 ]] || error "Run as root (or with sudo)."
|
|
[[ -n "$PYTHON" ]] || error "python3 not found."
|
|
command -v curl &>/dev/null || error "curl not found."
|
|
command -v tar &>/dev/null || error "tar not found."
|
|
|
|
# Check ns8-sendmail availability the NS8-correct way (via runagent).
|
|
if check_ns8_sendmail; then
|
|
ok "ns8-sendmail available (NS8 node confirmed)."
|
|
else
|
|
warn "Neither ns8-sendmail nor runagent found."
|
|
warn "Make sure this runs on an NS8 node, or email delivery will fail."
|
|
fi
|
|
|
|
# --- interactive mail config ----------------------------------------------
|
|
echo -e "${BOLD}Mail configuration${RESET}"
|
|
echo -e "Email delivery uses ${BLUE}ns8-sendmail${RESET} (NS8 configured relay)."
|
|
echo
|
|
|
|
local default_from="ns8-backup-monitor@$(hostname -f 2>/dev/null || echo localhost)"
|
|
read -rp "Sender address (From) [${default_from}]: " MAIL_FROM
|
|
MAIL_FROM="${MAIL_FROM:-$default_from}"
|
|
|
|
local MAIL_TO_LIST=()
|
|
echo "Recipient addresses (To) - one per line, empty line when done:"
|
|
while true; do
|
|
read -rp " Recipient: " addr
|
|
[[ -z "$addr" ]] && break
|
|
MAIL_TO_LIST+=("$addr")
|
|
done
|
|
[[ ${#MAIL_TO_LIST[@]} -gt 0 ]] || error "At least one recipient is required."
|
|
|
|
read -rp "Subject prefix [[NS8 Backup]]: " SUBJECT_PREFIX
|
|
SUBJECT_PREFIX="${SUBJECT_PREFIX:-[NS8 Backup]}"
|
|
|
|
echo
|
|
info "From: $MAIL_FROM"
|
|
info "To: ${MAIL_TO_LIST[*]}"
|
|
info "Prefix: $SUBJECT_PREFIX"
|
|
echo
|
|
read -rp "Confirm and proceed with install? [Y/n] " go
|
|
[[ "$go" =~ ^[Nn]$ ]] && { info "Aborted."; exit 0; }
|
|
echo
|
|
|
|
# --- download source ------------------------------------------------------
|
|
if [[ -d "$INSTALL_DIR" ]]; then
|
|
info "${INSTALL_DIR} already exists - updating source..."
|
|
rm -rf "$INSTALL_DIR"
|
|
fi
|
|
download_source
|
|
|
|
# --- config directory -----------------------------------------------------
|
|
mkdir -p "$CONFIG_DIR"
|
|
chmod 750 "$CONFIG_DIR"
|
|
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
warn "Config ${CONFIG_FILE} already exists - keeping it."
|
|
warn "Edit it manually to change mail settings."
|
|
else
|
|
info "Writing ${CONFIG_FILE}..."
|
|
|
|
# Build YAML 'to' list
|
|
local to_yaml=""
|
|
for addr in "${MAIL_TO_LIST[@]}"; do
|
|
to_yaml+=" - \"${addr}\"\n"
|
|
done
|
|
|
|
cat > "$CONFIG_FILE" << EOF
|
|
# ns8-backup-monitor configuration
|
|
# Generated by install.sh on $(date -u '+%Y-%m-%d %H:%M UTC')
|
|
|
|
# Email delivery is handled by ns8-sendmail (NS8 configured relay).
|
|
mail:
|
|
from: "${MAIL_FROM}"
|
|
to:
|
|
$(printf '%b' "$to_yaml")
|
|
subject_prefix: "${SUBJECT_PREFIX}"
|
|
|
|
receiver:
|
|
host: "127.0.0.1"
|
|
port: 9099
|
|
|
|
correlator:
|
|
wait_seconds: 30
|
|
recent_window: 3600
|
|
|
|
redis:
|
|
socket: "/var/lib/nethserver/cluster/state/redis.sock"
|
|
|
|
repo_check:
|
|
timeout: 60
|
|
restic_flags: ""
|
|
|
|
logging:
|
|
level: INFO
|
|
file: "/var/log/ns8-backup-monitor.log"
|
|
EOF
|
|
chmod 640 "$CONFIG_FILE"
|
|
ok "Config written."
|
|
fi
|
|
|
|
# --- systemd unit ---------------------------------------------------------
|
|
info "Installing systemd unit..."
|
|
cp "${INSTALL_DIR}/deploy/ns8-backup-monitor.service" "$SERVICE_FILE"
|
|
systemctl daemon-reload
|
|
systemctl enable --now "$SERVICE_NAME"
|
|
ok "Service enabled and started."
|
|
|
|
# --- done -----------------------------------------------------------------
|
|
echo
|
|
echo -e "${GREEN}${BOLD}Installation complete.${RESET}"
|
|
echo -e " Config: ${CONFIG_FILE}"
|
|
echo -e " Status: systemctl status ${SERVICE_NAME}"
|
|
echo -e " Logs: journalctl -u ${SERVICE_NAME} -f"
|
|
echo
|
|
echo -e "To uninstall: ${BOLD}bash ${INSTALL_DIR}/deploy/install.sh --uninstall${RESET}"
|
|
echo -e "To update: ${BOLD}bash <(curl -fsSL ${RAW_BASE}/deploy/install.sh)${RESET}"
|
|
}
|
|
|
|
# =============================================================================
|
|
# ENTRYPOINT
|
|
# =============================================================================
|
|
case "${1:-}" in
|
|
--uninstall|-u|uninstall)
|
|
do_uninstall
|
|
;;
|
|
--help|-h)
|
|
echo "Usage: $0 [--uninstall]"
|
|
exit 0
|
|
;;
|
|
"")
|
|
do_install
|
|
;;
|
|
*)
|
|
error "Unknown argument: $1. Use --uninstall to remove."
|
|
;;
|
|
esac
|