S6-init no Obarun

Obarun e S6

O S6 - Skarnet.org’s Small & Secure Supervision Software Suite inclui um init, um dos vários projectos que se rebelaram contra o SystemD afirmando que havia maneiras melhores e/ou mais simples de fazer a mesma coisa.

Para quem?

Apesar de a implementação oficial do S6 ter começado por ser no Alpine Linux, por alguma razão o autor agora colabora com o Adélie Linux, que já explorei antes.
No entanto, a expressão mais madura do S6-init encontra-se no Obarun, uma distribuição baseada em Arch e, tanto quanto sei, sem a colaboração do autor do S6, apesar de serem todos franceses. Isto porque o S6 ainda não definiu uma maneira de organizar as dependências entre os serviços (e sendo zelota do “Caminho do UNIX”, talvez nunca o venha a fazer), o que significa que alguém tem de fazê-lo; a contribuição do Obarun é um conjunto de scripts chamado 66
Por isso, para experimentar o S6 tive de instalar o Obarun; sendo baseado em Arch, temi o pior, mas comparado com o Adélie até foi relativamente simples.

Notas de instalação

  • O locale PT-UTF8 causa erros de caracter na consola texto (configuração errada no grub.cfg?)

    Refiz a instalação no locale en_GB-UTF8 e funcionou.
  • Em modo minimal, o NAT do VirtualBox fornece o valore da opção nameserver (opção DHCP 5) que é escrita em /etc/resolv.conf, mas em NATnetwork não, é necessário editar o /etc/resolv.conf à mão. Bug do VirtualBox? A “NAT Network” ainda tem muitos bugs, e talvez um deles seja que as opções DHCP não são transmitidas, mas não cheguei a usar um packet sniffer para verificar…

S6/66 (v.6.3+)

O 66, como disse, é uma camada de gestão sobre o sistema S6, que se baseia na criação de um conjunto de árvores, que são criadas pelo utilizador e que são um meio-termo entre a ordem numérica/alfabética do SysV-init e o grafo dinamicamente actualizado do SystemD.

Exemplo: instalar SSHD

O serviço sshd instala-se com

1
pacman -S --needed openssh

66 fase 1: service script

O service script que controla o serviço openssh não é instalado automaticamente; tem de ser criado, ou obtido dos scripts que existem no repositório observice. Os service scripts existentes neste repo podem ser listados com

1
pacman -Sl observice

Para instalar o service script,

1
pacman -S sshd-66serv

Para que o sistema saiba que o serviço foi adicionado,

1
66-enable sshd

Agora já podemos ver o conteúdo do service script com

1
66-inservice sshd

Name                  : sshd
Version               : 0.2.1
In tree               : 
Status                : 
Type                  : classic
Description           : ssh daemon
Source                : /usr/lib/66/service/sshd
Live                  : /run/66/scandir/0/sshd
Dependencies          : sshd-log
External dependencies : None
Optional dependencies : None
Start script          :  
                        	foreground { exec ssh-keygen -A } 
                        	execl-cmdline -s { /usr/sbin/sshd -f ${conf_file} ${cmd_args} }
Stop script           : None
Environment source    : /etc/66/conf/sshd/0.2.1
Environment file      : 
                        environment variables from: /etc/66/conf/sshd/0.2.1/.sshd
                        conf_file=!/etc/ssh/sshd_config
                        cmd_args=!-D

Log name              : sshd-log
Log destination       : /var/log/66/sshd
Log file              : None

66 fase 2: configurar as dependências

No entanto, os serviços antes de serem iniciados têm de ser adicionados a uma tree, que codifica as dependências dos serviços.
Para ver e manipular as trees, usa-se o comando 66-intree (a partir da versão 0.6x do 66)
Acho muito útil a opção -g que mostra a estrutura de dependências dos serviços que se encontram configurados nas trees.

1
66-intree -g

Name         : boot
Initialized  : yes
Enabled      : no
Starts after : None
Current      : no
Allowed      : root
Symlinks     : svc->source db->source
Contents     : /
               ├─(144,Enabled,classic) tty-earlier@tty12
               ├─(up,Enabled,oneshot) system-hostname
               ├─(up,Enabled,oneshot) mount-run
               ├─(up,Enabled,oneshot) populate-run
               ├─(up,Enabled,oneshot) mount-tmp
               ├─(up,Enabled,oneshot) populate-tmp
               ├─(up,Enabled,oneshot) mount-proc
               ├─(up,Enabled,oneshot) mount-sys
               ├─(up,Enabled,oneshot) populate-sys
               ├─(up,Enabled,oneshot) mount-dev
               ├─(up,Enabled,oneshot) mount-pts
               ├─(up,Enabled,oneshot) mount-shm
               ├─(up,Enabled,oneshot) populate-dev
               ├─(up,Enabled,oneshot) mount-cgroups
               ├─(up,Enabled,bundle) 00
               ├─(up,Enabled,bundle) all-Mount
               ├─(up,Enabled,oneshot) system-hwclock
               ├─(up,Enabled,oneshot) modules-kernel
               ├─(up,Enabled,oneshot) system-random
               ├─(up,Enabled,oneshot) modules-system
               ├─(up,Enabled,oneshot) system-sysctl
               ├─(184,Enabled,longrun) udevd-log
               ├─(359,Enabled,longrun) udevd
               ├─(up,Enabled,oneshot) udevadm
               ├─(up,Enabled,oneshot) system-fontnkey
               ├─(up,Enabled,oneshot) system-fsck
               ├─(up,Enabled,oneshot) mount-fstab
               ├─(up,Enabled,bundle) all-System
               ├─(up,Enabled,oneshot) mount-rw
               ├─(up,Enabled,oneshot) mount-netfs
               ├─(up,Enabled,oneshot) local-loop
               ├─(up,Enabled,oneshot) local-sethostname
               ├─(up,Enabled,oneshot) local-time
               ├─(up,Enabled,oneshot) local-authfiles
               ├─(up,Enabled,oneshot) local-tmpfiles
               ├─(up,Enabled,oneshot) local-dmesg
               ├─(up,Enabled,bundle) all-Local
               ├─(up,Enabled,oneshot) all-Runtime
               ├─(up,Enabled,bundle) All
               ├─(580,Enabled,longrun) tty-rc@tty1
               ├─(579,Enabled,longrun) tty-rc@tty2
               └─(up,Enabled,module) boot@system

Name         : root
Initialized  : yes
Enabled      : yes
Starts after : None
Current      : yes
Allowed      : root
Symlinks     : svc->source db->source
Contents     : /
               ├─(567,Enabled,classic) dhcpcd-log
               └─(566,Enabled,classic) dhcpcd

Para activar o serviço e iniciá-lo na altura correcta do processo de arranque, criamos uma nova tree net (que correrá serviços que dependem de a rede estar configurada) a seguir à tree root (onde neste momento está o serviço dhcpcd que configura a rede):

1
66-tree –S root -nE net

66-tree: info: Created successfully tree: net
66-tree: info: Enabled successfully tree: net
66-tree: info: Ordered successfully tree: net starts after tree: root

Depois de criar a nova tree, adiciona-se o serviço sshd a essa tree:

1
66-enable -t net sshd

66-enable: info: Enabled successfully: sshd

E finalmente activam-se todos os serviços da tree:

1
66-all -t net up

66-all: info: Initialized successfully: sshd-log
66-all: info: Initialized successfully: sshd
66-all: info: Initialization: no atomic services into tree: net
66-all: info: sshd-log: started successfully
66-all: info: sshd: started successfully

E agora já nos podemos ligar ao Obarun por SSH.
Podemos ver as alterações que foram feitas repetindo o comando 66-intree -g

             
Name         : boot
Initialized  : yes
Enabled      : no
Starts after : None
Current      : no
Allowed      : root
Symlinks     : svc->source db->source
Contents     : /
               ├─(144,Enabled,classic) tty-earlier@tty12
               ├─(up,Enabled,oneshot) system-hostname
               ├─(up,Enabled,oneshot) mount-run
               ├─(up,Enabled,oneshot) populate-run
               ├─(up,Enabled,oneshot) mount-tmp
               ├─(up,Enabled,oneshot) populate-tmp
               ├─(up,Enabled,oneshot) mount-proc
               ├─(up,Enabled,oneshot) mount-sys
               ├─(up,Enabled,oneshot) populate-sys
               ├─(up,Enabled,oneshot) mount-dev
               ├─(up,Enabled,oneshot) mount-pts
               ├─(up,Enabled,oneshot) mount-shm
               ├─(up,Enabled,oneshot) populate-dev
               ├─(up,Enabled,oneshot) mount-cgroups
               ├─(up,Enabled,bundle) 00
               ├─(up,Enabled,bundle) all-Mount
               ├─(up,Enabled,oneshot) system-hwclock
               ├─(up,Enabled,oneshot) modules-kernel
               ├─(up,Enabled,oneshot) system-random
               ├─(up,Enabled,oneshot) modules-system
               ├─(up,Enabled,oneshot) system-sysctl
               ├─(184,Enabled,longrun) udevd-log
               ├─(359,Enabled,longrun) udevd
               ├─(up,Enabled,oneshot) udevadm
               ├─(up,Enabled,oneshot) system-fontnkey
               ├─(up,Enabled,oneshot) system-fsck
               ├─(up,Enabled,oneshot) mount-fstab
               ├─(up,Enabled,bundle) all-System
               ├─(up,Enabled,oneshot) mount-rw
               ├─(up,Enabled,oneshot) mount-netfs
               ├─(up,Enabled,oneshot) local-loop
               ├─(up,Enabled,oneshot) local-sethostname
               ├─(up,Enabled,oneshot) local-time
               ├─(up,Enabled,oneshot) local-authfiles
               ├─(up,Enabled,oneshot) local-tmpfiles
               ├─(up,Enabled,oneshot) local-dmesg
               ├─(up,Enabled,bundle) all-Local
               ├─(up,Enabled,oneshot) all-Runtime
               ├─(up,Enabled,bundle) All
               ├─(580,Enabled,longrun) tty-rc@tty1
               ├─(579,Enabled,longrun) tty-rc@tty2
               └─(up,Enabled,module) boot@system

Name         : root
Initialized  : yes
Enabled      : yes
Starts after : None
Current      : yes
Allowed      : root
Symlinks     : svc->source db->source
Contents     : /
               ├─(565,Enabled,classic) sshd-log
               ├─(567,Enabled,classic) dhcpcd-log
               ├─(566,Enabled,classic) dhcpcd
               └─(564,Enabled,classic) sshd

Name         : net
Initialized  : yes
Enabled      : yes
Starts after : root
Current      : no
Allowed      : root
Symlinks     : svc->source db->source
Contents     : /
               ├─(565,Enabled,classic) sshd-log
               └─(564,Enabled,classic) sshd

Conclusão

Sim, as “árvores” do 66 permitem gerir as dependências dos serviços de forma ligeiramente mais intuitiva do que os clássicos scripts numerados do SysV-init, mas estão muito longe da facilidade de utilização dos service units do SystemD, que são declarativos.
Além disso, a instalação e configuração dos service units é muitas vezes automatizada pelos package managers das distribuições que suportam SystemD, e como são declarativos, basta criar o service unit e depois o SystemD se encarregará de extrair as dependências e paralelismos nos serviços configurados. Apesar de o 66 suportar o arranque paralelo de serviços através do uso das trees, tem de ser o administrador a definir exactamente a ordem de arranque de cada serviço.
Para quem quiser mais controlo do que aquele que o SystemD oferece por defeito, é óptimo, ou pelo menos melhor que o SysV-init, mas é igualmente (ou mais) trabalhoso. Os scripts 66 ajudam um pouco, mas não muito.
Claro que o que falta ao S6, OpenRC, Runit, etc, é as milhares de horas de programação que foram investidas no SystemD e a quantidade neste caso tem uma qualidade em si mesma. Em comparação, todos estes inits são um bolo ao qual falta o fermento para subir.
Se estiver interessado em contribuir para este projecto, eles precisam de si.