Como adaptar regras do Bazel para execução remota

Esta página é destinada a usuários do Bazel que escrevem regras de build e teste personalizadas e querem entender os requisitos das regras do Bazel no contexto da 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. Você pode testar a execução remota com bazel-buildfarm, um projeto de código aberto que visa fornecer uma plataforma de execução remota distribuída.

Esta página usa a seguinte terminologia 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 um build do Bazel para execução remota, siga as diretrizes descritas nesta página para garantir que o build seja executado remotamente sem erros. Isso ocorre devido à 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.

Esta página descreve os problemas que podem surgir ao implementar regras de build e teste personalizadas do Bazel para execução remota e como evitá-los. Ela 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, usar e como configurá-las usando parâmetros definidos pelo criador da regra. Uma regra de conjunto de ferramentas permite que as regras de build e teste invoquem ferramentas de build de maneira previsível e pré-configurada que seja compatível com a execução remota. Por exemplo, use uma regra de conjunto de ferramentas em vez de invocar ferramentas de build usando PATH, JAVA_HOME ou outras variáveis locais que podem não estar definidas para valores equivalentes (ou não estar definidas) 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, e novas regras de conjunto de ferramentas estão em andamento para outras linguagens e ferramentas, como bash. Se uma regra de conjunto de ferramentas não existir para a ferramenta usada pela sua regra, considere criar 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 de outras. Algumas ferramentas de build retêm o estado em ações de build e acessam dependências que não foram incluídas explicitamente na invocação da ferramenta, o que fará com que as ações de build executadas remotamente falhem.

Por exemplo, quando o Bazel instrui um compilador com estado a criar foo localmente, o compilador retém referências às saídas de build do foo. Quando o Bazel então 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 será executada com êxito, desde que a mesma instância do compilador seja executada para ambas as ações (como é típico para execução local). No entanto, como em um cenário de execução remota cada ação de build executa uma instância de compilador separada, o estado do compilador e a dependência implícita de bar's em foo serão perdidos, e o build 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 a dependências. Consulte Solução de problemas de execução remota do Bazel com o Docker Sandbox para mais informações.

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 tem como destino a plataforma 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 tenha como destino a 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 o 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, faça uma destas ações:

  • Envie ou referencie 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 build.

Como gerenciar regras de WORKSPACE de estilo de configuração

As regras WORKSPACE do Bazel podem ser usadas para testar a plataforma host em busca de ferramentas e bibliotecas exigidas pelo build, que, para builds locais, também é a plataforma de execução do Bazel. Se o build depender explicitamente de ferramentas e artefatos 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 seguintes ações realizadas pelas regras WORKSPACE não são compatíveis com a execução remota:

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

  • Como instalar pacotes pip. Os pacotes pip instalados usando regras WORKSPACE exigem 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 ela for diferente da plataforma host.

  • Como criar links simbólicos para ferramentas ou artefatos locais. Os links simbólicos para ferramentas ou bibliotecas instaladas na plataforma host criados usando regras WORKSPACE farão com que o build falhe na plataforma de execução remota, já que o Bazel não poderá encontrá-los. Em vez disso, crie links simbólicos usando ações de build padrão para que as ferramentas e bibliotecas vinculadas sejam acessíveis na árvore runfiles do Bazel. Não use repository_ctx.symlink para vincular arquivos de destino fora do diretório do repositório externo.

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

Para ajudar a 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 da plataforma e enumeração de dependências. Essas operações podem ser executadas localmente 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 a compilação. Para execução remota, essas regras também precisam oferecer suporte ao uso de artefatos pré-verificados para fornecer as informações que normalmente seriam obtidas durante a inspeção da plataforma host. Os artefatos pré-verificados permitem que o Bazel descreva as dependências como se fossem locais. Use instruções condicionais ou a flag --override_repository para isso.

  • Como gerar ou compilar artefatos específicos do destino e mutação da plataforma. Essas operações precisam ser executadas usando regras de build normais. As ações que produzem artefatos específicos do 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. 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 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 os seguintes BUILD files. Para execução local, os arquivos produzidos pela verificação do ambiente host são usados. Para execução remota, uma instrução condicional em uma variável de ambiente permite que a regra use arquivos que são verificados no repositório.

Os BUILD arquivos declaram genrules que podem ser executados localmente e remotamente e realizam o processamento necessário que era feito anteriormente usando repository_ctx.symlink, conforme mostrado aqui.