Como adaptar regras do Bazel para execução remota

Informar um problema Ver fonte Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

Nesta página, usamos a seguinte terminologia ao nos referirmos 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 de destino: onde as saídas de build (e algumas ações) são executadas.

Visão geral

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

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

  • Diversos ambientes de execução. A configuração de 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 build e teste do Bazel para execução remota e como evitá-los. Ele aborda os seguintes tópicos:

Como invocar ferramentas de build usando regras de conjunto de ferramentas

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

Atualmente, existem regras de cadeia de ferramentas para regras de build e teste do Bazel para Scala, Rust e Go. Novas regras de cadeia de ferramentas estão sendo desenvolvidas para outras linguagens e ferramentas, como bash. Se não houver uma regra de cadeia de ferramentas para a ferramenta usada na sua regra, considere criar uma regra de cadeia de ferramentas.

Gerenciar dependências implícitas

Se uma ferramenta de build puder acessar dependências em ações de build, essas ações vão falhar quando executadas remotamente, porque cada ação de build remota é executada separadamente das 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 causa 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 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 sucesso desde que a mesma instância do compilador seja executada para ambas as ações (como é típico da execução local). No entanto, como em um cenário de execução remota cada ação de build executa uma instância separada do compilador, o estado do compilador e a dependência implícita de bar em foo serão perdidos, e o build vai 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 sua build para execução remota identificando e resolvendo erros de build relacionados a dependências. Consulte Solução de problemas da execução remota do Bazel com o sandbox do Docker para mais informações.

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 seja direcionado à plataforma de execução remota. Consulte a lógica de seleção de destino.

Não envie binários de ferramentas de build necessárias para seu build com o código-fonte a menos que você tenha certeza de que eles serão executados com segurança na sua plataforma de execução. Em vez disso, faça uma das seguintes ações:

  • Envie ou faça referência externa ao 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 cadeia de ferramentas) se ela for estável o suficiente e use regras de cadeia de ferramentas para executá-la no seu build.

Gerenciar regras do WORKSPACE configure-style

As regras WORKSPACE do Bazel podem ser usadas para sondar a plataforma host em busca de ferramentas e bibliotecas necessárias para a build, que, para builds locais, também é a plataforma de execução do Bazel. Se a build depender explicitamente de ferramentas e artefatos de build local, ela vai 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:

  • 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 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 host, serão incompatíveis com a plataforma de execução remota se forem diferentes da plataforma host.

  • Criação de links simbólicos para ferramentas ou artefatos locais. Links simbólicos para ferramentas ou bibliotecas instaladas na plataforma host criadas com regras WORKSPACE vão fazer com que o build falhe na plataforma de execução remota porque 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 vinculadas por link simbólico sejam acessíveis na árvore runfiles do Bazel. Não use repository_ctx.symlink para criar links simbólicos de arquivos de destino fora do diretório do repositório externo.

  • Mutação da 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 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 crie regras da seguinte maneira:

  • Inspeção de plataforma e enumeração de dependências. Essas operações podem ser executadas com segurança localmente usando regras WORKSPACE, que podem verificar quais bibliotecas estão instaladas, baixar 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.

  • Gerar ou compilar artefatos específicos do 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 do destino para dependências externas precisam ser executadas durante a build.

Para gerar mais facilmente artefatos pré-verificados 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 cadeia 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 o seguinte BUILD files. Para execução local, são usados 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 verificados no repositório.

Os arquivos BUILD declaram genrules que podem ser executados localmente e remotamente, além de realizar o processamento necessário que antes era feito via repository_ctx.symlink, conforme mostrado aqui.