#!/usr/bin/env bash set -euo pipefail if [[ "${EUID}" -ne 0 ]]; then echo "Run as root: sudo ./scripts/install.sh" >&2 exit 1 fi REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" BIN_DIR="/usr/local/bin" CONF_DIR="/etc/ananke" STATE_DIR="/var/lib/ananke" SYSTEMD_DIR="/etc/systemd/system" LIB_DIR="/usr/local/lib/ananke" START_NOW=1 INSTALL_DEPS=1 ENABLE_BOOTSTRAP="${ANANKE_ENABLE_BOOTSTRAP:-auto}" MANAGE_NUT="${ANANKE_MANAGE_NUT:-1}" NUT_UPS_NAME="${ANANKE_NUT_UPS_NAME:-}" NUT_VENDOR_ID="${ANANKE_NUT_VENDOR_ID:-0764}" NUT_PRODUCT_ID="${ANANKE_NUT_PRODUCT_ID:-0601}" NUT_MONITOR_USER="${ANANKE_NUT_MONITOR_USER:-monuser}" NUT_MONITOR_PASSWORD="${ANANKE_NUT_MONITOR_PASSWORD:-anankeupsmon}" FORCE_CONFIG_TEMPLATE="${ANANKE_FORCE_CONFIG_TEMPLATE:-}" ENFORCE_QUALITY_GATE="${ANANKE_ENFORCE_QUALITY_GATE:-1}" while [[ $# -gt 0 ]]; do case "$1" in --no-start) START_NOW=0 shift ;; --skip-deps) INSTALL_DEPS=0 shift ;; *) echo "Unknown argument: $1" >&2 exit 1 ;; esac done source "${REPO_DIR}/scripts/install-config-migration.sh" source "${REPO_DIR}/scripts/install-host-bootstrap.sh" source "${REPO_DIR}/scripts/install-legacy-migration.sh" source "${REPO_DIR}/scripts/install-artifacts.sh" ensure_dependencies migrate_legacy_hecate_install if [[ "${ENFORCE_QUALITY_GATE}" == "1" ]]; then echo "[install] running quality gate" "${REPO_DIR}/scripts/quality_gate.sh" else echo "[install] skipping quality gate (ANANKE_ENFORCE_QUALITY_GATE=${ENFORCE_QUALITY_GATE})" fi echo "[install] building ananke" cd "${REPO_DIR}" mkdir -p dist BUILD_TARGET="$(resolve_build_target || true)" if [[ -z "${BUILD_TARGET}" ]]; then echo "[install] unable to find build target (expected cmd/ananke)." >&2 exit 1 fi go build -o dist/ananke "${BUILD_TARGET}" echo "[install] installing binary" install -d -m 0755 "${BIN_DIR}" install -m 0755 dist/ananke "${BIN_DIR}/ananke" echo "[install] installing config + state dirs" install -d -m 0750 "${CONF_DIR}" install -d -m 0750 "${STATE_DIR}" install -d -m 0750 "${STATE_DIR}/reports" install -d -m 0755 "${LIB_DIR}" if [[ -n "${FORCE_CONFIG_TEMPLATE}" ]]; then case "${FORCE_CONFIG_TEMPLATE}" in coordinator) install_config_template coordinator "${CONF_DIR}/ananke.yaml" echo "[install] forced config template: coordinator" ;; peer) install_config_template peer "${CONF_DIR}/ananke.yaml" echo "[install] forced config template: peer" ;; example) install_config_template example "${CONF_DIR}/ananke.yaml" echo "[install] forced config template: example" ;; *) echo "[install] unknown ANANKE_FORCE_CONFIG_TEMPLATE value: ${FORCE_CONFIG_TEMPLATE}" >&2 exit 1 ;; esac elif [[ ! -f "${CONF_DIR}/ananke.yaml" ]]; then install_config_template example "${CONF_DIR}/ananke.yaml" echo "[install] wrote default config to ${CONF_DIR}/ananke.yaml" else echo "[install] keeping existing config at ${CONF_DIR}/ananke.yaml" fi migrate_ananke_config sanitize_migrated_ananke_config ensure_ananke_ssh_identity ensure_ananke_kubeconfig echo "[install] installing systemd units" install_systemd_units install_self_update_script resolve_nut_ups_name configure_nut systemctl daemon-reload systemctl enable ananke.service ananke-update.timer if [[ "${ENABLE_BOOTSTRAP}" == "1" ]]; then systemctl enable ananke-bootstrap.service elif [[ "${ENABLE_BOOTSTRAP}" == "0" ]]; then systemctl disable ananke-bootstrap.service >/dev/null 2>&1 || true else role="$(read_ananke_role)" systemctl enable ananke-bootstrap.service echo "[install] auto-enabled ananke-bootstrap.service for role=${role}" fi if [[ "${START_NOW}" -eq 1 ]]; then systemctl restart ananke.service systemctl restart ananke-update.timer echo "[install] ananke.service restarted" fi retire_legacy_hecate_install systemctl daemon-reload echo "[install] done" echo "Next steps:" echo " 1. Edit /etc/ananke/ananke.yaml" echo " 2. Run: ananke status --config /etc/ananke/ananke.yaml" echo " 3. Test dry run: ananke startup --config /etc/ananke/ananke.yaml" echo " 4. Trigger bootstrap now (db host): systemctl start ananke-bootstrap.service" echo " 5. Trigger self-update now: systemctl start ananke-update.service"