#!/usr/bin/env bash set -Eeuo pipefail SERVER="${NUT_SERVER:-192.168.3.12}" PORT="${NUT_PORT:-3493}" UPS_NAME="${NUT_UPS_NAME:-ups}" USERNAME="${NUT_USERNAME:-monuser}" PASSWORD="${NUT_PASSWORD:-secret}" # "slave" is retained for compatibility with NUT versions shipped by older # Proxmox releases; current NUT accepts it as an alias for "secondary". ROLE="${NUT_ROLE:-slave}" NON_INTERACTIVE=false usage() { cat <<'EOF' Настройка Proxmox как NUT-клиента Synology. Использование: bash install-proxmox-nut-client.sh [параметры] Параметры: --server IP NUT-сервер (192.168.3.12) --port PORT порт (3493) --ups NAME имя UPS (ups) --username USER пользователь (monuser) --password PASS пароль (secret) --non-interactive не задавать вопросы -h, --help показать справку Также поддерживаются NUT_SERVER, NUT_PORT, NUT_UPS_NAME, NUT_USERNAME, NUT_PASSWORD. Осторожно: пароль в аргументе может попасть в историю shell; предпочтительнее интерактивный ввод. EOF } while (($#)); do case "$1" in --server) SERVER="${2:?}"; shift 2 ;; --port) PORT="${2:?}"; shift 2 ;; --ups) UPS_NAME="${2:?}"; shift 2 ;; --username) USERNAME="${2:?}"; shift 2 ;; --password) PASSWORD="${2:?}"; shift 2 ;; --non-interactive) NON_INTERACTIVE=true; shift ;; -h|--help) usage; exit 0 ;; *) echo "Неизвестный параметр: $1" >&2; usage; exit 2 ;; esac done [[ $EUID -eq 0 ]] || { echo "Запустите скрипт от root." >&2; exit 1; } [[ -r /etc/os-release ]] || { echo "Не удалось определить ОС." >&2; exit 1; } . /etc/os-release [[ ${ID:-} == debian || ${ID_LIKE:-} == *debian* ]] || { echo "Требуется Debian/Proxmox." >&2; exit 1; } ask() { local label=$1 current=$2 answer read -r -p "$label [$current]: " answer printf '%s' "${answer:-$current}" } if ! $NON_INTERACTIVE && [[ -t 0 ]]; then echo "=== Параметры Synology NUT ===" SERVER=$(ask "Адрес сервера" "$SERVER") PORT=$(ask "Порт" "$PORT") UPS_NAME=$(ask "Имя UPS" "$UPS_NAME") USERNAME=$(ask "Пользователь" "$USERNAME") read -r -s -p "Пароль [оставьте пустым для текущего значения]: " entered_password; echo PASSWORD=${entered_password:-$PASSWORD} read -r -p "Продолжить настройку ${UPS_NAME}@${SERVER}:${PORT}? [y/N] " reply [[ $reply =~ ^[YyДд]$ ]] || { echo "Отменено."; exit 0; } fi [[ $SERVER =~ ^[A-Za-z0-9._:-]+$ ]] || { echo "Некорректный адрес сервера." >&2; exit 2; } [[ $PORT =~ ^[0-9]+$ ]] && ((PORT > 0 && PORT < 65536)) || { echo "Некорректный порт." >&2; exit 2; } [[ $UPS_NAME =~ ^[A-Za-z0-9._-]+$ ]] || { echo "Некорректное имя UPS." >&2; exit 2; } [[ $USERNAME != *[[:space:]]* && $PASSWORD != *[[:space:]]* ]] || { echo "Логин и пароль не должны содержать пробелы." >&2; exit 2; } echo "[1/6] Проверка сети..." if command -v timeout >/dev/null && ! timeout 3 bash -c "/dev/null; then echo "Предупреждение: TCP ${SERVER}:${PORT} пока недоступен. Проверьте firewall и список разрешённых IP Synology." >&2 fi echo "[2/6] Установка nut-client..." export DEBIAN_FRONTEND=noninteractive if ! apt-get update; then cat >&2 <<'EOF' ОШИБКА: apt update завершился неуспешно. NUT ещё не настраивался. Если узел Proxmox не имеет подписки, отключите pve-enterprise и ceph-enterprise в Node → Updates → Repositories, затем добавьте официальный pve-no-subscription репозиторий. После успешного `apt-get update` запустите этот скрипт повторно. EOF exit 1 fi apt-get install -y --no-install-recommends nut-client echo "[3/6] Проверка NUT-сервера..." if ! upsc -l "${SERVER}:${PORT}" 2>/dev/null | grep -Fxq "$UPS_NAME"; then echo "UPS '$UPS_NAME' не найден. Сервер сообщает:" >&2 upsc -l "${SERVER}:${PORT}" 2>&1 || true echo "Продолжаю: на Synology стандартное имя обычно 'ups'." >&2 fi timestamp=$(date +%Y%m%d-%H%M%S) cp -a /etc/nut/nut.conf "/etc/nut/nut.conf.bak-${timestamp}" cp -a /etc/nut/upsmon.conf "/etc/nut/upsmon.conf.bak-${timestamp}" echo "[4/6] Настройка конфигурации..." if grep -qE '^[[:space:]]*MODE=' /etc/nut/nut.conf; then sed -i -E 's/^[[:space:]]*MODE=.*/MODE=netclient/' /etc/nut/nut.conf else printf '\nMODE=netclient\n' >> /etc/nut/nut.conf fi # Удаляем только ранее созданную строку для этого UPS/сервера, затем добавляем актуальную. escaped_server=${SERVER//./\\.} sed -i -E "\\|^[[:space:]]*MONITOR[[:space:]]+${UPS_NAME}@${escaped_server}(:${PORT})?[[:space:]]|d" /etc/nut/upsmon.conf printf '\n# Managed by install-proxmox-nut-client.sh\nMONITOR %s@%s:%s 1 %s %s %s\n' \ "$UPS_NAME" "$SERVER" "$PORT" "$USERNAME" "$PASSWORD" "$ROLE" >> /etc/nut/upsmon.conf chmod 640 /etc/nut/upsmon.conf echo "[5/6] Запуск мониторинга..." systemctl enable nut-monitor.service systemctl restart nut-monitor.service echo "[6/6] Проверка результата..." upsc "${UPS_NAME}@${SERVER}:${PORT}" >/tmp/nut-upsc-check.txt status=$(sed -n 's/^ups.status: //p' /tmp/nut-upsc-check.txt) charge=$(sed -n 's/^battery.charge: //p' /tmp/nut-upsc-check.txt) rm -f /tmp/nut-upsc-check.txt systemctl is-active --quiet nut-monitor.service cat <