Сторож деплойных блокировок (Deploy Locks)
Если видишь
Refusing S3 deploy:при попытке деплоя — ты здесь.
Какие сторожа входят
| Сторож | Что охраняет |
|---|---|
| Host Deploy Lock (FD8) | Только один деплой на хосте одновременно |
| Codebase Deploy Lock (FD9) | Деплой запущен через официальную обёртку |
| Hidden Git Index Check | На checkout нет skip-worktree / assume-unchanged |
| Busy-Process Scan | Ни один процесс не запущен из заменяемого checkout |
| ProductSpec Registry Count | Количество ProductSpec-файлов совпадает с реестром |
Host Deploy Lock (FD8)
Где
scripts/deploy/verify_inherited_host_deploy_lock.py
Что охраняет
Файл /run/lock/gwptd-next-deploy.lock (EXCLUSIVE). Гарантирует что только
ОДИН деплой на всём хосте. Защита от случайного параллельного запуска двух
деплой-обёрток.
Как работает
- Обёртка
gwptd-next-deployоткрывает/run/lock/gwptd-next-deploy.lockна FD8 с EXCLUSIVE lock - Экспортирует
GWPTD_NEXT_DEPLOY_HOST_LOCK_PROTOCOL,GWPTD_NEXT_DEPLOY_HOST_LOCK_FD=8,GWPTD_NEXT_DEPLOY_HOST_LOCK_PATH - Внутренний deploy запускает
verify_inherited_host_deploy_lock.py - Python проверяет:
- Протокол верный
- FD = 8
- Путь фиксированный
- Inode совпадает
- Блокировка удерживается (независимый probe + перезахват)
Как отказывает
Refusing S3 deploy: host deploy lock protocol is absent or incompatible
Refusing S3 deploy: host deploy lock descriptor must be FD8
Refusing S3 deploy: host deploy lock path is not the fixed /run inode
Refusing S3 deploy: host deploy descriptor does not reference the fixed lock inode
Refusing S3 deploy: host deploy lock parent must be a real directory
Codebase Deploy Lock (FD9)
Где
scripts/deploy/verify_inherited_deploy_lock.py
Что охраняет
Файл /opt/mcp-gwptd/logs/codebase-reindex.lock на FD9 (EXCLUSIVE). Доказывает
что деплой запущен через gwptd-next-deploy, а не через ручной bash deploy-s3-next.sh.
Как работает
gwptd-next-deployоткрываетcodebase-reindex.lockна FD9 с EX- Экспортирует
GWPTD_NEXT_DEPLOY_LOCK_PROTOCOL,GWPTD_NEXT_DEPLOY_LOCK_FD=9 - Python проверяет:
- Иерархию путей (MCP root root:root 0755, logs root:gwptd 1770, lock root:gwptd 0660)
- Inode совпадает
- Блокировка УЖЕ удерживается (probe сначала)
- После перезахвата — всё ещё удерживается (probe после)
Обрати внимание: проверка делает TRIPLE probe. Это защита от гонки:
- Probe 1: блокировка уже есть (никто не передал разблокированный FD)
- Re-lock FD9: доказывает что именно FD9 владеет блокировкой
- Probe 3: блокировка всё ещё есть (re-lock не сломал)
Как отказывает
Refusing S3 deploy: inherited an unsupported lock protocol
Refusing S3 deploy: inherited an invalid lock descriptor
Refusing S3 deploy: inherited an unexpected lock descriptor
Refusing S3 deploy: inherited the wrong codebase lock inode
Refusing S3 deploy: lock was not held exclusive before inner execution
Refusing S3 deploy: inherited descriptor does not own the exclusive lock
Hidden Git Index Check
Где
ops/bin/gwptd-next-deploy
Что охраняет
На S3 checkout нет файлов, помеченных git update-index --skip-worktree или
--assume-unchanged. Эти флаги скрывают изменения от git status и могут
привести к деплою с непреднамеренными локальными правками.
Как отказывает
Refusing deploy: hidden Git index flags on S3 checkout:
<список файлов>
Exit code 9.
Что делать
- Посмотреть список файлов в сообщении
- Снять флаги:
git update-index --no-skip-worktree <file>
git update-index --no-assume-unchanged <file> - Проверить что
git status --porcelainчист
Busy-Process Scan
Где
deploy/s3/gwptd-deploy-app
Что охраняет
При деплое только app/API (без cron quarantine) проверяется что ни один
процесс не запущен из checkout, который заменяется. Ищет по /proc/*/cwd
и /proc/*/exe.
Как отказывает
Отказ: из этого checkout работает процесс $pid ($cwd) — подмена кода его сломает
Exit code 10.
ProductSpec Registry Count
Где
scripts/deploy/deploy-s3-next.sh (внутренний deploy)
Что охраняет
Количество YAML-файлов ProductSpec совпадает с количеством записей в реестре. Защита от: добавили spec, забыли реестр → endpoint молча не собирается.
Как отказывает
Refusing deploy: ProductSpec file/registry counts differ
Exit code 8.