Add idempotent install.sh for one-command deployment #10

Merged
forgejo-admin merged 1 commit from feature/8_install_script into main 2026-09-26 09:59:02 +00:00
Collaborator

Что сделано

Идемпотентный установщик deploy/install.sh — одна команда на скачивание и установку (issue #8):

curl -fsSL http://10.10.1.7:3000/forgejo-admin/watcherenish/raw/branch/main/deploy/install.sh | sudo bash

Работает и как pipe, и как файл (curl -fsSL -o install.sh ... && sudo bash install.sh), чистый bash без внешних зависимостей. Решение — по согласованному в #8 плану, с учётом аппрува заказчика: AUTH_TOKEN генерируется автоматически при первой установке; дефолты — /opt/watcherenish, пользователь pi, SESSIONS_DIR=~pi/.pi/agent/sessions.

Шаги скрипта (с прогрессом и финальным статусом «успешно/не успешно»):

  1. Проверки окружения: Linux + systemd, root/sudo, git/curl, существование пользователя — иначе понятная ошибка и код возврата ≠ 0.
  2. Node.js ≥ 20: если нет — установка через NodeSource (apt/dnf/yum).
  3. Код: /opt/watcherenish есть → git fetch + reset --hard origin/main; нет → git clone. Всё переопределяется переменными окружения (INSTALL_DIR, INSTALL_USER, PORT, BIND, SESSIONS_DIR, GATE_LOG, BRANCH, ...).
  4. npm test перед запуском сервиса — при падении установка прерывается со статусом «не успешно», сервис не трогается.
  5. systemd-юнит: генерируется из deploy/pi-web-monitor.service (User=, WorkingDirectory=, путь к node автодетектятся), все переменные окружения вынесены в EnvironmentFile=-/etc/default/pi-web-monitor; daemon-reload, enable, restart.
  6. Конфиг /etc/default/pi-web-monitor: создаётся только при первой установке, при повторных не перетирается (ручные правки и токен сохраняются). При создании — AUTH_TOKEN (openssl rand -hex 32), права 600.
  7. Финальная проверка: ждём GET /api/health со статусом (fallback на systemctl is-active), неуспех печатает конкретный шаг и подсказку journalctl -u ....

Идемпотентность: повторный запуск безопасен — обновляет код, перегенерирует юнит, рестартует сервис; дубликатов юнитов нет; конфиг не теряется.

README: разделы «Установка» (одна команда + что делает скрипт) и «systemd» обновлены.

Как проверить

  1. bash -n deploy/install.sh — синтаксис.
  2. Полный прогон на чистой машине: установка «с нуля», повторный запуск, pipe-режим.
  3. systemctl status pi-web-monitor; curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8787/api/health → {"status":"ok",...}; без токена → 401.

Проверено (E2E на чистом стенде)

  • Установка с нуля: все 7 шагов, 33 теста зелёные, конфиг создан, AUTH_TOKEN напечатан в статусе, healthcheck OK.
  • Повторный запуск: «конфиг уже существует — не перетираю», код обновлён, сервис рестартует, конфиг побайтно не изменился (diff), exit 0.
  • Pipe-режим curl -fsSL ... | sudo bash — через локальный HTTP-сервер: OK.
  • Healthcheck с токеном → 200 status:ok, без токена → 401.
  • Ошибочные пути: не-root и INSTALL_DIR без .git → внятное сообщение, exit code 1.

Closes #8

## Что сделано Идемпотентный установщик `deploy/install.sh` — одна команда на скачивание и установку (issue #8): ```bash curl -fsSL http://10.10.1.7:3000/forgejo-admin/watcherenish/raw/branch/main/deploy/install.sh | sudo bash ``` Работает и как pipe, и как файл (`curl -fsSL -o install.sh ... && sudo bash install.sh`), чистый bash без внешних зависимостей. Решение — по согласованному в #8 плану, с учётом аппрува заказчика: `AUTH_TOKEN` генерируется автоматически при первой установке; дефолты — `/opt/watcherenish`, пользователь `pi`, `SESSIONS_DIR=~pi/.pi/agent/sessions`. **Шаги скрипта** (с прогрессом и финальным статусом «успешно/не успешно»): 1. Проверки окружения: Linux + systemd, root/sudo, git/curl, существование пользователя — иначе понятная ошибка и код возврата ≠ 0. 2. Node.js ≥ 20: если нет — установка через NodeSource (apt/dnf/yum). 3. Код: `/opt/watcherenish` есть → `git fetch` + `reset --hard origin/main`; нет → `git clone`. Всё переопределяется переменными окружения (`INSTALL_DIR`, `INSTALL_USER`, `PORT`, `BIND`, `SESSIONS_DIR`, `GATE_LOG`, `BRANCH`, ...). 4. `npm test` перед запуском сервиса — при падении установка прерывается со статусом «не успешно», сервис не трогается. 5. systemd-юнит: генерируется из `deploy/pi-web-monitor.service` (`User=`, `WorkingDirectory=`, путь к `node` автодетектятся), все переменные окружения вынесены в `EnvironmentFile=-/etc/default/pi-web-monitor`; `daemon-reload`, `enable`, `restart`. 6. Конфиг `/etc/default/pi-web-monitor`: создаётся только при первой установке, при повторных **не перетирается** (ручные правки и токен сохраняются). При создании — `AUTH_TOKEN` (`openssl rand -hex 32`), права 600. 7. Финальная проверка: ждём `GET /api/health` со статусом (fallback на `systemctl is-active`), неуспех печатает конкретный шаг и подсказку `journalctl -u ...`. **Идемпотентность**: повторный запуск безопасен — обновляет код, перегенерирует юнит, рестартует сервис; дубликатов юнитов нет; конфиг не теряется. README: разделы «Установка» (одна команда + что делает скрипт) и «systemd» обновлены. ## Как проверить 1. `bash -n deploy/install.sh` — синтаксис. 2. Полный прогон на чистой машине: установка «с нуля», повторный запуск, pipe-режим. 3. `systemctl status pi-web-monitor`; `curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8787/api/health` → `{"status":"ok",...}`; без токена → 401. ## Проверено (E2E на чистом стенде) - [x] Установка с нуля: все 7 шагов, 33 теста зелёные, конфиг создан, `AUTH_TOKEN` напечатан в статусе, healthcheck OK. - [x] Повторный запуск: «конфиг уже существует — не перетираю», код обновлён, сервис рестартует, конфиг побайтно не изменился (`diff`), exit 0. - [x] Pipe-режим `curl -fsSL ... | sudo bash` — через локальный HTTP-сервер: OK. - [x] Healthcheck с токеном → 200 `status:ok`, без токена → 401. - [x] Ошибочные пути: не-root и `INSTALL_DIR` без `.git` → внятное сообщение, exit code 1. Closes #8
- deploy/install.sh: env checks, Node.js 20 bootstrap (NodeSource),
  clone-or-update into INSTALL_DIR, npm test gate, generated systemd
  unit with EnvironmentFile=/etc/default/pi-web-monitor, auto-generated
  AUTH_TOKEN on first install, health-check polling GET /api/health,
  final success/failure status with journalctl hints
- Idempotent: re-runs update code and restart service; env file is
  created only once and never overwritten
- Supports pipe-to-bash (curl ... | sudo bash) and file execution
- README: document one-command install and what the script does
forgejo-admin deleted branch feature/8_install_script 2026-09-26 10:00:59 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
forgejo-admin/watcherenish!10
No description provided.