Instalando o Ubuntu em um ambiente chroot jail no Archlinux – parte 2

Continuando o artigo anterior, vou descrever como ficou a versão final de minha instalação Ubuntu dentro do ambiente chroot e mostrar as configurações que haviam ficado pendentes:

  • D-Bus
  • PulseAudio

Mudanças desde a última versão

Eu estava enfrentando alguns problemas com o debconf/apt-get, então resolvi pegar a instalação de minha máquina virtual e transferir para o ambiente chroot. Para transferir a partição, que estava em um arquivo vdi, reconhecido somente pelo VirtualBox, eu coloquei a ISO de um livecd na VM, e a partir da VM usei o comando (onde o remote.host era meu próprio ip):

dd if=/dev/sda1 | ssh user@remote.host "cat > /remote/file"
view raw clone.sh hosted with ❤ by GitHub

NOTA: Antes de transferir a sua instalação Ubuntu, eu recomendo fortemente que instale todos os pacotes que você irá utilizar antes de transferir a partição. Isso vai lhe poupar bastante trabalho.

Para montar a imagem gerada com o comando anterior você pode usar o comando:

mount -o loop -t ext4 /path/to/chrootbuntu.sda1.ext4.img /srv/chroot/lucid/
view raw mount.sh hosted with ❤ by GitHub

Você pode alterar o arquivo /etc/rc.d/chrootbuntu para que ele faça a montagem dessa imagem para você. Ele ficaria então assim:

#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions
dirs=(/dev /dev/pts /dev/shm /tmp)
case $1 in
start)
stat_busy "Starting Ubuntu chroot"
mount -o loop -t ext4 /path/to/chrootbuntu.sda1.ext4.img /srv/chroot/lucid
for d in "${dirs[@]}"; do
mount -o bind $d /srv/chroot/lucid$d
done
mount -t proc none /srv/chroot/lucid/proc
mount -t sysfs none /srv/chroot/lucid/sys
add_daemon chrootbuntu
stat_done
;;
stop)
stat_busy "Stopping Ubuntu chroot"
for (( i = ${#dirs[@]} - 1; i >= 0; i-- )); do
umount "/srv/chroot/lucid${dirs[i]}"
done
umount /srv/chroot/lucid/{proc,sys}
umount /srv/chroot/lucid
rm_daemon chrootbuntu
stat_done
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
exit 0
view raw daemon.sh hosted with ❤ by GitHub

Nova configuração do ambiente chroot

Um processo interessante é também copiar certos arquivos de configuração que recriem o ambiente Archlinux dentro do ambiente Ubuntu, como arquivos de usuários e grupos. Isso é importante porque em sistemas Linux, um processo qualquer herda as configurações de ambiente do processo-pai, e dessa forma o comando chroot herdará as configurações de ambiente do processo bash, que está rodando dentro do seu Archlinux. Quando iniciar o bash do sistema Ubuntu, ele utilizará os arquivos de configuração que estão inconsistentes com as variáveis de ambiente herdadas. Abaixo um simples teste que mostra sobre sobre o quê eu estou discutindo:

[root@vinipsmaker-desktop ~]# groups
root bin daemon sys adm disk wheel log
[root@vinipsmaker-desktop ~]# chroot /srv/chroot/lucid/
groups: cannot find name for group ID 19
root@vinipsmaker-desktop:/# groups
root daemon bin sys adm disk uucp groups: cannot find name for group ID 19
19
view raw output.txt hosted with ❤ by GitHub

Você pode resolver o problema dessa inconsistência copiando arquivos importantes do sistema. Apenas execute os comandos abaixo:

# você também pode usar o comando "ln -f" no lugar de cp
cp /etc/passwd* /srv/chroot/lucid/etc
cp /etc/group* /srv/chroot/lucid/etc
# se você também usa sudo no seu Archlinux
# vai lhe poupar o trabalho de configurar o sudo do ambiente chroot
cp /etc/sudoers /srv/chroot/lucid/etc
# se você quiser o mesmo conjunto de senhas
cp /etc/shadow* /srv/chroot/lucid/etc
# opcional, somente para resolução de DNS
cp /etc/resolv.conf /srv/chroot/lucid/etc
cp /etc/localtime /srv/chroot/lucid/etc
cp /etc/mtab /srv/chroot/lucid/etc
view raw fix.sh hosted with ❤ by GitHub

Agora que o ambiente chroot está consistente com o ambiente Archlinux instalado, podemos também tornar o comando xhost mais seguro, restringindo os usuários com acesso ao seu servidor X:

xhost +SI:localuser:seu_username
xhost +SI:localuser:root
view raw xhost.sh hosted with ❤ by GitHub

D-Bus + PulseAudio

Para configurar uma única instância do D-Bus para todo o sistema, use os comandos abaixo antes de iniciar qualquer serviço D-Bus do ambiente chroot (lembrando que você também pode colocá-los no arquivo /etc/rc.d/chrootbuntu):

mount --bind /var/lib/dbus/ /srv/chroot/lucid/var/lib/dbus/
mount --bind /var/run/dbus/ /srv/chroot/lucid/var/run/dbus/
view raw dbus.sh hosted with ❤ by GitHub

Para permitir que aplicativos que façam uso do PulseAudio reproduzam som, utilizaremos as capacidades do PulseAudio de transmitir som através da rede. Para tal, edite o arquivo /etc/pulse/default.pa (tanto no Ubuntu quanto no Archlinux), adicionando/descomentando a linha:

load-module module-native-protocol-tcp
view raw pulse.conf hosted with ❤ by GitHub

Essa mudança irá garantir que o seu PulseAudio carregue o módulo tcp durante a inicialização, mas caso ele já esteja rodando, abra o console do pulseaudio (usando o comando pacmd), e use a mesma linha anterior como um comando nesse console.

Agora que o módulo está carregado, precisamos autorizar o usuário do ambiente chroot a acessar o servidor PulseAudio rodando localmente. Para tal, copie o arquivo de cookie que está na sua pasta de usuário (~/.pulse-cookie) para a pasta dos usuários irão usar o PulseAudio dentro do ambiente chroot.

Para finalizar, crie/edite o arquivo /etc/asound.conf do Ubuntu adicionando o conteúdo a seguir:

pcm.pulse {
type pulse
}
ctl.pulse {
type pulse
}
pcm.!default {
type pulse
}
ctl.!default {
type pulse
}
view raw alsa.conf hosted with ❤ by GitHub

Isso irá garantir que aplicações que façam uso diretamente do ALSA utilizem o PulseAudio.

Script facilitador

Um script que você pode colocar na sua pasta de usuário para automatizar a tarefa de configuração do X11 + PulseAudio é:

USER=$(whoami)
COOKIE=${HOME}/.pulse-cookie
xhost +SI:localuser:${USER}
xhost +SI:localuser:root
cp ${COOKIE} /srv/chroot/lucid/home/${USER}
sudo cp ${COOKIE} /srv/chroot/lucid/root
#sudo chroot /srv/chroot/lucid/ su ${USER}
view raw script.sh hosted with ❤ by GitHub

É isso.

EDIT:

Alguns programas (como o ROS, discutido na parte anterior do artigo), não irão funcionar corretamente se você configurou hostnames diferentes para a sua instalação Archlinux e sua instalação Ubuntu. Caso você tenha feito isso, não se desespere, basta editar o arquivo /etc/hosts e tudo vai funcionar normalmente.

EDIT2:

Alterei a linha:

umount /path/to/remote/file
view raw before.sh hosted with ❤ by GitHub

Para:

umount /srv/chroot/lucid
view raw after.sh hosted with ❤ by GitHub

Pois quando eu atualizei para o Linux 3.0 no Archlinux o comando antigo parou de funcionar.

EDIT3 (2014/02/10):

Hoje em dia eu não faria a abominação de copiar os arquivos da pasta /etc que definem usuários e grupos do ambiente hospedeiro para o ambiente convidado (ainda mais quando são baseados em distribuições completamente diferentes). Tal solução… tão vulgar… e pedindo para dores de cabeça no futuro. Só não apago o artigo, porque suas outras partes são úteis.

Hoje em dia eu só iria usar chroot para aplicações mínimas que não exigem comunicação com outros serviços do sistema. Se a aplicação precisar se comunicar com D-Bus, o Apache ou qualquer outro serviço do sistema, eu optaria por usar containers (chroot on steroids) no lugar. E a não ser que haja um meio fácil de atualizar a aplicação (e suas dependências) do chroot mínimo, eu acabaria optando por um ambiente completo no lugar de mínimo só para ter a facilidade de atualizar os pacotes facilmente (gerenciadores de pacotes ftw). Na verdade, eu provavelmente ainda acabaria optando por um container caso o ambiente convidado possuísse systemd, só para usufruir de suas funcionalidades legais como reiniciar serviços mortos, ativação por socket, monitoração de watchdog, interface unificada e bem documentada, …

E a “solução muito esperta” do D-Bus está com os dias contados com o pessoal querendo mover o D-Bus para o kernel.

Tags:, ,

Uma resposta para “Instalando o Ubuntu em um ambiente chroot jail no Archlinux – parte 2”

  1. Bruno Normande diz :

    Não sei se mais alguém teve esse problema, mas ao tentar instalar algo me deparei com o seguinte erro:

    dpkg: unrecoverable fatal error, aborting:
    syntax error: unknown group ‘mlocate’ in statoverride file
    E: Sub-process /usr/bin/dpkg returned an error code (2)

    resolvi rodando os seguintes comandos (precisa ser super user):
    # cat /dev/null > /var/lib/dpkg/statoverride-old
    # cat /dev/null > /var/lib/dpkg/statoverride
    $ sudo dpkg --configure -a

    ;D

Comentários (with MarkDown support)