Como posso instalar pacotes sem iniciar seus serviços associados?

13

Como você provavelmente sabe, por padrão quando você instala um pacote em um sistema Debian ou Ubuntu, se o pacote contém um serviço, esse serviço geralmente será ativado e iniciado automaticamente quando você instalar o pacote.

Isso é um problema para mim.

Eu me encontrei precisando gerenciar modelos para criar contêineres LXC. Existem vários contêineres, cada um correspondendo a um lançamento do Debian ou Ubuntu. (Há também contêineres baseados no Red Hat, mas eles não são relevantes aqui.)

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

Ocasionalmente, irei descobrir que os templates têm um pacote faltando ou precisam de alguma outra mudança, então eu vou chroot dentro deles para instalar o pacote. Infelizmente quando faço isso, acabo com várias cópias do serviço do pacote rodando!

Por exemplo, achei que os modelos não tinham um daemon syslog, então instalei um:

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

E prontamente acabou com quatro cópias do rsyslog em execução. Sem mencionar duas cópias do exim4. Opa!

Eu li em algum lugar (embora eu não consiga encontrá-lo novamente agora) que ele não deveria iniciar serviços quando executado em um chroot, mas isso claramente não está acontecendo aqui.

Um corte desagradável potencialmente viável requer a substituição temporária dos vários comandos que realmente iniciam serviços, como start-stop-daemon e initctl , embora isso seja muito mais trabalho do que eu realmente queria fazer. Se eu não tiver outra escolha, embora ...

A solução ideal aqui seria que os sistemas baseados no Debian parassem de fazer essa porcaria, mas, na sua falta, talvez uma opção de linha de comando obscura ou não documentada para apt-get ?

Caso não esteja claro, eu realmente quero manter qualquer coisa relacionada ao gerenciamento dos modelos fora dos modelos, se possível.

    
por Michael Hampton 15.01.2014 / 17:30

2 respostas

22

Para o debian, você pode fazer isso com policy-rc.d . Aqui está uma explicação :

A package’s maintainer scripts are supposed to only interface with the init system by means of invoke-rc.d, update-rc.d and the LSB init script headers... invoke-rc.d will, before taking its action, check whether /usr/sbin/policy-rc.d is executable, will call it with the respective service name and the current runlevel number on its command line and act according to its exit code. For example, a return value of 101 will prevent the planned action from being taken. This includes the automated start of the service upon package installation as well as the stop of the service on package removal and reduces the stop-upgrade-restart ritual during package upgrades to just performing the upgrade which might leave the old version of the service running

Como você não deseja que nenhum serviço seja iniciado, seu script policy-rc.d pode ser simplesmente

#!/bin/sh
exit 101

Esta é a técnica usada por ferramentas como o mkimage-debootstrap .

Infelizmente, essa técnica não funciona com o chroots do Ubuntu . Os pacotes que se integram ao sistema init de inicialização chamam / usr / sbin / initctl em vez de invoke-rc.d durante a instalação, e o initctl não consulta o policy-rc.d. De acordo com o autor do upstart , a solução é substituir / sbin / initctl por um link simbólico para / bin / true em um chroot. Você pode ver isso no mkimage-debootstrap também, eles fazem

dpkg-divert --local --rename --add /sbin/initctl
ln -sf /bin/true sbin/initctl
    
por 15.01.2014 / 18:10
4

Você pode fazer:

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

Eu não testei com o chroot, mas deve funcionar. Inicialmente, ele define a variável de ambiente RUNLEVEL, portanto, os processos iniciados pelo apt-get não iniciarão quaisquer serviços, porque eles "pensarão" que o sistema está sendo executado no modo único. Como o ambiente é modificado da maneira que pode afetar comandos futuros, é necessário sair do shell quando o ambiente modificado não é mais necessário, isso é realizado pelo comando exit no final. Existem podem ser alguns pacotes (raros?) Que não serão instalados corretamente no modo único (mas o AFAIK não deve ser um problema na maioria dos casos).

    
por 04.02.2014 / 18:22