- убран блок collections: community.docker и community.general приходят
вместе с пакетом ansible, версия которого уже точно зафиксирована в uv.lock
- пин заводил вторую копию в ~/.ansible/collections, она перекрывала
bundled-версию и молча расходилась с ней при обновлении ansible
- CI и так жил на bundled-коллекциях: requirements.yml он не читает,
ставит только pip install ansible ansible-lint
- community.docker 5.2.2 -> 5.3.0, community.general 13.3.0 -> 13.4.0
- пины приведены к версиям, которые уже приносит пакет ansible 14.4.0:
ansible-lint больше не подхватывает старую копию из ~/.ansible
- galaxy-роли (timezone, security, docker) уже на последних версиях
- pyrefly 1.2.0 -> 1.3.0, ruff 0.16.6 -> 0.16.7, ansible 14.3.1 -> 14.4.0
(ansible-core 2.21.3 -> 2.21.4), filelock, platformdirs
- границы версий в pyproject.toml не трогали, изменился только uv.lock
- pyrefly, ruff, yamllint и ansible-lint на новых версиях проходят без замечаний
- обе секции llm ходят в одну модель вместо разных, комментарии
переписаны под именование моделей через Bifrost
- обновлены секреты в group_vars/all/secrets.yml
- контейнер запускается от своего пользователя, доступ к docker.sock
через дополнительную группу docker
- добавлен data/ под /data, он же попадает в backup-targets
- в 0.16 расширился набор правил по умолчанию: 29 срабатываний там, где 0.15
давал "All checks passed"
- subprocess.run без явного check (PLW1510) — проставлен check=False там, где
код и так разбирает returncode сам
- слепые except Exception в оркестраторе бэкапов и скриптах помечены
noqa: BLE001 с объяснением, почему перехват намеренно широкий
- EXE001 и TRY004 отключены в pyproject: бит исполняемости в репозитории
ничего не решает, а ValueError при разборе config.toml — про содержимое
конфига, а не про тип аргумента
- ruff format в 0.16 форматирует python внутри markdown, из-за чего
переформатирован пример в docs/drafts/gitea-runner-on-demand.md
- ansible 13.2.0 -> 14.3.1 (ansible-core 2.20.1 -> 2.21.3), ansible-lint
25.12.2 -> 26.8.0, invoke 2.2.1 -> 3.0.3, requests, croniter, yamllint,
типы и транзитивные пакеты
- ruff оставлен на 0.15: в 0.16 расширился набор правил по умолчанию, из-за
чего в скриптах и tasks.py появляется 29 срабатываний; обновление вынесено
в отдельный заход вместе с правкой кода
- ansible-lint, pyrefly и yamllint на новых версиях проходят без замечаний
- geerlingguy.security 3.0.0 -> 3.0.2: фикс пропущенной точки с запятой в
50unattended-upgrades, из-за которой origin=Ubuntu,archive=*-security не
попадал в allowed origins и автообновления безопасности ничего не ставили
- geerlingguy.docker 7.9.0 -> 8.0.0: удалён сломанный nightly-репозиторий,
изменение затрагивает только RedHat
- community.docker 5.2.2 и community.general 13.3.0 зафиксированы явно, чтобы
версии не разъезжались между окружениями
- json-file с max-size 10m и max-file 3 через docker_daemon_options
- до этого логи росли неограниченно, /var/lib/docker/containers добрался до 1.8 GB
- лимит применяется только к новым контейнерам, старые подхватят его при пересоздании
- security_ssh_permit_root_login: "no" — ansible ходит под major с become,
root по SSH не нужен
- security_autoupdate_enabled: true — unattended-upgrades ставит только
патчи из security-репозиториев, автоперезагрузка выключена
- сплошная простановка no_log сделана, инвентарь рендеров заменён на историю
- осталась проверка в lefthook/CI и перенос miniflux_postgres_user и
miniflux_postgres_database из vault в открытые group_vars
- возврат читаемого диффа отдан серии secrets-file-*, приоритет понижен
до среднего
- канон ролей лежит в ansible-roles, синхронизация идёт тасками
roles-status / roles-pull / roles-push, подписка — eget и app_image
- драфт переведён в статус «реализовано»: отмечены расхождения с дизайном
(имя канона, состав подписки) и незакрытые пункты плана
- алерты на заполнение диска стоят в health.d/system_resources.conf
(warn >75%, crit >90% по каждой смонтированной ФС)
- размеры приложений и свободное место приходят в уведомлении backup-all.py
- первый вызов после простоя занял 65,9 с и был оборван минутным умолчанием,
следующие уложились в 6–10 с
- по журналу запросов шлюза попытка была одна: 65,5 с ждал провайдер,
накладные шлюза 0,46 с
- playbook-diet.yml и files/diet: образ через app_image, uid=gid=1111,
каталоги config/data/cache, backup-targets со строкой data/
- блок сайта в Caddy разделён: /api/* идёт мимо Authelia под собственную
аутентификацию, клиентские Remote-* срезаются на уровне сайта
- правило Authelia one_factor без subject: пользователи шире группы admins
- bothub заведён custom-провайдером (base_provider_type openai, адрес без /v1):
из него ходит diet, нативному DeepSeek снимки еды не по силам
- client.log_retention_days = 30: тело запроса пишется в logs.db целиком,
снимок в 2500 px даёт запись около 911 КБ
- gobackup.template.yml и backup.template.sh не применялись: плейбук сам
удалял backup.sh, а бэкап давно идёт через backup-targets
- шаблон gobackup остался копипастой от gramps, с его путями в комментариях
- задача удаления легаси-файлов оставлена, чтобы снять их с сервера
- netdata слал в бандл server, удалённый при переименовании в backups,
и все health-алерты уходили в 404
- бандлы теперь рендерятся циклом: backups для отчётов backup-all.py,
alerts для netdata
- 20 приложений её не получают: контейнерами рулит ansible от root, а
членство в группе docker равносильно root на хосте
- у gitea, miniflux и outline группа осталась — их backup.sh дампит базу
через docker compose exec из-под самого приложения
- задача service-users-docker-group закрыта, остаток вынесен в новую
backup-dump-without-docker-group