Como adaptar regras do Bazel para execução remota

Esta página é destinada a usuários do Bazel que escrevem regras personalizadas de compilação e teste que querem entender os requisitos delas 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. Tente a execução remota com o bazel-buildfarm, um projeto de código aberto que tem o objetivo de fornecer uma plataforma de execução remota distribuída.

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

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

Visão geral

Ao configurar uma compilação do Bazel para execução remota, siga as diretrizes descritas nesta página para garantir que ela seja executada remotamente sem erros. Isso se deve à natureza da execução remota, ou seja:

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

  • Ambientes de execução diversos. A configuração do build 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 aborda os seguintes tópicos:

Como invocar ferramentas de build usando regras de conjunto de ferramentas

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

Atualmente, existem regras de conjunto de ferramentas para regras de build e teste do Bazel para Scala, Rust e Go. Novas regras de conjunto de ferramentas estão em andamento para outras linguagens e ferramentas, como bash. Se não houver uma regra de conjunto de ferramentas para a ferramenta usada pela regra, crie uma regra de conjunto de ferramentas.

Como gerenciar dependências implícitas

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

Por exemplo, quando o Bazel instrui um compilador com estado a criar foo localmente, o compilador retém as referências às saídas de build de foo. Quando o Bazel instrui o compilador a criar 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 êxito, desde que a mesma instância do compilador seja executada para as duas ações (como é comum 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 de bar em foo serão perdidos e a compilação falhará.

Para ajudar a 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 para 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 à dependência. Consulte Como solucionar problemas de execução remota do Bazel com o sandbox do Docker para mais informações.

Como gerenciar binários dependentes da plataforma

Normalmente, um binário criado na plataforma de 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 tem como alvo a plataforma do 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 seja destinado à plataforma de execução remota. Consulte a lógica de seleção de destino.

Não envie binários de ferramentas de build 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, siga um destes procedimentos:

  • Enviar ou referenciar externamente o código-fonte da ferramenta para que ela possa ser criada 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 na compilação.

Como gerenciar regras do espaço de trabalho de estilo de configuração

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

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

  • Criação de binários Executar ações de compilação em 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 exigem que as dependências sejam pré-instaladas na plataforma host. Esses pacotes, criados especificamente para a plataforma de host, serão incompatíveis com a plataforma de execução remota se forem diferentes da plataforma host.

  • Links simbólicos para ferramentas ou artefatos locais. Links simbólicos para ferramentas ou bibliotecas instaladas na plataforma de host criadas usando regras WORKSPACE vão causar falha no build na plataforma de execução remota, já que o Bazel não vai conseguir localizá-los. Em vez disso, crie links simbólicos usando ações de build padrão para que as ferramentas e bibliotecas com links simbólicos possam ser acessadas pela árvore runfiles do Bazel. Não use repository_ctx.symlink para vincular arquivos de destino a arquivos de destino fora do diretório do repositório externo.

  • Como mudar a plataforma de host. Evite criar arquivos fora da árvore runfiles do Bazel, criar variáveis de ambiente e ações semelhantes, porque eles podem se comportar inesperadamente 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é-verificados para fornecer as informações que normalmente seriam recebidas durante a inspeção da plataforma do host. Os artefatos pré-verificados 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 do destino e mutação da plataforma. Essas operações precisam ser executadas por regras de build regulares. As ações que produzem artefatos específicos de destino para dependências externas precisam ser executadas durante o build.

Para gerar artefatos pré-verificados com mais facilidade para execução remota, use regras WORKSPACE para emitir arquivos gerados. É possível 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 da compilação de execução remota no repositório de origem para referência.

Por exemplo, para as regras do TensorFlow para cuda e python, as regras WORKSPACE produzem o seguinte BUILD files. Para execução local, são usados os arquivos produzidos pela verificação do ambiente do host. Para a execução remota, uma instrução condicional em uma variável de ambiente permite que a regra use arquivos que foram verificados no repo.

Os arquivos BUILD declaram genrules, que pode ser executado local e remotamente e que realiza o processamento necessário que era feito anteriormente por repository_ctx.symlink, como mostrado aqui.