Go to file
Ilgiz Kalmetyev d140d7db94 feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
.tmp/pytest feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
app feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
deployment feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
docs feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
migrations коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
proto коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
scripts коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
tests feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
.env.example feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
.env.test.example feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
.gitignore chore: initialize repository skeleton and engineering baseline 2026-04-06 21:13:57 +05:00
AGENTS.md скорректирован AGENTS.md 2026-04-07 21:49:35 +05:00
README.md feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
alembic.ini Сделал связку Alembic с общим источником конфигурации. 2026-04-11 22:50:00 +05:00
clear_messages_test_cli_0b60a97339f7446a9017938bfc3b8bbd-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
clear_messages_test_cli_2b79537f927948619217693e8cc9bfab-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
clear_messages_test_cli_51c6f188dc1f4a719983c20b5a20671c-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
clear_messages_test_cli_80dbf30071c249c6be5e50145d95bdf4-outbox.sqlite3 feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
clear_messages_test_cli_779da29743524fd88e22b34892b30bf0-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
clear_messages_test_cli_d0da372086e749d6bc5709591a3d33cc-outbox.sqlite3 Убрал journal event dropped by acl из journal adapter, чтобы ACL-drop больше не писался обратно в тот же journald-поток и не создавал петлю. 2026-04-13 21:48:11 +05:00
clear_messages_test_cli_d54a3bb779ca4ed790790ae134cabdc9-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
pyproject.toml daemon теперь автоматически поднимает только journal и dbus источники, если для них в ACL есть хотя бы одно правило с cache. navigation без такого правила не стартует. На старте и остановке health синхронизируется в БД 2026-04-11 23:57:30 +05:00
release.manifest.yml Добавлена инициализация источников в БД 2026-04-11 23:11:26 +05:00
show_messages_test_cli_08a49bc3f2584c9da6f5a76922162507-outbox.sqlite3 feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
show_messages_test_cli_19abfda6ceb34304a93a0c3b3b9a70fb-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
show_messages_test_cli_24f163762a2d4655b9da3555fc0c0ff1-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
show_messages_test_cli_92d346652f7540348f520e88d79168d6-outbox.sqlite3 Убрал journal event dropped by acl из journal adapter, чтобы ACL-drop больше не писался обратно в тот же journald-поток и не создавал петлю. 2026-04-13 21:48:11 +05:00
show_messages_test_cli_ac03cdc38a914baebb10348120b2040c-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
show_messages_test_cli_b9062f5ccd4d4f0499e7a4ca11599b13-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
show_messages_test_cli_d13a1e0564d04574bba6cff0b50ec71e-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_do_scan_cli_21f119f7b7b2488aaf4d683edd35d1c2-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_do_scan_cli_492d7004348d47b59dd4d378ce05fa58-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_do_scan_cli_872cc203d0084ad1a9bc45dbbaabb6a0-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_do_scan_cli_3306aba0015e4c4f829f87a50b4d89db-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_do_scan_cli_049869106bde426eb264076df0a62b53-outbox.sqlite3 feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
test_do_scan_cli_ad8d617284d14dc0885d55d17f0bee87-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_do_scan_cli_bd4e9b3bd08148ccbffd1866b39fcd39-outbox.sqlite3 Убрал journal event dropped by acl из journal adapter, чтобы ACL-drop больше не писался обратно в тот же journald-поток и не создавал петлю. 2026-04-13 21:48:11 +05:00
test_set_wpa_country_cli_80b8013ba3dc4b5b98e240047f932093-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_set_wpa_country_cli_59193d7f13fe4d26a87e4eb01910220b-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_set_wpa_country_cli_b26f986b1cb14ad1a9487143c29c12a8-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_set_wpa_country_cli_c64a41b0fed9410da11d359f77eafde4-outbox.sqlite3 Убрал journal event dropped by acl из journal adapter, чтобы ACL-drop больше не писался обратно в тот же journald-поток и не создавал петлю. 2026-04-13 21:48:11 +05:00
test_set_wpa_country_cli_d9257478f4744e58b0642c17f37c8438-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_set_wpa_country_cli_e48bf73040464e68aabc31e594e1c8f4-outbox.sqlite3 feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
test_set_wpa_country_cli_f711faccb89e435bb95032fc293a0488-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_set_wpa_log_level_cli_0d1973337d304fac8fcb043ceb89e1bd-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_set_wpa_log_level_cli_3cbf09975721407b84a9d161efb9c5d1-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_set_wpa_log_level_cli_4259e62f380d4093b96b41eed8f02acf-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_set_wpa_log_level_cli_0165510f914f407a9be630efa18994fc-outbox.sqlite3 feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
test_set_wpa_log_level_cli_1481033d0533487ba98f90e278f6001d-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_set_wpa_log_level_cli_a269125990f34d3a9995fd27b7152b80-outbox.sqlite3 Убрал journal event dropped by acl из journal adapter, чтобы ACL-drop больше не писался обратно в тот же journald-поток и не создавал петлю. 2026-04-13 21:48:11 +05:00
test_set_wpa_log_level_cli_b0a34a53162145ca88ec00c790211841-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_show_state_cli_0e091a94d02b49a1983b185c9197aad0-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_show_state_cli_05d1ca95696a47468bd0e79085b1a696-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_show_state_cli_18e40ebf8ab843dc83331b0de6bda67f-outbox.sqlite3 feat: prefilter journal reads from acl process allowlist 2026-04-13 22:50:40 +05:00
test_show_state_cli_89c5a94c88e943daa00bb8c9bb7f26da-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_show_state_cli_3208e00675754c8990202c7ee53331db-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00
test_show_state_cli_ac018d0e7f1248bcbbf9f3db7ee973e7-outbox.sqlite3 feat: split runtime env and system config 2026-04-13 16:29:06 +05:00
test_show_state_cli_e47e1737420e4889a3b9ab1d613456c7-outbox.sqlite3 Убрал journal event dropped by acl из journal adapter, чтобы ACL-drop больше не писался обратно в тот же journald-поток и не создавал петлю. 2026-04-13 21:48:11 +05:00
wf_agent_test_cache_cli-outbox.sqlite3 коррекции неудачных тестов 2026-04-13 15:32:48 +05:00

README.md

wf-agent

wf-agent - Linux/Python агент для сбора Wi-Fi телеметрии, событий journald, координат и выполнения команд. Проект построен как модульный монолит на Python 3.12+ с asyncio, FastAPI, SQLite, SQLAlchemy 2.x и Pydantic v2.

Назначение

Агент нужен, чтобы:

  • собирать данные из нескольких источников на Linux-хосте;
  • нормализовать входные события в каноническую модель;
  • хранить latest state, event log, journal cursor и служебные статусы отдельно;
  • выполнять команды через D-Bus command path;
  • экспортировать часть данных сразу, а часть по расписанию;
  • строить корреляции между Wi-Fi, journald, координатами и командами;
  • предоставлять HTTP API, CLI, метрики и операционные команды.

Архитектура

Поток данных

adapter -> internal envelope -> validation -> normalization -> canonical model -> persistence -> delivery overlay -> transport outbox -> northbound/API/observability

Основные принципы

  • модульный монолит, а не набор микросервисов;
  • весь входящий поток проходит через raw envelope -> validation -> normalization;
  • сначала persist, потом send;
  • кешированные данные остаются транспорт-агностичными;
  • состояние доставки хранится отдельно от cached_events;
  • outbox pattern обязателен для доставляемых сущностей;
  • transport outbox хранится в отдельной SQLite БД;
  • API не вызывает adapters напрямую, только services;
  • timestamps всегда UTC-aware;
  • latest state и event log разделены;
  • journal cursor хранится персистентно;
  • тесты не должны использовать production-like DSN.

Разделение конфигурации

Системные и пользовательские настройки разделены на два файла:

  • .env.example и deployment/env/wf-agent.env.example - переменные окружения для приложения;
  • deployment/config/wf-agent.toml.example - ACL, transports, интервалы и другие системные правила.

По умолчанию приложение ищет:

  • /opt/wf-agent/.env;
  • /etc/wf-agent/wf-agent.toml.

В .env хранятся:

  • APP_NAME;
  • APP_ENV;
  • DATABASE_DSN;
  • OUTBOX_DATABASE_DSN;
  • LISTEN_HOST;
  • LISTEN_PORT.

В TOML хранятся:

  • wifi_interface_name;
  • cache_ttl_seconds;
  • history_ttl_seconds;
  • [[transports]];
  • [acl].

Если параметры CLI --config-file и --env-file не переданы, используются значения по умолчанию.

Экспорт кешированных сообщений

Кешированные сообщения экспортируются по transport schedule:

  • [[transports]] задает outbound transports;
  • transport default обязателен и используется как fallback для cached deliveries;
  • в ACL можно указать transport <name> для конкретного правила;
  • kind = "none" не создает packet и помечает due-сообщения как delivered;
  • kind = "webhook" собирает JSON packet и отправляет его наружу.

Компоненты

app.adapters

  • navigation читает координаты и формирует navigation envelopes;
  • journal читает systemd-journal с persistent cursor;
  • dbus_wpa подключается к system D-Bus, получает сигналы wpa_supplicant и выполняет D-Bus команды;
  • client-модули содержат test-friendly абстракции и fake clients.

app.ingestion

  • IngestionDispatcher маршрутизирует envelopes по каналам;
  • SourceManager управляет жизненным циклом adapters и health state;
  • queues служат внутренней транспортной прослойкой между source runtime и services.

app.normalization

  • validator проверяет форму входных данных;
  • mapper создает canonical records;
  • classifier назначает delivery mode и priority;
  • dedup содержит dedup и idempotency helpers.

app.services

  • CanonicalIngestionService выполняет validate -> map -> classify -> persist;
  • StateService и EventService разделяют latest-state и event-log persistence;
  • OutboxService создает transactional outbox rows для доставляемых сущностей;
  • ReplayService управляет retry/replay абстракциями;
  • CommandService и command state machine управляют жизненным циклом команд.

app.correlation

  • LocationMatcher связывает Wi-Fi event с ближайшей валидной location snapshot;
  • JournalLinker связывает Wi-Fi event с journald evidence;
  • CommandLinker связывает command с observed effects;
  • DerivedEventEngine превращает корреляции в derived events.

app.delivery

  • NorthboundExporter превращает outbox row в стабильный payload;
  • packet builder собирает JSON packet для cached exports;
  • WebhookTransportClient отправляет packet наружу;
  • FakeNorthboundClient используется в тестах.

app.workers

  • CachedExportWorker обрабатывает cached messages по transport schedule;
  • SourceHealthWorker пишет health snapshots;
  • retention worker очищает просроченные cached rows.

app.api

  • /health/live и /health/ready;
  • /admin/sources, /admin/outbox, /admin/cache-retention, /admin/scan-results;
  • /commands и retry endpoints;
  • /metrics.

app.cli

  • show messages list;
  • show messages content;
  • show outbox state;
  • show outbox content --id <packet_id>;
  • show outbox counters;
  • inspect outbox как alias к show outbox state;
  • clear outbox;
  • clear outbox counters.

app.storage

  • main DB bootstrap;
  • outbox DB bootstrap;
  • ORM schema;
  • repositories;
  • unit of work;
  • record mappers для source registry, health, state, events, journal cursors, commands, derived events, cached event delivery overlay и packet outbox.

Структура репозитория

wf-agent/
  app/
    adapters/         # navigation, journal, dbus_wpa adapters and client abstractions
    api/              # FastAPI entrypoint, health/admin/command/metrics routes
    bootstrap/        # application factory, dependency wiring, lifecycle
    cli/              # local diagnostic CLI
    commands/         # command state machine and dispatcher
    correlation/      # location matcher, journal linker, command linker, derived events
    core/             # config, clock, ids, logging, constants
    delivery/         # northbound client, packet builder, exporter helpers
    ingestion/        # envelopes, queues, dispatcher, source manager
    monitoring/       # metrics, health snapshots, source-health worker support
    normalization/    # validator, mapper, classifier, dedup helpers
    services/         # canonical ingestion, state/event/outbox/replay/command services
    storage/          # DB bootstrap, schema, repositories, UoW
    workers/          # cached export worker, source health worker, retention worker
  deployment/
    config/           # example runtime config files, including ACL and transports
    env/              # example environment file for system deployment
    systemd/          # systemd service unit baseline
  docs/
    adr/              # architecture decision records
    architecture/     # policy and architecture notes
    operations/       # runbook, support guide, procedures
  migrations/
  tests/
  pyproject.toml
  README.md

Конфигурация и запуск

Основные примеры файлов:

Локальный запуск:

python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -e .[test]
pytest -q

Примеры CLI:

wf-agent show messages list
wf-agent show outbox state
wf-agent show outbox content --id <packet_id>
wf-agent inspect outbox

Документация