feat(ops): сверка .env инстанса с таблицей профилей

- scripts/test-profiles.sh --env <файл>: профиль берётся из .env, значения
  таблицы 10.10 пересчитываются и сверяются с производными ключами
  (SQLITE_MMAP_SIZE, MAX_UPLOAD_SIZE, APP_MEMORY_LIMIT, SHARE_SOFT_LIMIT,
  BACKUP_KEEP_DAYS и т. д.), offsite-ключи проверяются на наличие.
- make profiles-env — тот же прогон для /opt/glchat/.env.
- На стенде: профиль standard совпал (67 проверок, 0 ошибок); .env дополнен
  ключами offsite, установленный backup.sh обновлён, выгрузка и недоступный
  приёмник проверены вживую.
This commit is contained in:
2026-09-22 18:46:49 +03:00
parent 3151327f6e
commit d2712c4c99
2 changed files with 85 additions and 0 deletions
+4
View File
@@ -201,6 +201,10 @@ profiles-test: ## Проверить таблицу профилей произ
backup-test: ## Проверить бэкап и offsite-выгрузку на синтетическом инстансе
bash scripts/test-backup.sh
.PHONY: profiles-env
profiles-env: ## Сверить .env установленного инстанса с таблицей профилей
sudo bash scripts/test-profiles.sh --env "$${GLCHAT_ETC_DIR:-/opt/glchat}/.env"
.PHONY: ops-test
ops-test: profiles-test backup-test ## Проверки эксплуатационных скриптов
+81
View File
@@ -2,12 +2,25 @@
# test-profiles.sh — проверка таблицы профилей производительности (AGENT.md 10.10).
# Значения из профиля обязаны совпадать со спецификацией: профиль меняет только
# лимиты и тюнинг, поэтому расхождение — дефект установщика.
#
# bash scripts/test-profiles.sh # таблица профилей
# bash scripts/test-profiles.sh --env /opt/glchat/.env # установленный инстанс
set -euo pipefail
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck source=../deploy/lib/common.sh
source "${REPO_DIR}/deploy/lib/common.sh"
ENV_FILE=""
case "${1:-}" in
"") ;;
--env)
ENV_FILE="${2:?укажите путь к .env}"
[ -f "$ENV_FILE" ] || die "не найден ${ENV_FILE}"
;;
*) die "неизвестный аргумент: $1 (поддерживается --env <файл>)" ;;
esac
failures=0
checks=0
@@ -112,5 +125,73 @@ check_plus_and_pro
check_none
check_same_keys
# --- режим установленного инстанса ----------------------------------------
# env_get уже есть в common.sh: читает значение из файла .env.
expect_env() { # expect_env <ключ .env> <ожидаемое>
local key="$1" want="$2" got
got="$(env_get "$key" "$ENV_FILE" || true)"
checks=$((checks + 1))
if [ "$got" != "$want" ]; then
printf 'FAIL %s = %s, ожидалось %s\n' "$key" "$got" "$want" >&2
failures=$((failures + 1))
else
printf 'ok %s = %s\n' "$key" "$got"
fi
}
# expect_present <ключ> — ключ есть в .env; пустое значение допустимо.
expect_present() {
checks=$((checks + 1))
if grep -qE "^$1=" "$ENV_FILE"; then
printf 'ok ключ %s в .env есть\n' "$1"
else
printf 'FAIL в .env нет ключа %s\n' "$1" >&2
failures=$((failures + 1))
fi
}
# check_env сверяет .env инстанса с таблицей профиля: профиль — единственный
# источник этих значений, поэтому расхождение означает правку .env руками.
check_env() {
local tier
tier="$(env_get PROFILE "$ENV_FILE" || true)"
[ -n "$tier" ] || die "в ${ENV_FILE} нет PROFILE"
profile_values "$tier"
# Значения, которые установщик вычисляет сам, а не берёт из профиля.
PROFILE_APP_CPUS="$(detect_cpus)"
PROFILE_LIVEKIT_CPUS="1.0"
local simulcast="true"
if [ "${PROFILE_LIVEKIT_SIMULCAST:-0}" -gt 0 ] 2>/dev/null; then simulcast="false"; fi
printf '\n=== профиль %s в %s ===\n' "$tier" "$ENV_FILE"
expect_env PROFILE "$tier"
expect_env SQLITE_READ_POOL "$PROFILE_SQLITE_READ_POOL"
expect_env SQLITE_CACHE_SIZE "-${PROFILE_SQLITE_CACHE_MB}000"
expect_env SQLITE_MMAP_SIZE "$((PROFILE_SQLITE_MMAP_MB * 1024 * 1024))"
expect_env GOMAXPROCS "$PROFILE_GOMAXPROCS"
expect_env LRU_CACHE_ENTRIES "$PROFILE_LRU_ENTRIES"
expect_env PROFILE_UPLOAD_MB "$PROFILE_UPLOAD_MB"
expect_env MAX_UPLOAD_SIZE "$((PROFILE_UPLOAD_MB * 1024 * 1024))"
expect_env APP_CPUS "$PROFILE_APP_CPUS"
expect_env APP_MEMORY_LIMIT "$PROFILE_APP_LIMIT"
expect_env LIVEKIT_CPUS "$PROFILE_LIVEKIT_CPUS"
expect_env LIVEKIT_MEMORY_LIMIT "$PROFILE_LIVEKIT_LIMIT"
expect_env LIVEKIT_MAX_PARTICIPANTS "$PROFILE_LIVEKIT_MAX_PARTICIPANTS"
expect_env LIVEKIT_MAX_VIDEO "$PROFILE_LIVEKIT_MAX_VIDEO"
expect_env LIVEKIT_DISABLE_SIMULCAST "$simulcast"
expect_env SHARE_SOFT_LIMIT "$PROFILE_SHARE_SOFT"
expect_env SHARE_MAX_LIMIT "$PROFILE_SHARE_MAX"
expect_env BACKUP_KEEP_DAYS "$PROFILE_BACKUP_KEEP"
expect_env SWAP_SIZE_GB "$PROFILE_SWAP_GB"
# Ключи offsite должны существовать даже пустыми, иначе бэкап их не увидит.
expect_present BACKUP_OFFSITE_TARGET
expect_present BACKUP_OFFSITE_KEEP_DAYS
}
if [ -n "$ENV_FILE" ]; then
check_env
fi
printf '\n=== профили: %d проверок, %d ошибок ===\n' "$checks" "$failures"
[ "$failures" -eq 0 ] || exit 1