Próximo: , Anterior: , Acima: Desenvolvimento   [Conteúdo][Índice]


7.3 Invocando guix pack

Ocasionalmente você quer passar software para pessoas que não têm (ainda!) a sorte de usar Guix. Você diria para elas executarem guix package -i algo, mas isso não é possível neste caso. É aqui que guix pack entra.

Nota: Se você estiver procurando maneiras de trocar binários entre máquinas que já executam Guix, veja Invocando guix copy, Invocando guix publish e Invocando guix archive.

O comando guix pack cria uma embalagem de software encapsulado: ele cria um tarball ou algum outro arquivo contendo os binários do software em que você está interessado e todas as suas dependências. O arquivo resultante pode ser usado em qualquer máquina que não tenha Guix, e as pessoas podem executar exatamente os mesmos binários que você tem com Guix. A embalagem em si é criada de forma reproduzível em bits, para que qualquer um possa verificar se ela realmente contém os resultados da compilação que você pretende enviar.

Por exemplo, para criar uma embalagem contenda Guile, Emacs, Geiser e todas as suas dependências, você pode executar:

$ guix pack guile emacs emacs-geiser
…
/gnu/store/…-pack.tar.gz

O resultado aqui é um tarball contendo um diretório /gnu/store com todos os pacotes relevantes. O tarball resultante contém um perfil com os três pacotes de interesse; o perfil é o mesmo que seria criado por guix package -i. É esse mecanismo que é usado para criar o próprio tarball binário autônomo do Guix (veja Instalação de binários).

Usuários desta embalagem teriam que executar /gnu/store/…-profile/bin/guile para executar o Guile, o que você pode achar inconveniente. Para contornar isso, você pode criar, digamos, uma ligação simbólica /opt/gnu/bin para o perfil:

guix pack -S /opt/gnu/bin=bin guile emacs emacs-geiser

Dessa forma, os usuários podem digitar /opt/gnu/bin/guile e aproveitar.

E se o destinatário do sua embalagem não tiver privilégios de root na máquina dele e, portanto, não puder descompactá-lo no sistema de arquivos raiz? Nesse caso, você vai querer usar a opção --relocatable (veja abaixo). Essa opção produz binários relocáveis, o que significa que eles podem ser colocados em qualquer lugar na hierarquia do sistema de arquivos: no exemplo acima, os usuários podem descompactar seu tarball no diretório pessoal deles e executar diretamente ./opt/gnu/bin/guile.

Como alternativa, você pode produzir uma embalagem no formato de imagem do Docker usando o seguinte comando:

guix pack -f docker -S /bin=bin guile guile-readline

O resultado é um tarball que pode ser passado para o comando docker load, seguido por docker run:

docker load < arquivo
docker run -ti guile-guile-readline /bin/guile

onde arquivo é a imagem retornada por guix pack, e guile-guile-readline é sua “image tag”. Veja documentação do Docker para mais informações.

Outra opção é produzir uma imagem SquashFS com o seguinte comando:

guix pack -f squashfs bash guile emacs emacs-geiser

O resultado é uma imagem do sistema de arquivos SquashFS que pode ser montada ou usada diretamente como uma imagem de contêiner do sistema de arquivos com o ambiente de execução do contêiner Singularity, usando comandos como singularity shell ou singularity exec.

Outro formato internamente baseado em SquashFS é o AppImage. Um arquivo de AppImage pode ser criado e executado sem qualquer provilégio especial:

file=$(guix pack -f appimage --entry-point=bin/guile guile)
$file --help

Várias opções de linha de comando permitem que você personalize sua embalagem:

--format=formato
-f formato

Produza uma embalagem no formato fornecido.

Os formatos disponíveis são:

tarball

Este é o formato padrão. Ele produz um tarball contendo todos os binários e ligações simbólicas especificados.

docker

Isso produz um tarball que segue o Docker Image Specification. Por padrão, o “nome do repositório” como aparece na saída do comando docker images é computado a partir de nomes de pacotes passados na linha de comando ou no arquivo manifesto. Como alternativa, o “nome do repositório” também pode ser configurado por meio da opção --image-tag. Consulte --help-docker-format para obter mais informações sobre essas opções avançadas.

squashfs

Isso produz uma imagem SquashFS contendo todos os binários e ligações simbólicas especificados, bem como pontos de montagem vazios para sistemas de arquivos virtuais como procfs.

Nota: Singularity requer que você forneça /bin/sh na imagem. Por esse motivo, guix pack -f squashfs sempre implica -S /bin=bin. Portanto, sua invocação guix pack deve sempre começar com algo como:

guix pack -f squashfs bash …

Se você esquecer o pacote bash (ou similar), singularity run e singularity exec falharão com uma mensagem inútil “nenhum arquivo ou diretório”.

deb

Isso produz um arquivo Debian (um pacote com a extensão de arquivo ‘.deb’) contendo todos os binários e ligações simbólicas especificados, que podem ser instalados em cima de qualquer distribuição GNU(/Linux) baseada em dpkg. Opções avançadas podem ser reveladas por meio da opção --help-deb-format. Elas permitem incorporar arquivos de controle para um controle mais refinado, como ativar gatilhos específicos ou fornecer um script de configuração do mantenedor para executar código de configuração arbitrário na instalação.

guix pack -f deb -C xz -S /usr/bin/hello=bin/hello hello

Nota: Como os arquivos produzidos com guix pack contêm uma coleção de itens de armazém e como cada pacote dpkg não deve ter arquivos conflitantes, na prática isso significa que você provavelmente não conseguirá instalar mais de um desses arquivos em um dado sistema. Você pode, no entanto, empacotar quantos pacotes Guix quiser em um desses arquivos.

Aviso: dpkg assumirá a propriedade de quaisquer arquivos contidos no pacote que ele não saiba. Não é sensato instalar arquivos ‘.deb’ produzidos pelo Guix em um sistema onde /gnu/store é compartilhado por outro software, como uma instalação do Guix ou outras embalagens não deb.

rpm

Isso produz um arquivo RPM (um pacote com a extensão de arquivo ‘.rpm’) contendo todos os binários e ligações simbólicas especificados, que podem ser instalados em cima de qualquer distribuição GNU/Linux baseada em RPM. O formato RPM incorpora somas de verificação para cada arquivo que ele contém, que o comando rpm usa para validar a integridade do arquivo.

Opções avançadas relacionadas a RPM são reveladas por meio da opção --help-rpm-format. Essas opções permitem incorporar scripts de mantenedor que podem ser executados antes ou depois da instalação do arquivo RPM, por exemplo.

O formato RPM suporta pacotes relocáveis por meio da opção --prefix do comando rpm, o que pode ser útil para instalar um pacote RPM em um prefixo específico.

guix pack -f rpm -R -C xz -S /usr/bin/hello=bin/hello hello
sudo rpm --install --prefix=/opt /gnu/store/...-hello.rpm

Nota: Ao contrário dos pacotes Debian, arquivos conflitantes, mas idênticos em pacotes RPM podem ser instalados simultaneamente, o que significa que vários pacotes RPM produzidos pelo guix pack geralmente podem ser instalados lado a lado sem nenhum problema.

Aviso: rpm assume a propriedade de quaisquer arquivos contidos no pacote, o que significa que ele removerá /gnu/store ao desinstalar um pacote RPM gerado pelo Guix, a menos que o pacote RPM tenha sido instalado com a opção --prefix do comando rpm. Não é sensato instalar pacotes ‘.rpm’ produzidos pelo Guix em um sistema onde /gnu/store é compartilhado por outro software, como uma instalação do Guix ou outras embalagens não rpm.

appimage

Isto produz um arquivo AppImage com a extensão ‘.AppImage’. Um AppImage é um volume SquashFS prefixado com uma execução que monta o sistema de arquivo SquashFS e executa o binário criado com o --entry-point. Isso resulta num arquivo auto-contido que agrupa o software e todos os requisitos num único arquivo. Quando o mesmo é executado, ele roda o software empacotado.

guix pack -f appimage --entry-point=bin/vlc vlc

A execução usada pelos AppImages invoca o comando fusermount3 para montar a imagem rapidamente. Se o comando está indiponível, o AppImage falha em executar, mas ele ainda pode ser iniciado com a opção --appimage-extract-and-run.

Aviso: Ao construir um AppImage, sempre passe a opção --relocatable (ou -R, ou a -RR) para ter certeza que a imagem pode ser usada em sistemas onde o Guix não está instalado. Um aviso é impresso quando esta opção não é usada.

guix pack -f appimage --entry-point=bin/hello --relocatable hello

Nota: The resulting AppImage does not conform to the complete standard as it currently does not contain a .DirIcon file. This does not impact functionality of the AppImage itself, but possibly that of software used to manage AppImages.

Nota: As the generated AppImage packages the complete dependency graph, it will be larger than comparable AppImage files found online, which depend on host system libraries.

--relocatable
-R

Produza binários relocáveis—ou seja, binários que podem ser colocados em qualquer lugar na hierarquia do sistema de arquivos e executados a partir daí.

Quando essa opção é passada uma vez, os binários resultantes requerem suporte para user namespaces no kernel Linux; quando passada duas vezes18, binários relocáveis recorrem a outras técnicas se os namespaces de usuário não estiverem disponíveis, e essencialmente funcionam em qualquer lugar—veja abaixo as implicações.

Por exemplo, se você criar uma embalagem contendo Bash com:

guix pack -RR -S /mybin=bin bash

... você pode copiar essa embalagem para uma máquina que não tenha Guix e, a partir do seu diretório pessoal, como um usuário normal, executar:

tar xf pack.tar.gz
./mybin/sh

Nesse shell, se você digitar ls /gnu/store, você notará que /gnu/store aparece e contém todas as dependências de bash, mesmo que a máquina realmente não tenha /gnu/store completamente! Essa é provavelmente a maneira mais simples de implementar software construído pelo Guix em uma máquina não Guix.

Nota: Por padrão, binários relocáveis dependem do recurso user namespace do kernel Linux, que permite que usuários sem privilégios montem ou alterem a raiz (chroot). Versões antigas do Linux não o suportavam, e algumas distribuições GNU/Linux o desativam.

Para produzir binários relocáveis que funcionam mesmo na ausência de namespaces de usuário, passe --relocatable ou -R duas vezes. Nesse caso, os binários tentarão o suporte a namespaces de usuário e retornarão a outro mecanismo de execução se os namespaces de usuário não forem suportados. Os seguintes mecanismos de execução são suportados:

default

Experimente usar namespaces de usuário e retorne ao PRoot se eles não forem suportados (veja abaixo).

performance

Experimente usar namespaces de usuário e retorne ao Fakechroot se eles não forem suportados (veja abaixo).

userns

Execute o programa por meio de namespaces de usuário e aborte se eles não forem suportados.

proot

Execute através do PRoot. O programa PRoot fornece o suporte necessário para virtualização do sistema de arquivos. Ele consegue isso usando a chamada de sistema ptrace no programa em execução. Essa abordagem tem a vantagem de funcionar sem exigir suporte especial do kernel, mas incorre em sobrecarga de tempo de execução toda vez que uma chamada de sistema é feita.

fakechroot

Execute através do Fakechroot. Fakechroot virtualiza acessos ao sistema de arquivos interceptando chamadas para funções da biblioteca C, como open, stat, exec e assim por diante. Ao contrário do PRoot, ele incorre em muito pouca sobrecarga. No entanto, nem sempre funciona: por exemplo, alguns acessos ao sistema de arquivos feitos de dentro da biblioteca C não são interceptados, e acessos ao sistema de arquivos feitos via syscalls diretas também não são interceptados, levando a um comportamento errático.

Ao executar um programa encapsulado, você pode solicitar explicitamente um dos mecanismos de execução listados acima, definindo a variável de ambiente GUIX_EXECUTION_ENGINE adequadamente.

--entry-point=comando

Use command as the entry point of the resulting pack, if the pack format supports it—currently docker, appimage, and squashfs (Singularity) support it. command must be relative to the profile contained in the pack.

O ponto de entrada especifica o comando que ferramentas como docker run ou singularity run iniciam automaticamente por padrão. Por exemplo, você pode fazer:

guix pack -f docker --entry-point=bin/guile guile

A embalagem resultante pode ser facilmente carregado e docker run sem argumentos extras irá gerar bin/guile:

docker load -i pack.tar.gz
docker run image-id
--entry-point-argument=comando
-A comando

Use comando como um argumento para o ponto de entrada da embalagem resultante. Esta opção é válida somente em conjunto com --entry-point e pode aparecer várias vezes na linha de comando.

guix pack -f docker --entry-point=bin/guile --entry-point-argument="--help" guile
--max-layers=n

Especifica o número máximo de camadas de imagem do Docker permitidas ao criar uma imagem.

guix pack -f docker --max-layers=100 guile

Esta opção permite que você limite o número de camadas em uma imagem Docker. As imagens Docker são compostas de várias camadas, e cada camada adiciona ao tamanho geral e à complexidade da imagem. Ao definir um número máximo de camadas, você pode controlar os seguintes efeitos:

  • Uso do disco: Aumentar o número de camadas pode ajudar a otimizar o espaço em disco necessário para armazenar várias imagens criadas com um grafo de pacote semelhante.
  • Puxar: Ao transferir imagens entre diferentes nós ou sistemas, ter mais camadas pode reduzir o tempo necessário para puxar a imagem.
--expression=expr
-e expr

Considere o pacote que expr avalia.

Isso tem o mesmo propósito que a opção de mesmo nome em guix build (veja --expression em guix build).

--file=arquivo

Build a pack containing the package or other object the code within file evaluates to.

This has the same purpose as the same-named option in guix build (veja --file in guix build), but it has no shorthand, because -f already means --format.

--manifest=arquivo
-m arquivo

Use os pacotes contidos no objeto manifesto retornado pelo código Scheme em arquivo. Esta opção pode ser repetida várias vezes, nesse caso os manifestos são concatenados.

Isto tem um propósito similar à opção de mesmo nome em guix package (veja --manifest) e usa os mesmos arquivos de manifesto. Ele permite que você defina uma coleção de pacotes uma vez e use-a tanto para criar perfis quanto para criar arquivos para uso em máquinas que não tenham o Guix instalado. Note que você pode especificar ou um arquivo de manifesto ou uma lista de pacotes, mas não ambos.

Veja Escrevendo manifestos, para obter informações sobre como escrever um manifesto. Veja guix shell --export-manifest, para obter informações sobre como “converter” opções de linha de comando em um manifesto.

--system=sistema
-s sistema

Tente compilar para sistema—por exemplo, i686-linux—em vez do tipo de sistema do host de compilação.

--target=tripleto

Construção cruzada para tripleto, que deve ser um tripleto GNU válido, como "aarch64-linux-gnu" (veja (Autoconf)autoconf).

--compression=ferramenta
-C ferramenta

Compacte o tarball resultante usando ferramenta—um dos seguintes: gzip, zstd, bzip2, xz, lzip ou none para nenhuma compactação.

--symlink=spec
-S spec

Adicione os symlinks especificados por spec à embalagem. Esta opção pode aparecer várias vezes.

spec tem o formato fonte=alvo, onde fonte é a ligação simbólica que será criado e alvo é o destino da ligação simbólica.

Por exemplo, -S /opt/gnu/bin=bin cria uma ligação simbólica /opt/gnu/bin apontanda para o subdiretório bin do perfil.

--save-provenance

Salvar informações de procedência para os pacotes passados na linha de comando. As informações de procedência incluem a URL e o commit dos canais em uso (veja Canais).

As informações de procedência são salvas no arquivo /gnu/store/…-profile/manifest na embalagem, junto com os metadados usuais do pacote — o nome e a versão de cada pacote, suas entradas propagadas e assim por diante. São informações úteis para o destinatário da embalagem, que então sabe como a embalagem foi (supostamente) obtida.

Esta opção não é habilitada por padrão porque, assim como os timestamps, as informações de proveniência não contribuem em nada para o processo de construção. Em outras palavras, há uma infinidade de URLs de canais e IDs de commit que podem levar à mesma embalagem. Gravar esses metadados “silenciosos” na saída, portanto, potencialmente quebra a propriedade de reprodutibilidade bit a bit de origem para binário.

--root=arquivo
-r arquivo

Crie arquivo como uma ligação simbólica para a embalagem resultante e registre-a como uma raiz do coletor de lixo.

--localstatedir
--profile-name=nome

Inclua o “diretório de estado local”, /var/guix, na embalagem resultante, e principalmente o perfil /var/guix/profiles/per-user/root/nome — por padrão, nome é guix-profile, que corresponde a ~root/.guix-profile.

/var/guix contém o banco de dados do armazém (veja O armazém), bem como as raízes do coletor de lixo (veja Invocando guix gc). Fornecê-lo na embalagem significa que o armazém está “completo” e gerenciável pelo Guix; não fornecê-lo na embalagem significa que o armazém está “morto”: itens não podem ser adicionados a ele ou removidos dele após a extração da embalagem.

Um caso de uso para isso é o tarball binário independente do Guix (veja Instalação de binários).

--derivation
-d

Exiba o nome da derivação que constrói a embalagem.

--bootstrap

Use os binários bootstrap para construir a embalagem. Esta opção é útil somente para desenvolvedores do Guix.

Além disso, guix pack suporta todas as opções de compilação comuns (veja Opções de compilação comuns) e todas as opções de transformação de pacote (veja Opções de transformação de pacote).


Notas de Rodapé

(18)

Aqui vai um truque para memorizá-la: -RR, que adiciona suporte a PRoot, pode ser pensado como a abreviação de “Really Relocatable”. Legal, não é?


Próximo: A cadeia de ferramentas do GCC, Anterior: Invocando guix environment, Acima: Desenvolvimento   [Conteúdo][Índice]