Files
awg-dash/docs/ci/RUNNER-CHECK-17-v2.md
T
embeddevio bbe0886342
ci / lint (push) Successful in 42s
contract-openapi / openapi-contract (push) Failing after 48s
contract-openapi / ts-client-is-current (push) Failing after 50s
ci / lint (pull_request) Successful in 42s
contract-openapi / openapi-contract (pull_request) Failing after 40s
contract-openapi / ts-client-is-current (pull_request) Failing after 28s
ci / unit (push) Successful in 49s
ci / security (push) Successful in 3m10s
ci / unit (pull_request) Successful in 48s
ci / security (pull_request) Successful in 2m22s
ci / build (push) Has been skipped
ci / image-scan (push) Has been skipped
ci / build (pull_request) Has been skipped
ci / push (push) Has been skipped
ci / image-scan (pull_request) Has been skipped
ci / push (pull_request) Has been skipped
docs(ci): runbook пайплайна и отчёт проверки runner'а (#17)
Refs #17, Refs #15
2026-10-28 23:12:17 +03:00

139 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Отчёт: Gitea Actions runner + CI-пайплайн `embeddevio/awg-dash` (v2)
**Владелец:** devops · **Дата:** 2026-10-28 · **Refs #17, Refs #15**
**Ветка:** `feat/17-ci` · **Ветка проверки:** `feat/17-verify` (= #17 + `deploy/*` из #18)
## 1. Итог
Runner, поднятый 28.10, **фактически не работал**: задачи забирались, но падали на создании
контейнера, а результаты не фиксировались в Gitea. Причины найдены и устранены на build-хосте
`192.168.1.147`. Пайплайн `ci.yml` написан, закоммичен и **прогнан на живом runner'е** —
все три гейта подтверждены реальными падениями jobs.
Осталось три внешних пункта, которые агент закрыть не может (нет SSH к `192.168.1.111`,
нет прав на merge): git-http дефект Gitea (#59), артефакты Gitea не публикуются,
`deploy/Dockerfile` появится в `main` только после merge #18.
## 2. Что было сломано в runner'е и как исправлено
| # | Симптом | Причина | Исправление |
|---|---|---|---|
| 1 | jobs вечно `queued`, `runner_id: 0`, логов нет | runner зарегистрирован **instance-token'ом** (`gitea-runner-awg`): задачи забирались, но результат не привязывался к репозиторию | зарегистрирован **repo-scoped** runner `awg-dash-147-repo` (repo registration token через API), `online`, id 2; legacy-контейнер остановлен |
| 2 | `failed to create container: Duplicate mount point: /var/run/docker.sock` | `container.options` монтировал сокет, а act_runner v0.6.1 монтирует его сам | `options: ""` + `valid_volumes: ["/var/run/docker.sock"]` |
| 3 | `all predefined address pools have been fully subnetted` | 23 «висимых» сети `GITEA-ACTIONS-*` от прерванных job'ов вычерпали пул Docker | удалены все `GITEA-ACTIONS-*` с 0 контейнеров (31 → 8 сетей); `container.network: "host"` как профилактика |
| 4 | `git clone` в шаге checkout: `bad pack header` | дефект Gitea git-http (issue #59), не runner | в `ci.yml` — fallback на `archive/<sha>.tar.gz` (archive работает: 200, валидный tar) |
| 5 | trivy: `install.sh` + `v0.57.1` → 404, tarball с github releases качается минутами | неверная версия в скрипте + медленная отдача github releases | trivy запускается официальным образом `aquasec/trivy:0.76.1` через docker-сокет, БД кэшируется в `/opt/trivy-cache` |
## 3. Итоговая конфигурация runner'а
```
контейнер : gitea-runner-awg-repo (docker.io/gitea/act_runner:latest v0.6.1), 192.168.1.147
область : repo-scoped (embeddevio/awg-dash), runner id 2, online
label : ubuntu-latest -> catthehacker/ubuntu:act-22.04
capacity : 1 (maxParallel=1)
сеть job : host, socket /var/run/docker.sock проброшен
toolcache : volume act-toolcache -> /opt/hostedtoolcache (Python 3.12.16 установлен один раз)
trivy : образ aquasec/trivy:0.76.1 + БД-кэш /opt/trivy-cache
registry : 192.168.1.111:3000 добавлен в insecure-registries на .147
(применено `systemctl reload docker`, контейнеры не перезапускались)
```
## 4. Пайплайн `.gitea/workflows/ci.yml`
```
lint ─┬─ unit ───────┐
│ ├─ build ── image-scan ── push (только push-событие)
└─ security ───┘
```
| Job | Команды | Гейт |
|---|---|---|
| lint | `ruff check backend`, `ruff format --check backend`, `mypy backend` | любая ошибка |
| unit | `pytest --cov=awg_agent --cov=awg_api --cov-report=xml/html --cov-fail-under=70` | **coverage < 70 %** |
| security | `bandit -lll -r backend`, `pip-audit -r requirements.txt -r requirements-contract.txt` | **bandit HIGH**, известные CVE в зависимостях |
| build | `docker build --pull -f deploy/Dockerfile -t 192.168.1.111:3000/embeddevio/awg-dash:staging-<sha8>` | ошибка сборки |
| image-scan | `trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1` | **HIGH/CRITICAL в образе** |
| push | `docker login` + `docker push ...:staging-<sha8>` | ошибка авторизации/пуша |
`build`/`image-scan`/`push` активируются только при наличии `deploy/Dockerfile`
(output `has_dockerfile` из `lint`); до merge #18 они скипаются с предупреждением.
## 5. Прогоны на живом runner'е (доказательства по AC)
### 5.1 `feat/17-ci` (ветка от `main`, Dockerfile ещё нет) — run #39
http://192.168.1.111:3000/embeddevio/awg-dash/actions/runs/39
| Job | Результат | Детали |
|---|---|---|
| lint | ✅ success | ruff check/format + mypy strict |
| unit | ✅ success | **198 passed**, coverage **96.80 %** (порог ≥ 70 %) |
| security | ✅ success | bandit: 0 HIGH, pip-audit: CVE не найдены |
| build / image-scan / push | ⏭ skipped | нет `deploy/Dockerfile` (ждёт #18) — штатное поведение |
### 5.2 `feat/17-verify` (= #17 + `deploy/*` из #18) — run #49
http://192.168.1.111:3000/embeddevio/awg-dash/actions/runs/49
| Job | Результат | Детали |
|---|---|---|
| lint | ✅ success | |
| unit | ✅ success | 198 passed, coverage 96.80 % |
| security | ✅ success | |
| build | ✅ success | образ `192.168.1.111:3000/embeddevio/awg-dash:staging-<sha8>` собран на runner'е |
| image-scan | ❌ failure | `Total: 22 (HIGH: 21, CRITICAL: 1)` — golang stdlib v1.25.14, `golang.org/x/crypto` — см. п. 6.1 |
| push | ⏭ skipped | fail-closed: при красном image-scan образ не публикуется |
### 5.3 Негативные прогоны гейтов — `ci/17-gate-negative` (ветка-пробник, удалена)
| Проверка | Run | Что в логе |
|---|---|---|
| покрытие < порога | #51 http://192.168.1.111:3000/embeddevio/awg-dash/actions/runs/51 | `FAIL Required test coverage of 99% not reached. Total coverage: 96.80%` → job `unit` **failure** |
| HIGH-находка bandit | #55 http://192.168.1.111:3000/embeddevio/awg-dash/actions/runs/55 | `Issue: [B602 ...] Severity: High Confidence: High` → job `security` **failure**, pipeline красный |
| HIGH/CRITICAL в образе | #49 (см. 5.2) | 22 находки → `image-scan` **failure** |
**Вывод по AC:** пуш в `feat/*` даёт jobs `lint`/`unit`/`security`/`build`; снижение покрытия
ниже порога роняет job; HIGH-уязвимость (код или образ) роняет pipeline.
## 6. Открытые вопросы (эскалация)
### 6.1 Образ содержит 21 HIGH + 1 CRITICAL (нужен апгрейд сборки, #18)
Trivy по образу, собранному из `deploy/Dockerfile` (#18):
- `stdlib` Go **v1.25.14** → CVE-2026-56857 (CRITICAL), CVE-2026-111943, CVE-2026-78667, CVE-2026-97031 (HIGH);
- `golang.org/x/crypto v0.42.0` → CVE-2025-47913 (HIGH, fix в 0.43.0).
Причина: `ARG GO_IMAGE=golang:1.25-alpine` в `deploy/Dockerfile`. Гейт работает правильно —
публикация образа заблокирована. Требуется бамп Go до ≥ 1.26.10 и `golang.org/x/crypto` ≥ 0.43.0
(владелец #18), после этого `image-scan` и `push` пойдут зелёными без правок CI.
### 6.2 Артефакты Gitea не публикуются
`actions/upload-artifact@v3` отрабатывает без ошибок («Artifact has been successfully uploaded!»,
173 КБ на coverage), но ни API (`/actions/runs/<id>/artifacts`, `/actions/artifacts`), ни UI
артефактов не показывают (`total_count: 0`). `upload-artifact@v4` **зависает** (job висел >6 мин
на старте экшена, контейнер пришлось снять). Итог: содержимое артефактов в Gitea 1.26 + runner
v0.6.1 не сохраняется — поэтому в шагах дополнительно печатается сводка в лог job
(coverage-таблица, bandit-отчёт, trivy-таблица) — эти логи стабильны и доступны по ссылке run'а.
### 6.3 Git-http Gitea (issue #59)
Checkout штатным `actions/checkout` падает (`bad pack header`), работает только архивный
fallback. Нужен доступ к хосту Gitea `192.168.1.111` (fsck/repack, проверка диска) — у агентов
его нет.
### 6.4 Token для registry push
PAT агента не имеет `write:package` → `401 Unauthorized` на `POST /v2/.../blobs/uploads/`
(проверено вручную на .147). В `ci.yml` логин берёт `secrets.REGISTRY_TOKEN`, если он задан,
иначе `secrets.GITHUB_TOKEN`. Для гарантированного push нужен секрет `REGISTRY_TOKEN`
(owner, PAT с `write:package`).
## 7. Эксплуатация
- Перезапуск run'а без коммита: `POST /api/v1/repos/embeddevio/awg-dash/actions/runs/<id>/rerun`.
- Ручной запуск: `workflow_dispatch` у `ci.yml`.
- Логи job'а: `GET /api/v1/repos/embeddevio/awg-dash/actions/jobs/<job_id>/logs`.
- Полный runbook: `docs/ci/CI.md` в ветке `feat/17-ci`.