docs(#21): README netns и runbook dev-stand — ci.sh, приоритет AWG_NS_EXEC_MODE, DEV_SKIP_BUILD

Приведение документации к фактическому поведению после ревью PR #53 (раунд 2):
точка входа для CI без make (контракт 0/1/3/4), приоритет AWG_NS_EXEC_MODE над
make-алиасом, сборка без сети (DEV_SKIP_BUILD=1).

Refs #21
Refs #56
This commit is contained in:
2026-10-28 21:58:15 +03:00
parent b612a3450c
commit 94d3a28adf
2 changed files with 38 additions and 4 deletions
+20 -1
View File
@@ -21,6 +21,15 @@ make dev-logs # логи контейнера
make dev-down # остановить (каталоги состояния сохраняются)
```
`dev-up` добавляет `--build`, когда в дереве есть `deploy/Dockerfile` (после мержа #18).
Если у хоста нет сети/DNS для `docker build` (офлайн-стенд, CI без прокси), сборку
нужно пропустить — образ `awg-dash:dev` уже должен существовать:
```bash
make dev-up DEV_SKIP_BUILD=1 # up -d --no-build — использовать готовый образ
make dev-up DEV_UP_BUILD= # вообще не передавать флаги сборки
```
До реализации FastAPI-каркаса (**#31**) `/api/v1/health` не отвечает — контейнер
работает как агент и помечается `unhealthy`. Чтобы проверить плумбинг стенда
(порт, healthcheck, тома, restart) **до** #31, используйте health-заглушку:
@@ -71,6 +80,10 @@ make dev-verify-stub # AC-1 проходит на заглушке, в отч
| `AWG_DASH_DOCKERFILE` | `deploy/Dockerfile` | путь к Dockerfile для build |
| `COMPOSE_PROJECT_NAME` | `awg-dash-dev` | изоляция от других стендов |
| `AWG_LOG_LEVEL` | `info` | уровень логирования приложения |
| `DEV_SKIP_BUILD` | — | `1` → `make dev-up` выполняет `up -d --no-build` (образ уже собран) |
| `DEV_UP_BUILD` | авто | переопределение флагов сборки (`--build`, пусто, `--no-build`) |
| `AWG_NS_EXEC_MODE` | `auto` | режим входа в netns: `auto|ip|nsenter` (issue #56) |
| `NETNS_EXEC_MODE` | `auto` | make-алиас `AWG_NS_EXEC_MODE` (приоритет у `AWG_NS_EXEC_MODE`) |
## Зависимости
@@ -79,7 +92,7 @@ make dev-verify-stub # AC-1 проходит на заглушке, в отч
| #16 (каркас репо, Makefile) | PR #47 | нужен `Makefile`, `requirements.txt`, `deploy/` |
| #18 (образ, entrypoint) | PR #49 | нужен `deploy/Dockerfile` для `--build` |
| #31 (каркас FastAPI, `/api/v1/health`) | Sprint 2 | без него AC-1 выполняется только с заглушкой |
| #17 (CI-пайплайн) | Sprint 0 | `make test-netns-ci`, `make test-manifests` — готовые гейты для пайплайна |
| #17 (CI-пайплайн) | Sprint 0 | гейты для пайплайна: `bash tests/netns/ci.sh` (коды 0/1/3/4), `make test-manifests`, `make test-deploy`, `make lint-shell` |
## Откат и уборка
@@ -106,3 +119,9 @@ du -sh /opt/awg-dash-dev # состояние стенда
маскирует отсутствие API. Не включайте `docker-compose.stub.yml` в staging.
* **netns-стенд вне Docker** требует root: `make test-netns` вернёт код 3, если нет
CAP_NET_ADMIN/CAP_SYS_ADMIN (например, в непривилегированном CI-раннере).
* **netns в контейнере (`make test-netns-ci`, `bash tests/netns/ci.sh`)**: `ip netns exec`
падает (`mount of /sys failed`), харнесс сам переходит на `nsenter`; контракт кодов
`0/1/3/4` действует на уровне контейнера. **make возвращает 2 на любом провале** —
в CI вызывайте `bash tests/netns/ci.sh`, иначе ветки 3 и 4 неразличимы (#56).
* **`--build` без сети**: после мержа #18 `dev-up` собирает образ; если на хосте нет
DNS/доступа к registry, используйте `DEV_SKIP_BUILD=1` (готовый `awg-dash:dev`).
+18 -3
View File
@@ -35,7 +35,9 @@ make test-netns # поднять стенд, прогнать т
make test-netns-keep # оставить топологию и логи для отладки
make test-netns NETNS_ARGS="--no-tests" # только поднять стенд
make test-netns-ci # то же в привилегированном контейнере (путь для CI)
# в контейнере вход в netns идёт через nsenter (issue #56)
bash tests/netns/ci.sh # точка входа для CI #17: контейнер без make
# (make отдаёт 2 на любом провале — см. ниже)
bash tests/netns/topology.sh status # состояние топологии
bash tests/netns/topology.sh down # снести топологию вручную
@@ -49,15 +51,26 @@ backend netfilter — `nft` или `iptables` (в alpine-образе прило
Коды возврата: `0` — тесты прошли, `1` — тесты упали, `3` — «заблокировано окружением»
(нет прав на создание netns), `4` — ошибка самого стенда (сюда же нормализуются
неожиданные коды утилит, например `255` от `ip netns exec` в контейнере).
**В CI (#17) используйте `bash tests/netns/ci.sh`, а не `make test-netns-ci`:**
GNU make возвращает `2` на любой упавший рецепт, поэтому через make контракт
`0/1/3/4` не виден и пайплайн не отличит «раннеру не дали прав» (`3`) от
«регрессия стенда» (`4`). `ci.sh` запускает тот же контейнер напрямую и отдаёт
его код как есть (`2` у него означает «сломан вызов/нет docker/нет образа»).
Вход в namespace выполняется через `ns_exec()`: `ip netns exec` в контейнере падает
(`mount of /sys failed`, issue #56), поэтому харнесс сам переключается на
`nsenter --net=/var/run/netns/<ns>`; режим форсируется `AWG_NS_EXEC_MODE`.
`nsenter --net=/var/run/netns/<ns>`; режим форсируется `AWG_NS_EXEC_MODE`
(`auto|ip|nsenter`). Тот же режим через make — `NETNS_EXEC_MODE` (алиас;
`AWG_NS_EXEC_MODE` имеет приоритет), например:
`AWG_NS_EXEC_MODE=ip make test-netns-ci`.
## Состав
| Файл | Назначение |
|---|---|
| `run.sh` | точка входа: preflight → топология → мок → тесты → снос |
| `ci.sh` | точка входа для CI #17: тот же прогон в контейнере без make, коды `0/1/3/4` доходят до пайплайна |
| `lib.sh` | конфигурация стенда + правила netfilter (nft/iptables) |
| `topology.sh` | `up`/`down`/`status`/`killswitch on|off` |
| `mock_wg_endpoint.py` | мок WireGuard-endpoint: отвечает на handshake initiation |
@@ -92,7 +105,9 @@ backend netfilter — `nft` или `iptables` (в alpine-образе прило
| `AWG_FWMARK` / `AWG_ROUTE_TABLE` | `51820` / `51820` | метка и таблица policy routing |
| `AWG_FW_BACKEND` | `auto` | `nft`, `iptables` или автоопределение |
| `AWG_NETNS_WORKDIR` | `mktemp -d` | каталог логов и отчёта стенда |
| `AWG_NS_EXEC_MODE` | `auto` | вход в netns: `ip`, `nsenter` или `auto` (проба) — issue #56 |
| `AWG_NS_EXEC_MODE` | `auto` | вход в netns: `ip`, `nsenter` или `auto` (проба) — issue #56; make-алиас — `NETNS_EXEC_MODE` |
| `AWG_NS_PRIVILEGED` | `1` | только для `ci.sh`: `0` — прогон без `privileged` (проверка ветки «код 3») |
| `AWG_DASH_TEST_ARTIFACTS` | `<repo>/artifacts` | каталог для `netns-report.json` (`ci.sh`) |
## Pitfalls