Скрипты пакета, reinstall и конфигурационные файлы

⏱ 30 мин · 🧩 заданий: 5

Зачем пакету скрипты

Установка — не только распаковка файлов. Многим программам нужны действия, которые нельзя выразить списком файлов. Для этого пакет содержит скрипты сопровождающего (maintainer scripts), которые менеджер запускает в определённые моменты.

Debian (dpkg) RPM Когда выполняется
preinst %pre до распаковки файлов (при установке и обновлении)
postinst %post после распаковки (настройка — configure)
prerm %preun до удаления файлов (при удалении и обновлении — у старой версии)
postrm %postun после удаления файлов (в том числе purge)

Скрипт получает аргумент-контекст: install, upgrade <старая версия>, configure <версия>, remove, purge (в RPM — число установленных экземпляров), и может вести себя по-разному.

Типичные задачи pre-install

  • Проверить условия и прервать установку (ненулевой код выхода): несовместимая версия, нет нужного ресурса.
  • Остановить старую версию службы перед заменой исполняемых файлов.
  • Создать пользователя/группу, если распаковываемые файлы должны сразу им принадлежать.
  • Подготовить миграцию: сохранить данные старой версии, переименовать устаревший конфиг.

Типичные задачи post-install

  • Создать системного пользователя (adduser --system nginx), каталоги с нужными владельцами и правами (/var/lib/app).
  • Сгенерировать то, что нельзя положить в пакет: ключи SSH-сервера (openssh-server создаёт /etc/ssh/ssh_host_*), сертификаты, уникальные идентификаторы.
  • Зарегистрировать и запустить службу: systemctl enable --now, перезапустить после обновления.
  • Обновить системные кеши и базы: ldconfig после установки библиотек (вспомните урок о ldd), базы man, кеш шрифтов и иконок, update-alternatives, depmod для модулей ядра. Сейчас многое из этого делают триггеры пакетного менеджера — один раз на всю транзакцию.
  • Мигрировать данные и конфигурацию со старой версии.
#!/bin/sh
# postinst
set -e
case "$1" in
    configure)
        adduser --system --group --no-create-home myapp || true
        install -d -o myapp -g myapp /var/lib/myapp
        systemctl daemon-reload
        systemctl enable --now myapp.service
        ;;
esac
exit 0

Скрипты выполняются от root

Поэтому пакеты принимают только из доверенных подписанных репозиториев: скрипт пакета может сделать в системе что угодно.

Конфигурационные файлы

Файлы в /etc пользователь правит под себя. При обновлении нельзя просто затереть их новой версией. Поэтому пакет помечает конфигурационные файлы:

  • dpkg: список conffiles (все файлы пакета в /etc обычно попадают туда автоматически);
  • RPM: %config и %config(noreplace) в спецификации.

dpkg: три контрольные суммы

При установке новой версии dpkg сравнивает: файл на диске (текущий), файл из старого пакета (сумма запомнена при прошлой установке) и файл из нового пакета.

Пользователь менял? В пакете изменился? Действие dpkg
нет нет ничего не делать
нет да тихо поставить новую версию
да нет оставить версию пользователя
да да спросить пользователя (или по опциям --force-confold / --force-confnew); новая версия — .dpkg-dist, старая — .dpkg-old
удалил — считать удаление намеренным, не восстанавливать (кроме --force-confmiss)

apt remove оставляет конфиги (пакет в состоянии rc), apt purge удаляет и их.

RPM

Пометка Пользователь изменил файл Результат
%config(noreplace) да файл пользователя остаётся, новый — рядом как .rpmnew
%config да ставится новый, файл пользователя сохраняется как .rpmsave
любая нет тихо заменяется

Reinstall

Переустановка той же версии: apt install --reinstall pkg, dnf reinstall pkg, rpm -Uvh --replacepkgs.

Когда это осмысленно

  1. Повреждены или удалены файлы пакета: случайно удалили бинарник или библиотеку, сбой диска; debsums pkg / rpm -V pkg показывают расхождения.
  2. Файлы перезаписаны вручную: make install поверх пакетной версии, ручная замена библиотеки.
  3. Нужно снова выполнить скрипты пакета: служба не зарегистрирована, удалён системный пользователь, не обновлён кеш.

Reinstall не нужен для обновления версии и не сбрасывает изменённые конфиги.

Что происходит

dpkg выполняет полный цикл как при обновлении на ту же версию: prerm upgrade старой копии → preinst upgrade → распаковка всех файлов заново (повреждённые и удалённые обычные файлы восстанавливаются) → postrm upgrade → postinst configure.

С конфигурационными файлами — по правилам выше:

  • изменённые пользователем — сохраняются (пакетная версия та же, вопросов нет);
  • неизменённые — остаются равными пакетным;
  • удалённые conffiles не восстанавливаются — dpkg считает удаление волей пользователя. Восстановить: apt install --reinstall -o Dpkg::Options::="--force-confmiss" pkg.

В RPM при reinstall изменённый %config(noreplace) остаётся, а пакетная версия кладётся как .rpmnew; изменённый %config заменяется, а старый сохраняется как .rpmsave.

Ответ на задачу 6 коротко

Скрипты pre/post-install нужны для действий, которых нет в списке файлов: проверить условия и прервать установку, остановить старую службу; после распаковки — создать пользователей и каталоги, сгенерировать ключи, зарегистрировать и запустить службу, обновить кеши (ldconfig, man), мигрировать данные. Reinstall осмыслен, когда файлы пакета повреждены, удалены или перезаписаны вручную, либо нужно заново выполнить скрипты. При этом все файлы пакета распаковываются заново и скрипты выполняются снова, а конфигурационные файлы, изменённые администратором, сохраняются; удалённые конфиги dpkg не восстанавливает без --force-confmiss; RPM кладёт новую версию рядом (.rpmnew) или сохраняет старую (.rpmsave).

Итог

  • preinst/postinst/prerm/postrm (%pre/%post/%preun/%postun) — действия до и после распаковки и удаления.
  • Конфиги помечаются (conffiles, %config); изменения пользователя не затираются.
  • Reinstall восстанавливает файлы пакета и перезапускает скрипты, но изменённые конфиги оставляет.

Практика решено 0 из 5

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Заполнить таблицу

В каком скрипте пакета уместно каждое действие?

preinst (до распаковки)postinst (после распаковки)prerm (до удаления файлов)postrm (после удаления)
Создать системного пользователя nginx для службы
Остановить работающую старую версию службы перед обновлением
Включить и запустить службу, обновить кеш ldconfig
Проверить, что на диске хватает места / несовместимая версия — и прервать установку
Остановить службу перед удалением пакета
При purge удалить данные и пользователя, созданных пакетом
Отметьте ячейку — «+», пустая — «−».
Задание 2 Несколько вариантов

Зачем в метаинформации пакета нужны скрипты pre-install и post-install?

Задание 3 Заполнить таблицу

Что произойдёт с конфигурационным файлом при apt install --reinstall pkg (dpkg)?

Заменится версией из пакетаОстанется как естьБудет вопрос пользователю
Файл не менялся пользователем
Пользователь изменил файл, версия в пакете та же
Пользователь удалил conffile
Пользователь изменил файл, а в новой версии пакета (обновление) файл тоже изменился
Отметьте ячейку — «+», пустая — «−».
Задание 4 Несколько вариантов

В каких случаях осмысленно выполнить reinstall пакета?

Задание 5 Один вариант ответа

RPM-пакет помечает конфиг как %config(noreplace). Пользователь изменил файл. Что сделает dnf reinstall?

Войдите, чтобы отмечать пройденные уроки.