Las compilaciones de Bazel que tienen éxito de manera local pueden fallar cuando se ejecutan de forma remota debido a restricciones y requisitos que no afectan a las compilaciones locales. Las causas más comunes de estas fallas se describen en Adapta las reglas de Bazel para la ejecución remota.
En esta página, se describe cómo identificar y resolver los problemas más comunes que surgieron con la ejecución remota mediante la característica de zona de pruebas de Docker, que impone restricciones en la compilación iguales a las de la ejecución remota. Esto te permite solucionar problemas de tu compilación sin la necesidad de usar un servicio de ejecución remota.
La función de zona de pruebas de Docker imita las restricciones de la ejecución remota de la siguiente manera:
Las acciones de compilación se ejecutan en contenedores de la cadena de herramientas. Puedes usar los mismos contenedores de la cadena de herramientas para ejecutar tu compilación de forma local y remota mediante un servicio que admita la ejecución remota en contenedores.
Ningún dato ajeno cruza el límite del contenedor. Solo las entradas y salidas declaradas de forma explícita ingresan y salen del contenedor, y solo después de que la acción de compilación asociada se completa con éxito.
Cada acción se ejecuta en un contenedor nuevo. Se crea un contenedor único y nuevo para cada acción de compilación generada.
Puedes solucionar estos problemas mediante uno de los siguientes métodos:
Solución de problemas de forma nativa. Con este método, Bazel y sus acciones de compilación se ejecutan de forma nativa en tu máquina local. La función de zona de pruebas de Docker impone restricciones en la compilación iguales a las de la ejecución remota. Sin embargo, este método no detectará herramientas, estados ni datos locales que se filtren a tu compilación, lo que causará problemas con la ejecución remota.
Solución de problemas en un contenedor de Docker. Con este método, Bazel y sus acciones de compilación se ejecutan dentro de un contenedor de Docker, lo que te permite detectar herramientas, estados y datos que se filtran desde la máquina local a la compilación, además de imponer restricciones equivalentes a las de la ejecución remota. Este método proporciona estadísticas sobre tu compilación incluso si fallan partes de ella. Este método es experimental y no se admite oficialmente.
Requisitos previos
Antes de comenzar a solucionar problemas, haz lo siguiente si aún no lo hiciste:
- Instala Docker y configura los permisos necesarios para ejecutarlo.
- Instala Bazel 0.14.1 o una versión posterior. Las versiones anteriores no admiten la función de zona de pruebas de Docker.
- Agrega el repositorio bazel-toolchains, fijado en la versión más reciente del archivo, al archivo
WORKSPACE
de la compilación, como se describe aquí. - Agrega marcas a tu archivo
.bazelrc
para habilitar la función. Crea el archivo en el directorio raíz de tu proyecto de Bazel si no existe. Las marcas a continuación son una muestra de referencia. Consulta el archivo.bazelrc
más reciente en el repositorio de bazel-toolchains y copia los valores de las marcas definidas aquí para la configuracióndocker-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
Si tus reglas requieren herramientas adicionales, haz lo siguiente:
Crea un contenedor personalizado de Docker mediante la instalación de herramientas con un Dockerfile y la compilación de la imagen de forma local.
Reemplaza el valor de la marca
--experimental_docker_image
anterior por el nombre de tu imagen de contenedor personalizada.
Solución de problemas de forma nativa
Este método ejecuta Bazel y todas sus acciones de compilación directamente en la máquina local y es una forma confiable de confirmar si tu compilación tendrá éxito cuando se ejecute de forma remota.
Sin embargo, con este método, las herramientas instaladas de manera local, los objetos binarios y los datos pueden filtrarse en tu compilación, en especial si usa reglas de estilo de trabajo de configuración. Estas filtraciones causarán problemas con la ejecución remota. Para detectarlas, soluciona los problemas en un contenedor de Docker, además de solucionar los problemas de forma nativa.
Paso 1: Ejecuta la compilación
Agrega la marca
--config=docker-sandbox
al comando de Bazel que ejecuta tu compilación. Por ejemplo:bazel --bazelrc=.bazelrc build --config=docker-sandbox target
Ejecuta la compilación y espera a que se complete. La compilación se ejecutará hasta cuatro veces más de lo normal debido a la función de zona de pruebas de Docker.
Es posible que encuentres el siguiente error:
ERROR: 'docker' is an invalid value for docker spawn strategy.
Si lo haces, vuelve a ejecutar la compilación con la marca --experimental_docker_verbose
.
Esta marca habilita los mensajes de error detallados. Por lo general, este error se debe a una instalación con errores de Docker o a la falta de permisos para ejecutarla en la cuenta de usuario actual. Consulta la documentación de Docker para obtener más información. Si los problemas persisten, continúe con la solución de problemas en un contenedor de Docker.
Paso 2: Resuelva los problemas detectados
A continuación, se incluyen los problemas más comunes y sus soluciones alternativas.
Falta un archivo, una herramienta, un objeto binario o un recurso al que hace referencia el árbol de runfiles de Bazel. Confirma que todas las dependencias de los destinos afectados se hayan declarado de forma explícita. Consulta Administra dependencias implícitas para obtener más información.
Falta un archivo, una herramienta, un objeto binario o un recurso al que hace referencia una ruta de acceso absoluta o la variable
PATH
. Confirma que todas las herramientas necesarias estén instaladas dentro del contenedor de la cadena de herramientas y usa las reglas de la cadena de herramientas para declarar de forma correcta las dependencias que apuntan al recurso faltante. Consulta Invoca herramientas de compilación a través de reglas de la cadena de herramientas para obtener más información.Una ejecución binaria falla. Una de las reglas de compilación hace referencia a un objeto binario que no es compatible con el entorno de ejecución (el contenedor de Docker). Consulta Administra objetos binarios dependientes de la plataforma para obtener más información. Si no puedes resolver el problema, comunícate con bazel-discuss@google.com para obtener ayuda.
Falta un archivo de
@local-jdk
o está causando errores. Los objetos binarios de Java en tu máquina local se filtran en la compilación y no son compatibles con ella. Usajava_toolchain
en tus reglas y destinos en lugar de@local_jdk
. Comunícate con bazel-discuss@google.com si necesitas más ayuda.Otros errores. Comunícate con bazel-discuss@google.com para obtener ayuda.
Soluciona problemas en un contenedor de Docker
Con este método, Bazel se ejecuta dentro de un contenedor de Docker del host, y las acciones de compilación de Bazel se ejecutan dentro de contenedores de cadenas de herramientas individuales que genera la función de zona de pruebas de Docker. La zona de pruebas genera un contenedor nuevo de la cadena de herramientas para cada acción de compilación y solo se ejecuta una acción en cada contenedor de la cadena de herramientas.
Este método proporciona un control más detallado de las herramientas instaladas en el entorno de host. Puedes separar la ejecución de la compilación de las acciones de compilación y mantener las herramientas instaladas al mínimo para verificar si la compilación tiene alguna dependencia en el entorno de ejecución local.
Paso 1: Compila el contenedor
Crea un
Dockerfile
que cree el contenedor de Docker y, luego, instale Bazel con un conjunto mínimo de herramientas de compilación: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
Compila el contenedor como
bazel_container
:docker build -t bazel_container - < Dockerfile
Paso 2: Inicia el contenedor
Inicia el contenedor de Docker con el comando que se muestra a continuación. En el comando, sustituye la ruta de acceso al código fuente de tu host que desees compilar.
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
Este comando ejecuta el contenedor como raíz, asigna el socket de Docker y activa el directorio /tmp
. Esto permite que Bazel genere otros contenedores de Docker y que use directorios en /tmp
para compartir archivos con esos contenedores. Tu código fuente está disponible en /src
dentro del contenedor.
El comando se inicia de forma intencional desde un contenedor base debian:stretch
que
incluye objetos binarios incompatibles con el contenedor rbe-ubuntu16-04
que se usa como
contenedor de la cadena de herramientas. Si los objetos binarios del entorno local tienen fugas en el
contenedor de la cadena de herramientas, causarán errores de compilación.
Paso 3: Prueba el contenedor
Ejecute los siguientes comandos desde el contenedor de Docker para probarlo:
docker ps
bazel version
Paso 4: Ejecuta la compilación
Ejecuta la compilación como se muestra a continuación. El usuario de salida es raíz, de modo que corresponde a un directorio al que se puede acceder con la misma ruta de acceso absoluta desde el contenedor del host en el que se ejecuta Bazel, desde los contenedores de la cadena de herramientas que genera la función de zona de pruebas de Docker en la que se ejecutan las acciones de compilación de Bazel, y desde la máquina local en la que se ejecutan los contenedores de host y de acción.
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
Paso 5: Resuelva los problemas detectados
Puedes resolver las fallas de compilación de la siguiente manera:
Si la compilación falla con un error de “sin espacio en el disco”, puedes aumentar este límite si inicias el contenedor del host con la marca
--memory=XX
, en la queXX
es el espacio en disco asignado en gigabytes. Esto es experimental y puede dar como resultado un comportamiento impredecible.Si la compilación falla durante las fases de análisis o carga, una o más de las reglas de compilación declaradas en el archivo WORKSPACE no son compatibles con la ejecución remota. Consulta Adapta las reglas de Bazel para la ejecución remota a fin de conocer las posibles causas y soluciones.
Si, por algún otro motivo, la compilación falla, consulta los pasos para solucionar problemas en el Paso 2: Resuelve los problemas detectados.