# B5 SingBox Template Migration And Rollback Runbook ## Цель Операционный runbook для миграции `legacy singbox-.service` к template-модели `singbox@.service` и для аварийного отката при инциденте деплоя. ## Контекст текущей модели - Целевой runtime: `singbox@.service` + per-instance drop-in `singbox@.service.d/10-selective-vpn.conf`. - One-shot миграция legacy unit выполняется автоматически в pre-action (`start/restart`) для `kind=singbox`. - Safety guard: legacy unit обрабатывается только при ownership marker `Environment=SVPN_TRANSPORT_ID=`. ## Preflight перед деплоем 1. Проверить runtime-зависимости: - `scripts/check_runtime_dependencies.sh` 2. Проверить strict-режим (опционально для CI/релиза): - `scripts/check_runtime_dependencies.sh --strict` 3. Проверить наличие template unit: - `systemctl list-unit-files 'singbox@.service' --no-legend` ## Управление миграцией - Отключить авто-миграцию для профиля: - `config.singbox_legacy_unit_migrate=false` - Включить dry-run без изменений unit-файлов: - `config.singbox_legacy_unit_migrate_dry_run=true` - Поведение dry-run: - backend пишет trace/stdout о планируемом `legacy -> template` переходе, - `stop/disable/remove` не выполняются. ## Нормальный migrate-путь 1. Обновить API-бинарь и перезапустить `selective-vpn-api.service`. 2. На `start/restart` конкретного SingBox-клиента backend: - валидирует ownership legacy unit, - выполняет `stop + disable + remove` legacy unit, - выполняет `daemon-reload + reset-failed` для legacy unit, - запускает template instance `singbox@.service`. 3. Проверить: - `systemctl status 'singbox@.service'` - `systemctl list-unit-files 'singbox-*' --no-legend` (legacy не должен появляться как managed unit) ## Аварийный rollback (template -> legacy) Важно: текущий прод-код нормализует SingBox clients к `config.unit=singbox@.service`, поэтому rollback делается на уровне release rollback (предыдущий API build + восстановление unit/state). 1. Зафиксировать инцидент и остановить изменения policy: - временно не выполнять `start/restart/switch` через GUI/API. 2. Откатить API до предыдущего релиза (где legacy path поддерживался штатно). 3. Восстановить `transport-clients` state из backup/снапшота релиза (если в инциденте state был изменён). 4. Восстановить legacy unit-файлы `singbox-*.service` из backup среды (если удалены). 5. Выполнить: - `systemctl daemon-reload` - `systemctl reset-failed` 6. Поднять нужные legacy unit и проверить egress/health. ## Проверка после rollback - `systemctl is-active selective-vpn-api.service` - `systemctl is-active 'singbox-.service'` (для rollback-релиза) - API smoke: - `curl -fsS http://127.0.0.1:8080/healthz` - `curl -fsS http://127.0.0.1:8080/api/v1/transport/clients` ## Примечание - Legacy `sing-box.service` остаётся только как compat-артефакт окружения. - Production path для новых профилей: только `singbox@.service`.