Alpine Linux: Compilando

Saudações.

Este tutorial ensina como compilar os pacotes originais do Alpine Linux usando os esquemas oficiais.

O propósito e utilidade desses procedimentos serve à personalização de programas na estapa de compilação como:

  • Adicionar features omitidas no pacote oficial;
  • Adicionar configurações;
  • Ativar tunings de arquitetura (instruções nativas);
  • Criar repositórios de pacotes próprios.

Tutoriais de base:

Pré-requisitos:

  • VM/VPS/Host com instalação do Linux Alpine;
  • Internet no servidor (sua VPS ou host);

1 – Preparando Alpine

Vamos baixar os pacotes de ferramentas e fontes. Iniciaremos logados como root.

1.1 – Ferramentas

Programas compiladores:

Shell (root)
# Atualizar o sistema base
    apk update;
    apk upgrade;

# (No Host ou VM, se houver atualizacao de kernel, reinicie: reboot )

# Instalar ferramentas para o ambiente de compilacao:
    apk add \
        alpine-sdk abuild doas \
        sudo bash openssl tar file binutils \
        strace \
        git \
        make pkgconf patch \
        gcc g++ readline musl-dev;

1.2 – Usuário para compilação

Os procedimentos de compilação devem ser realizados por usuário comum (sem privilégios de root).

Shell (root)
# Criar usuário para rodar processos de compilacao
    adduser -D builder;

# Adicionar no grupo de construtores (abuild)
    addgroup builder abuild;

# Dar poder de SUDO para rodar algumas operacoes como root
    echo "builder ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/builder;

1.3 – Alternar para modo usuário “builder”

De agora em diante vamos alterar para o modo usuário comum “builder“.

Você pode usar o “su” para obter shell (/bin/ash) como “builder” ou fazer logout do root e login nesse usuário.

Shell (root)
# Rodar o shell como usuario builder
# Shell ash
    su - builder -s /bin/ash;

# OU shell bash:
#   su - builder -s /bin/bash;

Agora logado como “builder“:

Shell ASH (user: builder)
# Conferir id:
# - Precisa ter uid diferente de zero
# - Precisa estar no grupo: abuild
    id;
    # uid=1000(builder) gid=1000(builder) groups=300(abuild),1000(builder)

# Entrar na pasta do usuário:
    cd ~;

# Conferir:
    pwd;
    # /home/builder

1.4 – Gerar configuração e chave privada

A chave privada (RSA 4096 bits) é necessária para assinar digitalmente os pacotes que você gerar.

Shell ASH (user: builder)
# Alternativa automatica (chave com caminho aleatorio):
#   echo | abuild-keygen -a -i;

# Variaveis
    # Contato responsavel
    NAME="Eu Mesmo";
    EMAIL="eu@mesmo.com";
    # Caminho das chaves
    PRIV="/home/builder/.abuild/builder-default.rsa";
    PUBK="$PRIV.pub"; 

# Criar pasta da config do abuild:
    mkdir -p .abuild;
    mkdir -p /home/builder/packages;

# Gerar chave privada RSA 4096 bits
    [ -s "$PRIV" ] || {
        openssl genrsa \
            -out         $PRIV \
            4096;
    };

# Gerar chave publica derivada da privada
    [ -s "$PUBK" ] || {
        openssl rsa \
            -in          $PRIV \
            -pubout -out $PUBK;
    };

# Gerar configuracao de usuario compilador
(
    echo "PACKAGER_PRIVKEY=\"$PRIV\"";
    echo "PACKAGER=\"$NAME <$EMAIL>\"";
    echo "MAINTAINER=\"$NAME <$EMAIL>\"";
    echo 'USE_COLORS=1';
    echo 'DABUILD_PACKAGES="/home/builder/packages"';
) > .abuild/abuild.conf;

# Colocar no caminho padrao:
sudo sh -c "cat .abuild/abuild.conf > /etc/abuild.conf";

# Copiar chave publica para a pasta de chaves do sistema:
sudo cp $PUBK /etc/apk/keys/;

O arquivo de configuração do abuilder será lido em /home/builder/.abuild/abuild.conf ou /etc/abuild.conf (caminho principal).

Diretórios para arquivos baixados (fontes, patchs, projetos git, etc):

Shell ASH (user: builder)
# Diretório de cache para arquivos baixados
sudo  mkdir -p      /var/cache/distfiles;
sudo  chgrp abuild  /var/cache/distfiles;
sudo  chmod g+w     /var/cache/distfiles;

1.5 – Obter os fontes oficiais

Os fontes do Alpine são conjuntos de pacotes “aports” contendo os scripts que baixam os fontes originais, patches (correções), dependências e ferramentas para construir um pacote final pronto para uso.

Shell ASH (user: builder)
# Baixando projeto aports do Alpine Linux
# - Na pasta do usuario
cd ~;

# - Clonar projeto git
git clone --depth 1 https://gitlab.alpinelinux.org/alpine/aports.git;

O projeto será baixado na pasta “aports“.

Diretórios em “./aports/“:

  • main/ – Pacotes oficiais que fazem parte da distribuição Alpine Linux, 1.653 pacotes;
  • community/: Pacotes de vários fabricantes e projetos diversos, 7.775 pacotes;
  • testing/: Pacotes em fase de teste para aprovação (branch edge), 3.167 pacotes;

Explore os diretórios para se acostumar com o formato.

2 – Analisando o pacote Redis

Vou usar o Redis como base para analise e recompilação.
Ele se encontra em: /home/builder/aports/community/redis

Arquivos dentro do pacote Redis:

  • APKBUILD – Script shell POSIX, define variáveis e funções que serão executadas durante a construção do pacote.
    • pkgname: Nome do pacote;
    • pkgver: Versão;
    • pkgrel: Número incremental por compilação, reinicia ao mudar o pkgver;
    • pkgdesc: Descrição do pacote e projeto;
    • url: Url do projeto;
    • arch: Arquitetura, padrão “all”;
    • license: Nome da licença usada (ex: MIT);
    • depends: Nome dos pacotes necessários previamente para rodar o programa;
    • makedepends: Pacotes necessários para compilar o pacote;
    • checkdepends: Pacotes necessários para verificação do pacote;
    • install: Nome dos scripts usados na instalação do pacote final;
    • subpackages: Nome dos pacotes gerados pela compilação do projeto;
    • source: Arquivos e URLs onde os fontes, patchs e artefatos do projeto estão;
    • builddir: Diretório usado para trabalhar na construção do pacote;
    • build(): Função de construção;
    • check(): Função de verificação;
    • package(): Função de empacotamento;
  • Arquivos para o OpenRC:
    • redis-sentinel.initd – Instalado em /etc/init.d/redis-sentinel;
    • redis.initd – Instalado em /etc/init.d/redis;
    • redis.confd – Instalado em /etc/conf.d/redis;
  • Configurações final para uso do software:
    • redis.logrotate – Instalado em /etc/logrotate.d/redis;
  • Patchs e alterações do código original:
    • redis.conf.patch – Altera a configuração padrão do projeto Redis;
    • sentinel.conf.patch – Altera a configuração padrão do sentinel;
  • Scripts do pacote pronto para execução no ambiente de destino:
    • redis.pre-install – Script a executar antes da instalação;
    • redis.post-install – Script a executar após a instalação;

Agora vamos compilá-lo:

Shell ASH (user: builder)
# Entrar no projeto aports do Redis
cd ~/aports/community/redis/;

# Compilar:
# -r = instalar dependencias
# -c = saida colorida durante compilacao
abuild -r -c;

Verificar pacote pronto:

Shell ASH (user: builder)
# Verificar pacotes prontos:
find /home/builder/packages/community;

3 – Construindo via Docker

O ideal é criar uma imagem de container que tenha todos os pacotes e preparativos prontos, assim você pula direto para a personalização e compilação do seu pacote.

.

“Comece fazendo o que é necessário,
depois o que é possível,
e de repente você estará
fazendo o impossível.”
São Francisco de Assis

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com