Configuração de Servidor de Compilação

O servidor de compilação do F-Droid isola as compilações de cada pacote num ambiente de máquina virtual descartável limpo, isolado e seguro. Compilar milhares de aplicações, especialmente com processos automatizados e/ou autónomos, pode ser considerado um passatempo perigoso do ponto de vista da segurança. Esse é ainda mais o caso quando os produtos da compilação também são distribuídos amplamente e de forma semiautomática (“você tem atualizações disponíveis”).

Suponha que um repositório de fontes do upstream esteja comprometido. Uma pequena seleção de coisas que um invasor poderia fazer em tal situação:

  1. Usar etapas de compilação personalizadas para executar praticamente qualquer coisa como o utilizador a fazer a compilação.
  2. Acessar a keystore.
  3. Modificar os ficheiros APK compilados ou tarballs de fonte para outras aplicações no repositório.
  4. Modificar os metadados (que incluem scripts de compilação, que também incluem a capacidade de executar qualquer coisa) para outras aplicações no repositório.

Através de isolamento completo, as repercussões são, pelo menos limitadas, à aplicação em questão. O ambiente de compilação não é apenas novo para cada compilação e descartado posteriormente, mas também é totalmente isolado do ambiente de assinatura.

Além de questões de segurança, existem algumas aplicações que possuem requisitos estranhos, como versões antigas do NDK. Seria impraticável (ou pelo menos extremamente confuso) começar a modificar e restaurar o SDK num sistema com vários propósitos, mas dentro dos limites de uma máquina virtual descartável, tudo é possível.

Tudo isso é somado à vantagem óbvia de ter um ambiente padronizado e completamente reproduzível no qual as construções são feitas. Além disso, ele permite ambientes personalizados de criação personalizados para aplicações específicas.

Visão geral da configuração

Esta é a forma de configurar um servidor de compilação funcional, a partir de uma instalação Debian/estável mínima completamente limpa. Este HOWTO presume que já configurou um fdroidserver. Executar as ferramentas d o fdroidserver diretamente do git (por exemplo, ~/fdroidserver/fdroid build org.adaway), provavelmente será o mais fácil por agora, já que os scripts de configuração do servidor de compilação não estão realmente prontos para o empacotamento correto. Além disso, provavelmente funcionará apenas no Debian, Ubuntu e outros derivados do Debian, uma vez que o F-Droid só usa Debian em sua infraestrutura (nós aceitamos contribuições de portabilidade!).

O servidor base precisa de ser no mínimo Debian/trixie, ou terá de haver alguns ajustes pesados. Se correr o Ubuntu ou uma distro derivada, pode obter quaisquer pacotes em falta na sua versão, como o vagrant-cachier, a partir deste PPA: https://launchpad.net/~fdroid/+archive/ubuntu/buildserver/

Primeiro, instale os pacotes necessários e crie um utilizador para executar todo o processo aqui, por exemplo, fdroid. Estes são apenas os pacotes requeridos por todas as compilações, pode precisar instalar pacotes adicionais para compilar aplicações, por exemplo, mercurial ou subversion. Uma vez que os pacotes estejam instalados e o utilizador fdroid seja criado, nada mais neste processo deve ser executado a usar root ou sudo.

root:~# apt-get install vagrant git python3-certifi \
        python3-libvirt python3-requestbuilder python3-yaml \
        python3-progress python3-vagrant python3-paramiko python3-pyasn1 \
        python3-pyasn1-modules python3-requests python3-git
        vagrant-mutate vagrant-libvirt ebtables dnsmasq-base \
        libvirt-clients libvirt-daemon-system qemu-kvm qemu-utils
root:~# adduser --disabled-password fdroid
root:~# su fdroid

Clonar o código fonte executado como utilizador fdroid:

fdroid:~$ cd ~
fdroid:~$ git clone https://gitlab.com/fdroid/fdroidserver.git

Também tem que ter certeza de que sua variável de ambiente ANDROID_HOME esteja configurada corretamente.

Para sua conveniência, pode adicionar o executável fdroid ao seu caminho de comandos:

fdroid:~$ echo "PATH=\$PATH:$HOME/fdroidserver" >> ~/.bashrc

Obtenha todos os metadados de compilação da app do repositório fdroiddata

fdroid:~/fdroidserver$ cd ~
fdroid:~$ git clone https://gitlab.com/fdroid/fdroiddata.git
fdroid:~$ cp fdroidserver/examples/config.yml fdroiddata/
fdroid:~$ sed -i "s@^[# ]*build_server_always.*@build_server_always: true@" fdroiddata/config.yml

A configurar um servidor de compilação

Para além da configuração básica descrita anteriormente, nós enviamos uma caixa base Debian/bullseye compatível com Vagrant chamada ‘fdroid/bullseye64’.

Estamos a inicializar as caixas Debian Vagrant para nosso servidor de construção do nada. Buscar e verificar nossas caixas Vagrant pré-construídas é completamente automatizado. (Se estiver interessado neste processo ou quiser inicializá-los por si mesmo, deve olhar no: Caixas Base F-Droid)

Criar a máquina de servidor de compilação do F-Droid

Crie um arquivo de configuração para o Vagrant como ~/fdroidserver/buildserver/Vagrantfile.yaml que contém:

vm_provider = 'libvirt'

Depois a imagem base do servidor de compilação… (descarregar a basebox e todas as plataformas SDK pode demorar muito tempo).

fdroid:~$ cd fdroidserver
fdroid:~/fdroidserver$ ./makebuildserver --verbose

Isso vai demorar muito tempo, usar muita largura de banda e espaço no disco

  • a maior parte demorou a instalar as partes necessárias do SDK do Android para todas as plataformas. Felizmente, só precisa de o fazer ocasionalmente. Uma vez que tenha uma imagem de servidor de compilação funcional, se as receitas mudarem (por exemplo, quando pacotes precisam ser adicionados) pode executar o script novamente e o existente será atualizado no lugar.

Uma vez concluída, terá uma nova caixa base chamada ‘buildserver’ que é utilizada para as execuções de compilação da aplicação. Agora pode construir pacotes como costumava fazer, mas quando executa fdroid build --verbose --server ... as execuções de compilação de aplicações serão isoladas dentro de uma máquina virtual.

Embora a imagem criada tenha atribuído uma quantidade limitada de núcleos de CPU e memória, pode editar ~/fdroiddata/builder/Vagrantfile para os modificar dinamicamente em tempo de execução, por exemplo. libvirt.cpus = 6 and libvirt.memory = 12288, mas certifique-se de que não ultrapassa os limites das máquinas anfitriãs, caso contrário a VM pode ser eliminada.

A primeira vez que uma compilação é feita, uma nova máquina virtual é criada a usar a caixa ‘buildserver’ como base. Um snapshot desse estado limpo de máquina é salvo para uso em futuras construções e melhorar o desempenho. Pode forçar o descarte desse snapshot e a reconstrução do nada a usar um switch: fdroid build --resetserver ....

Ajustes do cache de makebuildserver (opcional)

Os principais downloads do SDK/NDK serão automaticamente armazenados em cache para acelerar as coisas na próxima vez, mas não há uma maneira fácil de fazer isso para as seções mais longas que usam a ferramenta android do SDK para instalar plataformas, add-ons e ferramentas. No entanto, em vez de permitir o armazenamento automático em cache, pode fornecer um diretório de cache pré-preenchido que inclui não só estes downloads, mas também ficheiros .tar.gz para todas as adições relevantes. Se os scripts de provisionamento os detectarem, eles serão usados de preferência a executar as ferramentas do Android. Por exemplo, se você tem buildserver/addons/cache/platforms/android-19.tar.gz que será usado quando instalar a plataforma android-19, ao invés de baixar novamente usando android update sdk --no-ui -t android-19. É possível criar os ficheiros de cache destas adições a partir de uma instalação local do SDK, incluindo estes:

cd /caminho/às/plataformas/android-sdk
tar czf android-19.tar.gz android-19
mv android-19.tar.gz /caminho/aos/caches/de/addons/do/buildserver/

Se já construiu um buildserver também é possível obter esses ficheiros diretamente do buildserver:

vagrant ssh -- -C 'tar -C ~/android-sdk/platforms czf android-19.tar.gz android-19'
vagrant ssh -- -C 'cat ~/android-sdk/platforms/android-19.tar.gz' > /caminho/para/fdroidserver/buildserver/cache/platforms/android19.tar.gz

Executar compilações

Ao usar o buildserver, executar fdroid diretamente de um checkout git de fdroidserver será o mais fácil. Se ainda não tem as ferramentas fdroidserver instaladas e configuradas, precisará fazê-lo em seguida: a instalar o Servidor e Ferramentas de Repo. Isso fornece todas as dependências necessárias para executar fdroidserver do git.

Agora está preparado para executar construções. Teste a construir a última versão do fdroid:

fdroid:~/fdroidserver$ cd ~/fdroiddata
fdroid:~/fdroiddata$ ~/fdroidserver/fdroid build org.fdroid.fdroid -l --server

Configurando o QEMU/KVM/libvirt

Embora o VirtualBox tenha sido usado no passado, as VMs convidadas QEMU/KVM via libvirt ainda é a configuração recomendada, pois é o que é usado pelo f-droid.org. Para tornar os ficheiros de imagem libvirt diretamente legíveis pelo vagrant package, o QEMU do libvirt precisa ser configurado para sempre definir a propriedade para libvirt.libvirt.

root:~# cat << EOF >> /etc/libvirt/qemu.conf
user = "libvirt"
group = "libvirt"
dynamic_ownership = 1
EOF
root:~# service libvirtd restart
Debian/bullseye e Ubuntu/xenial
root:~# adduser fdroid libvirt
root:~# adduser fdroid libvirt-qemu
Debian e Ubuntu mais velhos
root:~# adduser fdroid libvirtd
root:~# adduser fdroid kvm

Configuração avançada de KVM aninhada:

Esta secção não é relevante para o uso do F-Droid numa configuração normal. Se quiser executar o flag fdroid build --server dentro de um KVM, este capítulo ajudará-o a começar.

Considere a seguinte configuração básica de aninhamento:

bare metal host (l0)
\- F-Droid VM (l1)
   \- F-Droid builder VM (l2)

Os passos acima descrevem como configurar (l1) e makebuildserver configura (l2).

Primeiro de tudo, terá que verificar se sua cpu suporta o conjunto de instruções vmx (ou svm no amd). Pode usar este comando para listar detalhes sobre sua cpu:

root:~# cat /proc/cpuinfo

Em (l0) tem que verificar se o aninhamento está ativado:

root:~# cat /sys/module/kvm_intel/parameters/nested

Se não estiver ativado, pode ativá-lo a executar:

echo "options kvm-intel nested=Y" > /etc/modprobe.d/kvm-intel.conf

Terá de reiniciar o computador para que isto tenha efeito.

Em seguida, precisará certificar-se de que a sua configuração (l1) vm encaminha os recursos de cpu necessários para o agrupamento. Então abra sua configuração para a VM /etc/libvirt/qemu/my-vm.xml e insira um bloco de cpu dentro da sua etiqueta de domínio. (virt-manager também fornece uma interface de utilizador para esta operação.)

<cpu mode='custom' match='exact'>
    <model fallback='allow'>SandyBridge</model>
    <vendor>Intel</vendor>
    <feature policy='require' name='vmx'/>
</cpu>

A configuração realmente necessária aqui depende da sua cpu. Encontra detalhes em manual do libvirt. A parte importante é que encaminha vmx (ou svmm no amd) para o sistema convidado.