Como adaptar regras do Bazel para execução remota

Informar um problema Ver código-fonte

Esta página é destinada a usuários do Bazel que escrevem regras personalizadas de versão e teste e querem entender os requisitos para regras do Bazel no contexto de execução remota.

A execução remota permite que o Bazel execute ações em uma plataforma separada, como um data center. O Bazel usa um protocolo gRPC para a execução remota dele. É possível testar a execução remota com o bazel-buildfarm, um projeto de código aberto que fornece uma plataforma de execução remota distribuída.

Nesta página, usamos a seguinte terminologia ao se referir a diferentes tipos de ambientes ou plataformas:

  • Plataforma de host: onde o Bazel é executado.
  • Plataforma de execução: onde as ações do Bazel são executadas.
  • Plataforma de destino: em que as saídas de compilação (e algumas ações) são executadas.

Visão geral

Ao configurar um build do Bazel para execução remota, siga as diretrizes descritas nesta página para garantir que ele seja executado remotamente e sem erros. Isso se deve à natureza da execução remota, ou seja:

  • Ações de build isoladas. As ferramentas de compilação não mantêm o estado, e as dependências não podem vazar entre elas.

  • Ambientes de execução diversos. A configuração da versão local nem sempre é adequada para ambientes de execução remota.

Nesta página, descrevemos os problemas que podem surgir ao implementar regras personalizadas de compilação e teste do Bazel para execução remota e como evitá-las. Ele abrange os seguintes tópicos:

Como invocar ferramentas de build com regras do conjunto de ferramentas

Uma regra de conjunto de ferramentas do Bazel é uma provedora de configuração que informa quais ferramentas de compilação, como compiladores e vinculadores, vão usar e como configurá-las usando parâmetros definidos pelo criador da regra. Uma regra de conjunto de ferramentas permite que as regras de compilação e teste invoquem ferramentas de compilação de maneira previsível e pré-configurada e compatível com a execução remota. Por exemplo, use uma regra de conjunto de ferramentas em vez de invocar ferramentas de compilação usando PATH, JAVA_HOME ou outras variáveis locais que podem não estar definidas como valores equivalentes (ou iguais) no ambiente de execução remota.

Atualmente, existem regras de conjunto de ferramentas para versões de teste e criação do Bazel para Scala, Rust e Go. Novas regras do conjunto de ferramentas estão em vigor para outras linguagens e ferramentas, como bash. Se não houver uma regra de conjunto de ferramentas para a ferramenta que sua regra usa, considere criar uma regra de conjunto de ferramentas.

Como gerenciar dependências implícitas

Se uma ferramenta de compilação puder acessar dependências entre ações de compilação, essas ações falharão quando executadas remotamente, porque cada ação de compilação remota é executada separadamente das outras. Algumas ferramentas de compilação mantêm o estado em ações de compilação e dependências de acesso que não foram incluídas explicitamente na invocação da ferramenta, o que causa falha nas ações de compilação executadas remotamente.

Por exemplo, quando o Bazel instrui um compilador com estado a compilar localmente foo, ele mantém referências às saídas de compilação do foo. Quando o Bazel instrui o compilador a criar a bar, que depende de foo, sem declarar explicitamente essa dependência no arquivo BUILD para inclusão na invocação do compilador, a ação é executada com sucesso, desde que a mesma instância do compilador seja executada para ambas as ações (o que é típico para execução local). No entanto, como em um cenário de execução remota cada ação de compilação executa uma instância de compilador separada, o estado do compilador e a dependência implícita da bar em foo serão perdidas e a compilação falhará.

Para detectar e eliminar esses problemas de dependência, o Bazel 0.14.1 oferece o sandbox local do Docker, que tem as mesmas restrições de dependências que a execução remota. Use o sandbox para preparar seu build para execução remota identificando e resolvendo erros de build relacionados a dependências. Para mais informações, consulte Solução de problemas do Bazel Remote Execution com o Docker Sandbox.

Como gerenciar binários dependentes da plataforma

Normalmente, um binário criado na plataforma host não pode ser executado com segurança em uma plataforma de execução remota arbitrária devido a dependências potencialmente incompatíveis. Por exemplo, o binário SingleJar fornecido com o Bazel é direcionado à plataforma de host. No entanto, para execução remota, o SingleJar precisa ser compilado como parte do processo de criação do código para que ele segmente a plataforma de execução remota. Consulte a lógica de seleção de destino.

Não envie binários das ferramentas de compilação exigidas pelo build com seu código-fonte, a menos que você tenha certeza de que eles serão executados com segurança na plataforma de execução. Em vez disso, escolha uma destas opções:

  • Enviar ou referenciar externamente o código-fonte da ferramenta para que ele possa ser criado para a plataforma de execução remota.

  • Pré-instale a ferramenta no ambiente de execução remota (por exemplo, um contêiner de conjunto de ferramentas) se ela for estável o suficiente e use regras de conjunto de ferramentas para executá-la no seu build.

Gerenciar regras de trabalho do estilo de configuração

As regras WORKSPACE do Bazel podem ser usadas para somar a plataforma host em busca de ferramentas e bibliotecas exigidas pela versão que, para versões locais, também é a plataforma de execução do Bazel. Se o build depender explicitamente de artefatos e ferramentas de build locais, ele falhará durante a execução remota se a plataforma de execução remota não for idêntica à plataforma host.

As ações a seguir realizadas por regras WORKSPACE não são compatíveis com a execução remota:

  • Criação de binários A execução de ações de compilação nas regras WORKSPACE resulta em binários incompatíveis com a plataforma de execução remota se for diferente da plataforma host.

  • Instalando pacotes pip. Os pacotes pip instalados por regras WORKSPACE precisam que as dependências sejam pré-instaladas na plataforma host. Esses pacotes, criados especificamente para a plataforma host, serão incompatíveis com a plataforma de execução remota se forem diferentes da plataforma host.

  • Link direto para ferramentas ou artefatos locais. Os links simbólicos para ferramentas ou bibliotecas instalados na plataforma host criada por regras WORKSPACE farão com que a versão falhe na plataforma de execução remota, já que o Bazel não poderá localizá-los. Em vez disso, crie links simbólicos usando ações de compilação padrão para que as ferramentas e bibliotecas vinculadas possam ser acessadas na árvore runfiles do Bazel. Não use repository_ctx.symlink para vincular links de arquivo fora do diretório externo do repositório.

  • Mitigar a plataforma host Evite criar arquivos fora da árvore runfiles do Bazel, criando variáveis de ambiente e ações semelhantes, porque eles podem se comportar de forma inesperada na plataforma de execução remota.

Para encontrar possíveis comportamentos não herméticos, use o registro de regras do Workspace.

Se uma dependência externa executar operações específicas dependentes da plataforma host, divida essas operações entre WORKSPACE e regras de build da seguinte maneira:

  • Inspeção de plataforma e enumeração de dependências Essas operações são seguras para execução local usando regras WORKSPACE, que podem verificar quais bibliotecas estão instaladas, fazer o download de pacotes que precisam ser criados e preparar os artefatos necessários para compilação. Para a execução remota, essas regras também precisam ser compatíveis com o uso de artefatos pré-marcados para fornecer as informações que normalmente seriam recebidas durante a inspeção da plataforma host. Os artefatos pré-marcados permitem que o Bazel descreva dependências como se fossem locais. Para isso, use instruções condicionais ou a sinalização --override_repository.

  • Gerar ou compilar artefatos específicos de destino e mutação da plataforma. Essas operações precisam ser executadas usando regras de build regulares. As ações que produzem artefatos específicos de destino para dependências externas precisam ser executadas durante a criação.

Para gerar artefatos pré-marcados com mais facilidade para execução remota, use regras WORKSPACE para emitir arquivos gerados. Você pode executar essas regras em cada novo ambiente de execução, como dentro de cada contêiner de conjunto de ferramentas, e verificar as saídas do build remoto no seu repositório de origem para referência.

Por exemplo, para as regras do Tensorflow para cuda e python, as regras WORKSPACE produzem as seguintes BUILD files. Para execução local, são usados arquivos produzidos pela verificação do ambiente do host. Para uma execução remota, uma declaração condicional em uma variável de ambiente permite que a regra use arquivos verificados no repositório.

Os arquivos BUILD declaram genrules que podem ser executados local e remotamente e executam o processamento necessário que foi feito anteriormente usando repository_ctx.symlink, como mostrado aqui.