Como adaptar regras do Bazel para execução remota

Reportar um problema Ver código-fonte Nightly · 8.0 . 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Esta página é destinada a usuários do Bazel que escrevem regras de build e teste personalizadas 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 execução remota. Você pode testar a execução remota com o bazel-buildfarm, um projeto de código aberto que tem como objetivo 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 de destino: 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 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.

  • Diversos ambientes de execução. A configuração de 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 do Bazel personalizadas 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 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 toolchain permite que regras de build e de teste invoquem ferramentas de build de uma maneira previsível e pré-configurada que seja compatível com a execução remota. Por exemplo, use uma regra de toolchain em vez de invocar ferramentas de build usando PATH, JAVA_HOME ou outras variáveis locais que podem não ser definidas como valores equivalentes (ou nem mesmo) no ambiente de execução remota.

Atualmente, existem regras de conjunto de ferramentas para regras de criação 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 toolchain não existir para a ferramenta usada pela sua regra, crie uma regra de toolchain.

Gerenciamento de 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 todas as ações de build e acessam dependências que não foram incluídas explicitamente na invocação da ferramenta, o que faz com que as ações de build executadas remotamente falhem.

Por exemplo, quando o Bazel instrui um compilador com estado a criar localmente foo, o compilador mantém as referências às saídas de build de foo. Quando o Bazel instruí o compilador a criar bar, que depende de foo, sem explicitar essa dependência no arquivo BUILD para inclusão na chamada 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 para a 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 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 de dependências que a execução remota. Use o sandbox para preparar o 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 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 é direcionado à plataforma de destino. No entanto, para a 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 exigidos pelo build com seu código-fonte, a menos que tenha certeza de que eles serão executados com segurança na 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 conjunto de ferramentas) se ela for estável o suficiente e use as regras do conjunto de ferramentas para executá-la no build.

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

As regras WORKSPACE do Bazel podem ser usadas para detectar ferramentas e bibliotecas exigidas pelo build na plataforma host, 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 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 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 for diferente da plataforma host.

  • Instalação de pacotes pip. Os pacotes pip instalados com regras WORKSPACE exigem que as dependências sejam pré-instaladas na plataforma de destino. 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.

  • Criar links simbólicos para ferramentas ou artefatos locais. Os links simbólicos para ferramentas ou bibliotecas instaladas na plataforma host criada com regras WORKSPACE farão 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 com links simbólicos 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 de destino. Evite criar arquivos fora da árvore runfiles do Bazel, criar variáveis de ambiente e ações semelhantes, porque elas 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 que dependem da plataforma host, divida essas operações entre WORKSPACE e crie regras da seguinte maneira:

  • Inspeção da 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 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. Artefatos pré-marcados permitem que o Bazel descreva dependências como se fossem locais. Para isso, use instruções condicionais ou a flag --override_repository.

  • Gerar ou compilar artefatos específicos da segmentação 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 para execução remota com mais facilidade, 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 toolchain, 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 os arquivos produzidos pela verificação do ambiente do host. Para execução remota, uma expressã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 realizar o processamento necessário que antes era feito por repository_ctx.symlink, conforme mostrado aqui.