Защита /var и /etc от дрифта
В атомарной системе на базе bootc файловая система разделена на иммутабельную (/usr) и персистентную (/var, /etc) части. Директория /var не обновляется вместе с образом — она сохраняется как есть между обновлениями. Директория /etc управляется через 3-way merge, но не все изменения гарантированно применяются.
Это создает проблему дрифта — расхождения реального состояния файловой системы с тем, что ожидает образ.
Почему возникает дрифт
Репозиторий ALT Linux Sisyphus — это классический дистрибутив, не рассчитанный на атомарные обновления. Большинство пакетов не поставляют tmpfiles.d конфиги для своих директорий и файлов. В обычной системе это не проблема — пакетный менеджер создает все нужные файлы при установке. Но в атомарной системе:
/varне обновляется при смене образа. Если новый пакет в образе ожидает директорию в/var, а её там нет — сервис не запустится./etcпроходит через 3-way merge при обновлении, но над файлами могли быть совершены деструктивные действия на стороне пользователи- Права и владельцы могут разъехаться: например, GID группы изменился в новом образе, а файлы в
/varостались со старым владельцем.
Кроме обновлений, дрифт может возникнуть из-за ручных действий пользователя или сбоев.
Как APM решает проблему
APM включает модуль lint, который сканирует файловую систему образа и генерирует декларативные конфиги tmpfiles.d. При каждой загрузке systemd применяет эти конфиги, приводя /var и /etc в задекларированное состояние.
Что генерируется
Команда apm system image lint --fix (скрытая команда, выполняется автоматически при сборке образа, не запускайте на рабочей системе!) анализирует rootfs и создает /usr/lib/tmpfiles.d/apm-lint.conf с тремя типами записей:
d— директории с правами и владельцем. Если директория отсутствует, systemd создаст её при загрузке.L— симлинки с правильным target. Если симлинк пропал или указывает не туда, systemd восстановит его.z— права и владелец на существующие файлы. Если файл существует, но права или владелец расходятся — systemd исправит.
Пример сгенерированного конфига
# Auto-generated by apm lint
d /var/lib/chrony 0755 _chrony _chrony - -
d /var/lib/libvirt/qemu 0750 _libvirt vmusers - -
d /var/spool/cron 0730 root crontab - -
L /etc/mtab - - - - /proc/mounts
L /etc/init.d - - - - rc.d/init.d
z /etc/openssh/sshd_config 0600 root root - -
z /etc/shadow 0400 root root - -Что не покрывается
Тип z не создает файлы — только устанавливает права на существующие. Если конфигурационный файл пропал из /etc, tmpfiles.d не восстановит его содержимое. Такие файлы должны поставляться пакетом и восстанавливаться через ostree 3-way merge. Но конфиги из /etc которые входят в образ всегда доступны на рабочей системе и находятся в /usr/etc, можно считать этот референсным состоянием, в будущем мы напишем полноценные средства восстановления для /etc.
При сборке образа
При сборке образа через apm system image apply lint запускается автоматически — конфиг генерируется и включается в образ. На живой системе ничего запускать вручную не нужно.
Применение при загрузке
При каждой загрузке systemd автоматически выполняет systemd-tmpfiles --create, который читает все конфиги из /usr/lib/tmpfiles.d/, включая apm-lint.conf. Это происходит на раннем этапе загрузки.
Исключения
Некоторые директории намеренно исключены из рекурсивного анализа, так как их содержимое управляется другими механизмами:
| Директория | Причина |
|---|---|
/var/home, /var/root | Домашние директории пользователей |
/var/tmp | Временные файлы |
/var/cache/apt | Кэш пакетного менеджера |
/etc/rc.d | SysVinit симлинки, управляются chkconfig |
/etc/tcb | Управляются системой аутентификации |
/etc/alternatives/links | Управляются системой alternatives |
/etc/skel* | Шаблоны для создания пользователей |