Em alguns dos meus scripts de compilação, tenho usado namespaces de montagem como um mecanismo para montar com segurança sem nunca deixar essas montagens para trás quando o script termina. Os pontos de montagem não compartilhados são desmontados implicitamente quando o último processo nesse namespace é encerrado .
Meus scripts geralmente incluem uma stansa como esta:
#!/bin/bash
self_ns=$(ls -lh /proc/self/ns/mnt)
init_ns=$(ls -lh /proc/$PPID/ns/mnt)
if [ "${self_ns#*mnt:}" = "${init_ns#*mnt:}" ] ; then
unshare --mount $0 "$@"
exit $?
fi
Embora isso tenha funcionado bem para mim por algum tempo, recentemente encontrei um problema em um servidor de compilação jenkins.
Eu acredito que o problema é que o próprio script de compilação está sendo executado dentro de um ambiente chroot jenkins . Então, quando o script é executado unshare --mount ...
, ele falha com o erro:
unshare: cannot change root filesystem propagation: Invalid argument
Infelizmente, eu realmente não entendo essa restrição ou como contorná-la. Quando tento um chroot na linha de comando, não consigo replicar esse erro. Eu não sei o que o plugin jenkins fez para causar isso.
O mais importante é que esses pontos de montagem sejam removidos na saída todas as vezes, sem falhas .
Com base no comentário de AB, encontrei uma solução alternativa:
AB escreveu:
Com base nisso, descobri que isso não funciona:
Mas isso funciona:
A causa do problema é que
unshare
tenta definir os sinalizadores de propagação de montagem do diretório raiz, o que só pode ser feito para pontos de montagem. O diretório raiz do ambiente chroot do Jenkins não é um ponto de montagem.Por exemplo:
Uma reprodução completa:
Uma solução simples, que não faz montagens fora do namespace de montagem. Ele escapa do chroot para definir a propagação de montagem e assume que o comando mount está disponível fora do chroot:
Ou converta o chroot em um
pivot_root
ambiente: