diff --git a/ops/split-infra-postgres.sh b/ops/split-infra-postgres.sh index 7ca0f8c3..2b6e40e9 100755 --- a/ops/split-infra-postgres.sh +++ b/ops/split-infra-postgres.sh @@ -58,6 +58,24 @@ DST_CONTAINER="${DST_CONTAINER:-gendesign-infra-postgres}" DATABASES="${DATABASES:-forgejo glitchtip}" DUMP_DIR="${DUMP_DIR:-/opt/gendesign/backups/migration-3061}" FORGEJO_DIR="${FORGEJO_DIR:-/home/gendesign/forgejo}" + +# Где на самом деле лежит app.ini. Раньше здесь подразумевалось +# "${FORGEJO_DIR}/app.ini", и такого файла на хосте НЕТ: FORGEJO_DIR — каталог +# со стеком (docker-compose.yml, раннеры), а конфиг живёт внутри тома данных, +# который монтируется в контейнер как /data. Проверено на боевом хосте: +# /home/gendesign/forgejo/data/forgejo -> /data +# app.ini = /home/gendesign/forgejo/data/forgejo/gitea/conf/app.ini +# Тихо это ломало страж assert_not_cut_over: он проверяет файл через +# `[[ -r "$ini" ]]`, несуществующий путь читается как "признака нет", и +# половина защиты от повторного --force-restore после cutover просто не +# срабатывала — молча, без единого сообщения. +FORGEJO_APP_INI="${FORGEJO_APP_INI:-}" +if [[ -z "$FORGEJO_APP_INI" ]]; then + for candidate in "${FORGEJO_DIR}/data/forgejo/gitea/conf/app.ini" "${FORGEJO_DIR}/data/gitea/conf/app.ini" "${FORGEJO_DIR}/app.ini" + do + [[ -r "$candidate" ]] && { FORGEJO_APP_INI="$candidate"; break; } + done +fi # Писатели, которых надо погасить на время дампа. Порядок важен только тем, что # forgejo идёт первым: это git и CI, его простой заметнее всего. FORGEJO_CONTAINER="${FORGEJO_CONTAINER:-forgejo}" @@ -125,8 +143,15 @@ fi # сравнивает источник с приёмником, и записей, сделанных после cutover, в # источнике никогда не было. Поэтому единственная защита — не дать запуститься. assert_not_cut_over() { - local ini="${FORGEJO_DIR}/app.ini" hit="" - if [[ -r "$ini" ]] && grep -Eq '^[[:space:]]*HOST[[:space:]]*=[[:space:]]*infra-postgres' "$ini"; then + local ini="$FORGEJO_APP_INI" hit="" + # Не нашли app.ini — это НЕ "признака нет". Раньше здесь молча пропускалась + # половина стража, и --force-restore после cutover залил бы устаревший дамп + # поверх живых данных, а сверка фазы 5 подтвердила бы это как успех. + # Лучше остановиться и заставить указать путь явно. + if [[ -z "$ini" || ! -r "$ini" ]]; then + die "не найден app.ini Forgejo — проверить, сделан ли уже cutover, нечем. Искал: ${FORGEJO_DIR}/data/forgejo/gitea/conf/app.ini, ${FORGEJO_DIR}/data/gitea/conf/app.ini, ${FORGEJO_DIR}/app.ini. Укажи путь через FORGEJO_APP_INI=... Пропускать эту проверку нельзя: именно она не даёт --force-restore залить устаревший дамп поверх данных, записанных после cutover." + fi + if grep -Eq '^[[:space:]]*HOST[[:space:]]*=[[:space:]]*infra-postgres' "$ini"; then hit+="${ini} (HOST = infra-postgres); " fi if [[ -r "$GENDESIGN_ENV" ]] && grep -Eq '^[[:space:]]*GLITCHTIP_DB_HOST[[:space:]]*=[[:space:]]*infra-postgres' "$GENDESIGN_ENV"; then @@ -498,7 +523,7 @@ log "Сверка возражений не имеет." # ========================================================================== phase "ФАЗА 6: ручные шаги (скрипт их НЕ делает)" cat <