As compilações do Bazel bem-sucedidas no local podem falhar quando executadas remotamente devido a restrições e requisitos que não afetam as versões locais. As causas mais comuns dessas falhas são descritas em Como adaptar regras do Bazel para execução remota.
Esta página descreve como identificar e resolver os problemas mais comuns que surgem com a execução remota usando o recurso de sandbox do Docker, que impõe restrições ao build iguais às da execução remota. Isso permite que você resolva problemas do build sem precisar de um serviço de execução remota.
O recurso de sandbox do Docker imita as restrições da execução remota da seguinte maneira:
As ações de build são executadas em contêineres do conjunto de ferramentas. É possível usar os mesmos contêineres de conjunto de ferramentas para executar o build local e remotamente usando um serviço que ofereça suporte à execução remota em contêineres.
Nenhum dado externo cruza os limites do contêiner. Somente entradas e saídas declaradas explicitamente entram e saem do contêiner e somente após a conclusão bem-sucedida da ação de compilação associada.
Cada ação é executada em um novo contêiner. Um contêiner novo e exclusivo é criado para cada ação de compilação gerada.
É possível resolver esses problemas usando um dos seguintes métodos:
Solução de problemas nativa. Com esse método, o Bazel e as ações de compilação dele são executados nativamente na máquina local. O recurso de sandbox do Docker impõe restrições ao build iguais às da execução remota. No entanto, esse método não detectará ferramentas, estados e dados locais com vazamento para o build, o que causará problemas na execução remota.
Como solucionar problemas em um contêiner do Docker. Com esse método, o Bazel e as ações de build são executados em um contêiner do Docker, o que permite detectar ferramentas, estados e dados que vazam da máquina local para o build, além de impor restrições iguais às da execução remota. Esse método fornece insights sobre o build, mesmo que partes dele estejam com falhas. Esse método é experimental e não tem suporte oficial.
Pré-requisitos
Antes de iniciar a solução de problemas, faça o seguinte se ainda não tiver feito isso:
- Instale o Docker e configure as permissões necessárias para executá-lo.
- Instale o Bazel 0.14.1 ou mais recente. As versões anteriores não são compatíveis com o recurso de sandbox do Docker.
- Adicione o repositório bazel-Datasets, fixado na versão de lançamento mais recente, ao arquivo
WORKSPACE
do seu build, conforme descrito neste link. - Adicione sinalizações ao arquivo
.bazelrc
para ativar o recurso. Crie o arquivo no diretório raiz do projeto do Bazel, se ele não existir. As flags abaixo são um exemplo de referência. Consulte o arquivo.bazelrc
mais recente no repositório bazel-Datasets e copie os valores das flags definidas para a configuraçãodocker-sandbox
.
# Docker Sandbox Mode
build:docker-sandbox --host_javabase=<...>
build:docker-sandbox --javabase=<...>
build:docker-sandbox --crosstool_top=<...>
build:docker-sandbox --experimental_docker_image=<...>
build:docker-sandbox --spawn_strategy=docker --strategy=Javac=docker --genrule_strategy=docker
build:docker-sandbox --define=EXECUTOR=remote
build:docker-sandbox --experimental_docker_verbose
build:docker-sandbox --experimental_enable_docker_sandbox
Se as regras exigirem ferramentas adicionais, faça o seguinte:
Crie um contêiner do Docker personalizado instalando ferramentas usando um Dockerfile e criando a imagem localmente.
Substitua o valor da flag
--experimental_docker_image
acima pelo nome da imagem de contêiner personalizada.
Solução de problemas nativa
Esse método executa o Bazel e todas as ações de build diretamente na máquina local e é uma maneira confiável de confirmar se o build vai ser bem-sucedido quando executado remotamente.
No entanto, com esse método, ferramentas, binários e dados instalados localmente podem vazar para seu build, especialmente se ele usar regras de ESPAÇO DE TRABALHO de estilo de configuração. Esses vazamentos causam problemas na execução remota. Para detectá-los, resolva os problemas em um contêiner do Docker, além de solucionar problemas de maneira nativa.
Etapa 1: executar o build
Adicione a sinalização
--config=docker-sandbox
ao comando do Bazel que executa sua compilação. Exemplo:bazel --bazelrc=.bazelrc build --config=docker-sandbox target
Execute o build e aguarde a conclusão. A compilação será executada até quatro vezes mais devagar que o normal devido ao recurso de sandbox do Docker.
Talvez você encontre o seguinte erro:
ERROR: 'docker' is an invalid value for docker spawn strategy.
Se isso acontecer, execute o build novamente com a flag --experimental_docker_verbose
.
Essa sinalização permite mensagens de erro detalhadas. Esse erro geralmente é causado por uma
instalação incorreta do Docker ou pela falta de permissões para executá-lo na
conta de usuário atual. Consulte a documentação do Docker para mais informações. Se os problemas persistirem, avance para Como solucionar problemas em um contêiner do Docker.
Etapa 2: resolver os problemas detectados
Confira a seguir os problemas mais comuns e as soluções alternativas.
Um arquivo, ferramenta, binário ou recurso referenciado pela árvore de arquivos de execução do Bazel está ausente. Confirme se todas as dependências dos destinos afetados foram declaradas explicitamente. Consulte Como gerenciar dependências implícitas para mais informações.
Um arquivo, ferramenta, binário ou recurso referenciado por um caminho absoluto ou a variável
PATH
está ausente. Confirme se todas as ferramentas necessárias estão instaladas no contêiner do conjunto de ferramentas e use as regras do conjunto para declarar corretamente as dependências que apontam para o recurso ausente. Consulte Como invocar ferramentas de build por meio de regras de conjunto de ferramentas para ver mais informações.Uma execução binária falha. Uma das regras de build faz referência a um binário incompatível com o ambiente de execução (o contêiner do Docker). Consulte Gerenciar binários dependentes de plataforma para mais informações. Se você não conseguir resolver o problema, entre em contato com bazel-discuss@google.com para receber ajuda.
Um arquivo de
@local-jdk
está ausente ou causando erros. Os binários Java na máquina local estão vazando para o build, sendo incompatíveis com ele. Usejava_toolchain
nas regras e metas em vez de@local_jdk
. Entre em contato com bazel-discuss@google.com se precisar de mais ajuda.Outros erros. Entre em contato com bazel-discuss@google.com para receber ajuda.
Solução de problemas em um contêiner do Docker
Com esse método, o Bazel é executado em um contêiner do Docker host, e as ações de build do Bazel são executadas em contêineres de toolchain individuais gerados pelo recurso de sandbox do Docker. O sandbox gera um novo contêiner de conjunto de ferramentas para cada ação de compilação e apenas uma ação é executada em cada contêiner de conjunto de ferramentas.
Esse método oferece um controle mais granular das ferramentas instaladas no ambiente do host. Ao separar a execução do build da execução das ações de build e manter o mínimo de ferramentas instaladas, é possível verificar se o build tem dependências no ambiente de execução local.
Etapa 1: criar o contêiner
Crie um
Dockerfile
que crie o contêiner do Docker e instale o Bazel com um conjunto mínimo de ferramentas de build:FROM debian:stretch RUN apt-get update && apt-get install -y apt-transport-https curl software-properties-common git gcc gnupg2 g++ openjdk-8-jdk-headless python-dev zip wget vim RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" RUN apt-get update && apt-get install -y docker-ce RUN wget https://releases.bazel.build/<latest Bazel version>/release/bazel-<latest Bazel version>-installer-linux-x86_64.sh -O ./bazel-installer.sh && chmod 755 ./bazel-installer.sh RUN ./bazel-installer.sh
Crie o contêiner como
bazel_container
:docker build -t bazel_container - < Dockerfile
Etapa 2: iniciar o contêiner
Inicie o contêiner do Docker usando o comando mostrado abaixo. No comando, substitua o caminho para o código-fonte no host que você quer criar.
docker run -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /tmp:/tmp \
-v your source code directory:/src \
-w /src \
bazel_container \
/bin/bash
Esse comando executa o contêiner como raiz, mapeando o soquete do Docker e ativando o diretório /tmp
. Isso permite que o Bazel gere outros contêineres do Docker e
use diretórios em /tmp
para compartilhar arquivos com esses contêineres. O código-fonte
está disponível em /src
dentro do contêiner.
O comando começa intencionalmente de um contêiner base debian:stretch
que
inclui binários incompatíveis com o contêiner rbe-ubuntu16-04
usado como um
contêiner de conjunto de ferramentas. Se os binários do ambiente local estiverem vazando para o
contêiner do conjunto de ferramentas, eles vão causar erros de build.
Etapa 3: testar o contêiner
Execute os seguintes comandos no contêiner do Docker para testá-lo:
docker ps
bazel version
Etapa 4: executar o build
Execute o build conforme mostrado abaixo. O usuário de saída é raiz para corresponder a um diretório acessível com o mesmo caminho absoluto dentro do contêiner host em que o Bazel é executado, dos contêineres do conjunto de ferramentas gerados pelo recurso de sandbox do Docker em que as ações de build do Bazel estão sendo executadas e da máquina local em que os contêineres host e de ação são executados.
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
Etapa 5: resolver os problemas detectados
É possível resolver falhas de build da seguinte maneira:
Se o build falhar com um erro de "sem espaço em disco", você poderá aumentar esse limite iniciando o contêiner host com a flag
--memory=XX
, em queXX
é o espaço em disco alocado em gigabytes. Isso é experimental e pode resultar em um comportamento imprevisível.Se o build falhar durante as fases de análise ou carregamento, uma ou mais regras de build declaradas no arquivo WORKSPACE não serão compatíveis com a execução remota. Consulte Como adaptar regras do Bazel para execução remota para possíveis causas e soluções alternativas.
Se o build falhar por qualquer outro motivo, consulte as etapas de solução de problemas em Etapa 2: resolver os problemas detectados.