From d2712c4c99195a13115e2259fb9be36730dd92e7 Mon Sep 17 00:00:00 2001 From: grendervill Date: Tue, 22 Sep 2026 18:46:49 +0300 Subject: [PATCH] =?UTF-8?q?feat(ops):=20=D1=81=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20.env=20=D0=B8=D0=BD=D1=81=D1=82=D0=B0=D0=BD=D1=81?= =?UTF-8?q?=D0=B0=20=D1=81=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 обновлён, выгрузка и недоступный приёмник проверены вживую. --- Makefile | 4 ++ scripts/test-profiles.sh | 81 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/Makefile b/Makefile index d56cc95..26d70d6 100644 --- a/Makefile +++ b/Makefile @@ -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 ## Проверки эксплуатационных скриптов diff --git a/scripts/test-profiles.sh b/scripts/test-profiles.sh index 48e00e7..220d9b1 100755 --- a/scripts/test-profiles.sh +++ b/scripts/test-profiles.sh @@ -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