Вопрос: Как установить пакеты без запуска связанных служб?


Как вам известно, по умолчанию, когда вы устанавливаете пакет в системе на базе Debian или Ubuntu, если пакет содержит службу, эта служба обычно включается и запускается автоматически при установке пакета.

Это проблема для меня.

Я обнаружил, что мне нужно управлять шаблонами для создания контейнеров LXC. Существует несколько контейнеров, каждый из которых соответствует выпуску Debian или Ubuntu. (Существуют также контейнеры на основе Red Hat, но они здесь не актуальны.)

/var/lib/libvirt/filesystems/debian6_template
/var/lib/libvirt/filesystems/debian7_template
/var/lib/libvirt/filesystems/ubuntu1004_template
/var/lib/libvirt/filesystems/ubuntu1204_template

Иногда я обнаруживаю, что шаблоны имеют недостающий пакет или нуждаются в каких-то других изменениях, поэтому я буду использовать их для установки пакета. К сожалению, когда я это делаю, я завершаю работу нескольких копий службы пакета!

В качестве примера я обнаружил, что у шаблонов не было демона syslog, поэтому я установил его:

for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done

И быстро закончил работу с четырьмя копиями rsyslog. Не говоря уже о двух экземплярах exim4. К сожалению!


Я где-то читал (хотя теперь я не могу найти его снова), что он не должен запускать службы при работе в chroot, но это явно не происходит здесь.

Один потенциально жизнеспособный неприятный взломать вызывает временную замену различных команд, которые фактически запускают службы, такие как start-stop-daemon а также initctl, хотя это намного больше работы, чем я действительно хотел. Если у меня нет другого выбора, хотя ...

Идеальное решение здесь было бы для систем на базе Debian прекратить делать это дерьмо, но в противном случае, возможно, неясная или недокументированная опция командной строки для apt-get?

Если это было непонятно, я действительно хочу сохранить что-либо, связанное с управлением шаблонами за пределами шаблоны, если это возможно.


12
2018-01-15 16:30


Источник




Ответы:


Для debian вы можете сделать это с помощью политики rc.d, Вот одно объяснение:

Предполагается, что скрипты-хранители пакета должны взаимодействовать только с системой init с помощью invoke-rc.d, update-rc.d и заголовков сценариев LSB ...   invoke-rc.d, прежде чем предпринимать действия, проверит,   /usr/sbin/policy-rc.d является исполняемым, будет называть его соответствующим   имя службы и текущий номер уровня выполнения в командной строке и   действовать в соответствии с его кодом выхода. Например, возвращаемое значение 101   будет препятствовать планируемому действию. Это включает   автоматическое начало обслуживания при установке пакета, а также   остановку службы при удалении пакета и   ритуал остановки-обновления-перезагрузки при обновлении пакета до выполнения   обновление, которое может привести к запуску старой версии службы

Поскольку вы не хотите, чтобы какие-либо службы никогда не запускались, ваш скрипт policy-rc.d может быть просто

#!/bin/sh
exit 101

Это техника, используемая такими инструментами, как pbuilder и Docker's mkimage-Debootstrap,

К сожалению, эта техника не работает с Ubuntu chroots. Пакеты, которые интегрируются с системным вызовом upstart init / usr / sbin / initctl вместо invoke-rc.d во время установки, а initctl не обращается к policy-rc.d. По словам автора выскочки обходным путем является замена / sbin / initctl символьной ссылкой на / bin / true в chroot. Вы также можете увидеть это в mkimage-debootstrap, они делают

dpkg-divert --local --rename --add /sbin/initctl
ln -sf /bin/true sbin/initctl

22
2018-01-15 17:10



Это кажется довольно чистым, хотя его также нужно будет удалить, прежде чем создавать контейнер из шаблона. - Michael Hampton♦
Спасибо за это. Возможно, мне просто придется сорвать сценарий mkimage-debootstrap от Docker, поскольку они, похоже, в основном решили эту проблему. - Michael Hampton♦


Ты можешь сделать:

export RUNLEVEL=1
for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done
exit

Я не проверял его с помощью chroot, но он должен работать. Сначала он устанавливает переменную среды RUNLEVEL, поэтому процессы, инициированные apt-get не начнется любые сервисы, потому что они будут «думать», система работает в одном режиме. Поскольку среда изменена так, как она может повлиять на будущие команды, требуется выйти из оболочки, когда измененная среда больше не нужна, это достигается посредством Выход команды в конце. Там может быть некоторые (редкие?) пакеты, которые не будут установлены должным образом в одном режиме (но AFAIK это не должно быть проблемой в большинстве случаев).


4
2018-02-04 17:22



Является export RUNLEVEL=1 важная часть здесь? Что именно это может случиться? - Michael Hampton♦
@MichaelHampton Я считаю, что переменная окружения RUNLEVEL обеспечит текущий уровень выполнения. В этом случае он просто перезаписывает его, поэтому любое приложение будет думать, что оно работает на 1. Это своего рода «kludge», но этого достаточно. - WinkyWolly
Добавлено объяснение оригинальному ответу. В основном это то, что @WinkyWolly сказал. - DavisNT
К сожалению rsyslog оказался одним из «редких» пакетов, которые полностью взорвались при попытке установить этот путь. Однако это может быть полезно, так что вы можете сохранить upvote :) - Michael Hampton♦