feat(ops): offsite-бэкапы и проверки профилей
- deploy/backup.sh: BACKUP_OFFSITE_TARGET (rsync или rclone:remote:path) выгружает готовый архив после локальной ротации; неудача выгрузки только предупреждает. Ротация на приёмнике — опционально (BACKUP_OFFSITE_KEEP_DAYS, rclone delete --min-age). Имя архива получает суффикс, если бэкап запущен дважды в одну секунду. - deploy/install.sh: offsite-настройки в .env (BACKUP_OFFSITE_TARGET, BACKUP_OFFSITE_KEEP_DAYS) отдельным разделом; детектор незаполненных плейсхолдеров учитывает цифры в именах (FAIL2BAN_ENABLED); dry-run больше не требует прав на /opt/glchat — явность GLCHAT_ETC_DIR фиксируется до подключения common.sh, иначе ветка временного каталога была недостижима. - scripts/test-profiles.sh: сверка таблицы профилей 10.10 и одинакового набора PROFILE_* (46 проверок), make profiles-test / ops-test. - scripts/test-backup.sh: бэкап и offsite на синтетическом инстансе — локальный rsync-приёмник, шим rclone, недоступный хост, нечисловой срок (12 проверок), make backup-test. - scripts/test-install.sh: проверка offsite-ключей в .env после установки.
This commit is contained in:
Executable
+116
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env bash
|
||||
# test-profiles.sh — проверка таблицы профилей производительности (AGENT.md 10.10).
|
||||
# Значения из профиля обязаны совпадать со спецификацией: профиль меняет только
|
||||
# лимиты и тюнинг, поэтому расхождение — дефект установщика.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# shellcheck source=../deploy/lib/common.sh
|
||||
source "${REPO_DIR}/deploy/lib/common.sh"
|
||||
|
||||
failures=0
|
||||
checks=0
|
||||
|
||||
# expect <профиль> <параметр> <ожидаемое>
|
||||
expect() {
|
||||
local tier="$1" name="$2" want="$3"
|
||||
local got="${!name:-}"
|
||||
checks=$((checks + 1))
|
||||
if [ "$got" != "$want" ]; then
|
||||
printf 'FAIL %s: %s = %s, ожидалось %s\n' "$tier" "$name" "$got" "$want" >&2
|
||||
failures=$((failures + 1))
|
||||
else
|
||||
printf 'ok %s: %s = %s\n' "$tier" "$name" "$got"
|
||||
fi
|
||||
}
|
||||
|
||||
check_lite() {
|
||||
profile_values lite
|
||||
expect lite PROFILE_SQLITE_CACHE_MB 8
|
||||
expect lite PROFILE_SQLITE_MMAP_MB 128
|
||||
expect lite PROFILE_SQLITE_READ_POOL 2
|
||||
expect lite PROFILE_GOMAXPROCS 1
|
||||
expect lite PROFILE_LRU_ENTRIES 2000
|
||||
expect lite PROFILE_LIVEKIT_MAX_PARTICIPANTS 10
|
||||
expect lite PROFILE_LIVEKIT_MAX_VIDEO 4
|
||||
expect lite PROFILE_LIVEKIT_SIMULCAST 0
|
||||
expect lite PROFILE_UPLOAD_MB 25
|
||||
expect lite PROFILE_APP_LIMIT 384m
|
||||
expect lite PROFILE_LIVEKIT_LIMIT 640m
|
||||
expect lite PROFILE_SWAP_GB 2
|
||||
expect lite PROFILE_BACKUP_KEEP 7
|
||||
expect lite PROFILE_SHARE_SOFT 1440p/30
|
||||
}
|
||||
|
||||
check_standard() {
|
||||
profile_values standard
|
||||
expect standard PROFILE_SQLITE_CACHE_MB 16
|
||||
expect standard PROFILE_SQLITE_MMAP_MB 256
|
||||
expect standard PROFILE_SQLITE_READ_POOL 4
|
||||
expect standard PROFILE_GOMAXPROCS 2
|
||||
expect standard PROFILE_LRU_ENTRIES 10000
|
||||
expect standard PROFILE_LIVEKIT_MAX_PARTICIPANTS 25
|
||||
expect standard PROFILE_LIVEKIT_MAX_VIDEO 8
|
||||
expect standard PROFILE_LIVEKIT_SIMULCAST 2
|
||||
expect standard PROFILE_UPLOAD_MB 50
|
||||
expect standard PROFILE_APP_LIMIT 768m
|
||||
expect standard PROFILE_LIVEKIT_LIMIT 1536m
|
||||
expect standard PROFILE_SWAP_GB 2
|
||||
expect standard PROFILE_BACKUP_KEEP 14
|
||||
expect standard PROFILE_SHARE_SOFT 1440p/30
|
||||
}
|
||||
|
||||
check_plus_and_pro() {
|
||||
profile_values plus
|
||||
expect plus PROFILE_SQLITE_CACHE_MB 32
|
||||
expect plus PROFILE_SQLITE_MMAP_MB 512
|
||||
expect plus PROFILE_UPLOAD_MB 100
|
||||
expect plus PROFILE_APP_LIMIT 1536m
|
||||
expect plus PROFILE_LIVEKIT_LIMIT 3g
|
||||
expect plus PROFILE_BACKUP_KEEP 30
|
||||
expect plus PROFILE_SHARE_SOFT 4K/30
|
||||
|
||||
profile_values pro
|
||||
expect pro PROFILE_SQLITE_CACHE_MB 64
|
||||
expect pro PROFILE_SQLITE_MMAP_MB 1024
|
||||
expect pro PROFILE_UPLOAD_MB 250
|
||||
expect pro PROFILE_APP_LIMIT 4g
|
||||
expect pro PROFILE_LIVEKIT_LIMIT 6g
|
||||
expect pro PROFILE_BACKUP_KEEP 60
|
||||
expect pro PROFILE_SHARE_SOFT 4K/60
|
||||
}
|
||||
|
||||
check_none() {
|
||||
profile_values none
|
||||
# none — только обязательный минимум: системные лимиты не трогаем.
|
||||
expect none PROFILE_SWAP_GB 0
|
||||
expect none PROFILE_GOMAXPROCS 0
|
||||
expect none PROFILE_SHARE_SOFT 1080p/30
|
||||
}
|
||||
|
||||
# Профиль меняет только лимиты: набор параметров у всех профилей одинаков, иначе
|
||||
# переключение профиля оставило бы часть значений от прежнего.
|
||||
check_same_keys() {
|
||||
profile_values lite
|
||||
local lite_keys
|
||||
lite_keys="$(compgen -v PROFILE_ | sort | tr '\n' ' ')"
|
||||
profile_values pro
|
||||
local pro_keys
|
||||
pro_keys="$(compgen -v PROFILE_ | sort | tr '\n' ' ')"
|
||||
checks=$((checks + 1))
|
||||
if [ "$lite_keys" != "$pro_keys" ]; then
|
||||
printf 'FAIL набор параметров профилей различается:\nlite: %s\npro: %s\n' "$lite_keys" "$pro_keys" >&2
|
||||
failures=$((failures + 1))
|
||||
else
|
||||
printf 'ok набор параметров одинаков: %s\n' "$lite_keys"
|
||||
fi
|
||||
}
|
||||
|
||||
check_lite
|
||||
check_standard
|
||||
check_plus_and_pro
|
||||
check_none
|
||||
check_same_keys
|
||||
|
||||
printf '\n=== профили: %d проверок, %d ошибок ===\n' "$checks" "$failures"
|
||||
[ "$failures" -eq 0 ] || exit 1
|
||||
Reference in New Issue
Block a user