16 KiB
type, work_item_id, title, version, status, created_at, authors
| type | work_item_id | title | version | status | created_at | authors | |
|---|---|---|---|---|---|---|---|
| infra-requirements | ET-009 | Инфраструктурные требования — ET-009: Активация EnduroRussia + Wikiloc | 1 | approved | 2026-06-01 |
|
Инфраструктурные требования — ET-009
1. Резюме
ET-009 — конфиг-only активация двух дополнительных источников GPS-треков в pipeline ET-008. Инфраструктура не меняется:
- Никаких новых docker-сервисов;
- Никаких новых файлов БД;
- Никаких новых cron-записей (cron автоматизация — отдельный DevOps-task);
- Никаких новых env-переменных, секретов, ключей;
- Никаких новых портов и nginx-правил.
Все изменения — текстовые правки конфигов и тестовых артефактов плюс один ручной первый прогон pipeline на mva154.
Эскалация: minor change (см. ADR-013 §«Классификация»).
2. Контейнеры и сервисы
| Аспект | Требование |
|---|---|
Новый сервис gps-collector |
Уже существует (ET-008). Без изменений. |
Изменения Dockerfile |
Нет |
Изменения docker-compose.yml |
Нет |
| Перезапуск API после деплоя | Нужен — docker compose up -d --no-deps app (≈ 5 сек простоя). Перезапуск нужен только потому, что src/web/*.json подаётся API-контейнером; обновлённые style.json / style-dark.json подхватываются после рестарта |
Перезапуск gps-collector |
Не applicable (не daemon). Следующий запуск через docker compose --profile batch run --rm gps-collector ... уже использует новый конфиг через примонтированный config/ volume |
2.1 Зависимости между сервисами
Без изменений vs ET-008. gps-collector ↔ app коммуницируют через
docker-internal HTTP при cache-clear; этот контракт уже существует и
ET-009 его не трогает.
3. Сеть
| Аспект | Требование |
|---|---|
| Новые входящие порты | Нет |
| Изменения nginx | Нет |
| Новые исходящие HTTPS-соединения с mva154 | Да — две новых dest: endurorussia.ru (443) и www.wikiloc.com (443) |
| Firewall mva154 | Исходящие HTTPS уже разрешены (ET-008 §3, BRD §7). Дополнительных правил не нужно |
| DNS-резолвинг | Стандартный (системный resolver Docker). Никаких записей в /etc/hosts |
3.1 Изменение dest IP
Перед ET-009 контейнер gps-collector обращался только к:
api.openstreetmap.org(ADR-009);
После ET-009 добавляются:
endurorussia.ru(ADR-010 accepted);www.wikiloc.com(ADR-012 accepted).
Все три — стандартный HTTPS, без проксей и кастомных сертификатов.
3.2 Ограничение rate
| Источник | Rate-limit | Trafic за прогон | Пик |
|---|---|---|---|
| OSM | 1 req/sec | ≈ 100 МБ | без изменений |
| EnduroRussia | 5 sec / req | ≈ 30 МБ (≤ 305 треков × ~50 КБ + json list) | 1 req / 5 сек |
| Wikiloc | 10 sec / req | ≈ 5 МБ (≤ 50 треков × 3 req × ~30 КБ) | 1 req / 10 сек |
| Итого пиковый egress mva154 | ≈ 0.1 req/sec суммарно | ≤ 150 МБ / прогон | пренебрежимо |
Влияния на пропускную способность mva154 нет.
4. Хранилища данных
| Аспект | Требование |
|---|---|
| Новые БД | Нет |
| Изменения схемы | Нет |
| Миграции | Нет |
Изменения объёма data/gps_tracks.sqlite |
+20–50 МБ ожидаемо (≤ 200 треков EnduroRussia × ~50 КБ + ≤ 50 треков Wikiloc × ~50 КБ + метаданные) |
Лимит REQ-NF-03 (08-data-requirements.md ET-008) |
2 ГБ — далеко не достигнут |
Backup .sqlite |
Без изменений (тот же cron-скрипт, см. ET-008 §4.4) |
4.1 Опциональный one-shot fix старого URL
Если в БД test-сервера остались записи с старым external_url (с
дефисом enduro-russia.ru) — оператор может выполнить один раз
после первого прогона ET-009:
UPDATE tracks
SET external_urls_json = REPLACE(external_urls_json,
'enduro-russia.ru',
'endurorussia.ru')
WHERE external_urls_json LIKE '%enduro-russia.ru%';
На практике, поскольку до ET-009 enduro_russia был enabled: false,
таких записей нет. Скрипт — defensive, не обязательный (BRD R-9).
4.2 Backup retention
Без изменений. Ежедневный snapshot, 14 дней retention.
5. Конфигурация и секреты
| Аспект | Требование |
|---|---|
| Новые env-переменные | Нет |
| Новые секреты / API-ключи | Нет (EnduroRussia и Wikiloc — без авторизации) |
| Новые конфиг-файлы | Нет; меняется только содержимое существующих config/gps_sources.yaml и config/gps_regions.yaml |
5.1 Изменения config/gps_sources.yaml
См. ADR-013 §«Решение 2» — финальное содержимое. Изменения:
enduro_russia.base_url:https://enduro-russia.ru→https://endurorussia.ru(без дефиса);enduro_russia.enabled:false→true;enduro_russia.source_priority: добавлено80(раньше отсутствовало, default fall-back в коде);- новая запись
wikiloc(15 строк).
5.2 Изменения config/gps_regions.yaml
См. ADR-013 §«Решение 3». В tsfo_plus_chuvashia.sources добавляется
wikiloc.
6. Зависимости
| Аспект | Требование |
|---|---|
| Новые Python-пакеты | Нет (defusedxml, httpx, shapely, pyyaml — все есть из ET-008) |
| Системные библиотеки в Dockerfile | Нет |
| Версия Python | 3.12, без изменений |
| Внешние runtime-зависимости (источники) | endurorussia.ru + www.wikiloc.com (см. §3.1) |
| Pinned-версии библиотек | Без изменений |
7. Сборка и деплой
7.1 Pipeline CI
Существующий Gitea Actions:
make lint(ruff + eslint) — должен пройти без замечаний;make test— должен включать новые тесты UT-ER-, UT-WL-, IT-*;make build— пересобирает образ (никаких изменений в Dockerfile, но новые тестовые фикстуры и конфиги попадают в образ).
7.2 Деплой шаг-за-шагом
git pull origin mainна mva154.docker compose build(опционально; никаких изменений в Dockerfile/requirements не было, но сборка идемпотентна и быстрая).docker compose up -d --no-deps app— рестарт API (≈ 5 сек простоя) для подхвата обновлённыхstyle.json/style-dark.jsonи client-side JS (если изменилсяgps_tracks.js).- Первый ручной прогон EnduroRussia:
Ожидаемая длительность: 20–30 минут. Ожидаемый результат:
docker compose --profile batch run --rm gps-collector \ python -m scripts.gps_collect \ --region tsfo_plus_chuvashia --source enduro_russiatracks_new ≥ 200,status: ok. - Первый ручной прогон Wikiloc:
Ожидаемая длительность: 10–25 минут (cap
docker compose --profile batch run --rm gps-collector \ python -m scripts.gps_collect \ --region tsfo_plus_chuvashia --source wikilocmax_tracks_per_run=50). Ожидаемый результат:tracks_new ≥ 1,status: ok | partial. - Проверить
/api/gps-tracks/health—tracks_by_sourceсодержит ключиenduro_russiaиwikilocс ненулевыми значениями. - Smoke в UI: открыть
/enduro/, включить «Публичные треки», проверить три чекбокса источников и атрибуции. - Зафиксировать результат в
docs/work-items/ET-009/14-deploy-log.md.
7.3 Время простоя
API: ≤ 5 секунд на шаге 3 (стандартный рестарт контейнера). Pipeline: ≈ 50 минут (последовательные ручные прогоны двух источников). Pipeline-простой не влияет на API; оба независимы.
7.4 Cron включается отдельным task'ом
ET-009 не активирует автоматический cron. После двух успешных
ручных прогонов подряд DevOps вручную раскомментирует cron-записи
из ET-008 (/etc/cron.d/enduro-gps).
7.5 Rollback
| Сценарий | Действие | Время |
|---|---|---|
Откат конфигов (вернуть enabled: false) |
git revert <commit> + docker compose up -d --no-deps app |
≈ 2 мин |
| Откат БД (если новые источники запортили данные) | cp backups/gps_tracks-<date>.sqlite data/gps_tracks.sqlite + рестарт API |
≈ 1 мин |
| Точечное удаление источника без отката кода | Открыть config/gps_sources.yaml на mva154, выставить enabled: false, рестарт API (cache-clear) |
≈ 1 мин |
| Удаление треков конкретного источника | DELETE FROM tracks WHERE sources_json LIKE '%<id>%' (через ssh + sqlite3) |
≈ 1 мин |
8. Cron / scheduled jobs
Нет в ET-009. Cron активируется отдельным DevOps-task'ом после ETC-009 (см. §7.4).
9. Ресурсы (CPU / RAM / диск)
9.1 API-контейнер
Никаких изменений. Дополнительные source-ID не нагружают endpoint
(только новые значения в properties.sources).
9.2 gps-collector контейнер (во время прогона)
| Метрика | EnduroRussia | Wikiloc | OSM (для сравнения) |
|---|---|---|---|
| CPU (peak) | < 5% от 1 vCPU | < 5% от 1 vCPU | < 10% |
| RAM (peak) | ≤ 150 МБ | ≤ 150 МБ | ≤ 200 МБ |
| Network egress | ≈ 30 МБ | ≈ 5 МБ | ≈ 100 МБ |
| Длительность | 20–30 мин | 10–25 мин | 1–3 часа (ЦФО) |
| Disk write rate | низкий (≤ 1 МБ/мин) | низкий | средний |
Все три параллельно gps-collector cgroup-limit'ы (cpus: 1.0,
mem_limit: 512m) — никаких изменений по сравнению с ET-008.
9.3 Диск
Прирост data/gps_tracks.sqlite после первого прогона ET-009:
+20–50 МБ. Снимок backup того же объёма. Не влияет на disk budget.
10. Наблюдаемость
| Артефакт | Состояние после ET-009 |
|---|---|
GET /api/gps-tracks/health |
Возвращает tracks_by_source = {osm, enduro_russia, wikiloc} после первых прогонов |
/var/log/enduro-trails/gps-collect.log |
Логи ручных прогонов (через >> ... 2>&1 при ssh) |
pipeline_runs в БД |
Новые записи для source_id ∈ {enduro_russia, wikiloc} |
Docker docker compose logs app |
Без изменений |
10.1 Алерты
Нет новых алертов. Существующие правила ET-008 (cron MAILTO, db_size_mb > 2 ГБ) применяются как есть.
Опционально (out of scope ET-009): добавить ручную проверку
/api/gps-tracks/health в еженедельный operations-review для двух
новых источников.
10.2 Logrotate
Без изменений.
11. Безопасность
Никаких изменений по security-модели по сравнению с ET-008:
- XML-парсинг GPX через
defusedxml.ElementTree; - скрейпинг — только outgoing;
- cache-clear endpoint остаётся docker-internal через nginx allow/deny.
11.1 Новые atack-vectors
| Vector | Митигация |
|---|---|
| Wikiloc возвращает malformed HTML с XSS-payload | Парсер использует regex, не интерпретирует HTML как DOM. JS не исполняется на сервере. Любой malformed HTML — 0 треков без падения |
| EnduroRussia API возвращает malformed JSON | httpx.Response.json() бросает exception → graceful return из generator |
| Wikiloc / EnduroRussia возвращают XML-bomb в GPX | defusedxml блокирует billion-laughs (наследуется из ET-008) |
| Поддельный 403 от Wikiloc → DoS pipeline | Graceful-stop ≠ ошибка; следующий прогон попробует снова. Cron-окно (3 дня) > recovery-окна (часы) |
12. Влияние на C4 / архитектурную документацию
Изменения для отражения в docs/architecture/README.md:
- Таблица «Внешние источники pipeline» (lines 53-58 в текущем README):
EnduroRussia.ru:ADR-010 (proposed/blocked)→ADR-010 (accepted);- добавить строку
Wikiloc | HTML + GPX | proprietary (некоммерческое использование) | ADR-012 (accepted) | да; ttrails.ru: без изменений.
Изменения для отражения в docs/architecture/adr/README.md:
- ADR-010:
statusupdated toaccepted; - ADR-012: новая строка таблицы;
- ADR-013: новая строка таблицы (с ссылкой на ET-009).
C4 mmd-диаграмм в проекте нет (ET-008 §12 явно зафиксировано). ET-009 не создаёт диаграмм — изменение «активация existing source» выражается в текстовом README.
13. Вывод
ET-009 — minimal-change на инфра-уровне:
- 0 новых сервисов / 0 новых БД / 0 новых cron / 0 новых env / 0 новых портов;
- Все изменения локализованы в
config/*.yaml,src/web/style*.json, тестовых фикстурах иsrc/api/gps_tracks/sources/wikiloc.py(8 строк дляmax_tracks_per_run); - Деплой = git pull + рестарт API + один ручной прогон;
- Rollback =
git revertили ssh-правкаenabled: false.
Эскалация: не требуется (arch:major-change не выставлен, ADR-013 §«Классификация»).