Collector daemon, FastAPI server (addresses, diff, collect, sources), SQLite storage with change journal, Docker Compose deployment, tests, documentation and project rules. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
Итоги: хранение собранных адресов в SQLite
План: docs/plan-sqlite-storage.md.
Сделано
db.py(новый): SQLite (ripe.db, WAL), таблицаaddresses(kind, source, value, first_seen, last_seen),user_version;connect/session/transaction,merge_source(upsert + TTL),sweep_unconfigured,purge_source,get_values,count_values.- Миграция: при первом открытии базы
data.jsonиfqdn_data.jsonимпортируются одной транзакцией (BEGIN IMMEDIATE, параллельный старт безопасен),first_seen/last_seenсохраняются (старый формат без них:last_seen= момент миграции); оригиналы переименовываются в*.migrated-<ts>(резервная копия и путь отката). cidr_collector.py: сбор пишет в БД одной транзакцией (конфиг перечитывается внутри неё, удалённый во время сбора источник не воскресает); удалены JSON-хранилище,merge_entry,purge_entry, файловые блокировки данных. Блокировка конфига (update_config) осталась.api_server.py: чтение адресов, счётчики/healthиpurgeработают через БД;sqlite3.ErrorиStorageError-> 503.- Порча базы:
not a database/malformed-> файл (с-wal/-shm) переименовывается вripe.db.corrupt-<ts>,StorageError(503);database is lockedне считается порчей и файл не трогает. - Развёртывание:
db.pyдобавлен вDockerfile;*.db,*.db-wal,*.db-shm,*.migrated-*в.gitignore/.dockerignore; README: раздел 9 (схема, миграция, откат, бэкап), обновлены логика сбора и раздел Docker. - Тесты: тесты на JSON переведены на БД, добавлены проверка порчи базы (в существующем тесте) и
tests/test_db.py(импорт старого/нового формата, идемпотентность). Всего 14, в контейнере 14 passed.
Проверка
- Эталон: на копии реальных данных ответы
/addresses?type=all|cidr|fqdnпосле миграции побайтно совпадают со снятыми старой JSON-версией; повторный старт ничего не импортирует. - Сбор: 6 ASN и 3 FQDN обновлены, повторный запуск дубликатов не создаёт (49 = 49 уникальных).
- Конкурентность: 60 запросов
/addressesво время сбора - все 200; 15 прогонов по 5 процессов, одновременно мигрирующих чистую копию, - без ошибок, ровно один импорт. - Порча: мусор в
ripe.db-> 503, файл убран в*.corrupt-*. - Docker Compose (два контейнера, один том): миграция в томе, эталон совпал, демон записывает, API читает,
purgeвиден, послеdown/upданные на месте; стенд убран.
Замечания
- После порчи базы следующие запросы вернут пустой список (создаётся новая пустая база), пока сборщик не наполнит её заново; повреждённый файл сохранён как
*.corrupt-*. Это осталось прежним поведением, автоматического восстановления из копии нет. - Резервное копирование не автоматизировано (в README описана команда
sqlite3 ".backup"), это можно добавить заданием демона. - Сообщение лога «... data saved» теперь пишется после каждой транзакции, даже если ничего не изменилось.
- Первый запуск на реальных данных: запись
google.com(нет в конфигурации) станет стареть по TTL, её адрес удалится через 90 дней после миграции;last_seenстарых записей после миграции = момент миграции. - WAL не рекомендуется на сетевых ФС.
- Хранение истории изменений и
?since=в этот шаг не входили; схема (first_seen/last_seen) для них подготовлена.