Adapta reglas de Bazel para la ejecución remota

Informar un problema Ver fuente

Esta página está destinada a usuarios de Bazel que escriben reglas de compilación y prueba personalizadas que desean comprender los requisitos de las reglas de Bazel en el contexto de ejecución remota.

La ejecución remota permite que Bazel ejecute acciones en una plataforma independiente, como un centro de datos. Bazel usa un protocolo de gRPC para su ejecución remota. Puedes probar la ejecución remota con bazel-buildfarm, un proyecto de código abierto que tiene como objetivo proporcionar una plataforma de ejecución remota distribuida.

En esta página, se usa la siguiente terminología para referirse a diferentes tipos de entornos o plataformas:

  • Plataforma de host: Es la plataforma en la que se ejecuta Bazel.
  • Plataforma de ejecución: donde se ejecutan las acciones de Bazel
  • Plataforma de destino: donde se ejecutan los resultados de la compilación (y algunas acciones).

Descripción general

Cuando configures una compilación de Bazel para la ejecución remota, debes seguir los lineamientos que se describen en esta página para asegurarte de que la compilación se ejecute de forma remota sin errores. Esto se debe a la naturaleza de la ejecución remota, en particular:

  • Acciones de compilación aisladas. Las herramientas de compilación no retienen el estado, y las dependencias no pueden filtrarse entre ellas.

  • Varios entornos de ejecución. La configuración de compilación local no siempre es adecuada para entornos de ejecución remota.

En esta página, se describen los problemas que pueden surgir cuando se implementan reglas personalizadas de compilación y prueba de Bazel para la ejecución remota y cómo evitarlas. Abarca los siguientes temas:

Cómo invocar herramientas de compilación mediante reglas de la cadena de herramientas

Una regla de la cadena de herramientas de Bazel es un proveedor de configuración que le indica a una regla de compilación qué herramientas de compilación (como compiladores y vinculadores) debe usar y cómo configurarlas con parámetros definidos por el creador de la regla. Una regla de cadena de herramientas permite que las reglas de compilación y de prueba invoquen herramientas de compilación de una manera predecible y preconfigurada que sea compatible con la ejecución remota. Por ejemplo, usa una regla de cadena de herramientas en lugar de invocar herramientas de compilación mediante PATH, JAVA_HOME o cualquier otra variable local que pueda no estar configurada en valores equivalentes (o no) en el entorno de ejecución remoto.

Actualmente, existen reglas de la cadena de herramientas para las reglas de compilación y prueba de Bazel para Scala, Rust y Go, y hay nuevas reglas de cadena de herramientas en curso para otros lenguajes y herramientas como bash. Si no existe una regla de la cadena de herramientas para la herramienta que usa tu regla, considera crear una regla de la cadena de herramientas.

Administra dependencias implícitas

Si una herramienta de compilación puede acceder a dependencias en las acciones de compilación, estas fallarán cuando se ejecuten de forma remota, ya que cada acción de compilación remota se ejecuta por separado de las demás. Algunas herramientas de compilación conservan el estado en las acciones de compilación y acceden a dependencias que no se incluyeron de forma explícita en la invocación de herramientas, lo que hará que las acciones de compilación ejecutadas de forma remota fallen.

Por ejemplo, cuando Bazel le indica a un compilador con estado que compile foo de forma local, el compilador retiene referencias a los resultados de compilación de foo. Luego, cuando Bazel le indica al compilador que compile bar, que depende de foo, sin indicar explícitamente que la dependencia en el archivo BUILD para incluirla en la invocación del compilador, la acción se ejecuta correctamente, siempre y cuando se ejecute la misma instancia de compilador para ambas acciones (como es habitual en la ejecución local). Sin embargo, como en una situación de ejecución remota, cada acción de compilación ejecuta una instancia de compilador independiente, el estado del compilador y la dependencia implícita de bar en foo se perderán y la compilación fallará.

Para ayudar a detectar y eliminar estos problemas de dependencia, Bazel 0.14.1 ofrece la zona de pruebas local de Docker, que tiene las mismas restricciones para las dependencias que la ejecución remota. Usa la zona de pruebas a fin de preparar tu compilación para la ejecución remota. Para ello, identifica y resuelve los errores de compilación relacionados con las dependencias. Consulta Soluciona problemas de la ejecución remota de Bazel con la zona de pruebas de Docker para obtener más información.

Administra objetos binarios que dependen de la plataforma

Por lo general, un objeto binario compilado en la plataforma host no puede ejecutarse de forma segura en una plataforma de ejecución remota arbitraria debido a posibles dependencias no coincidentes. Por ejemplo, el objeto binario SingleJar proporcionado con Bazel se orienta a la plataforma host. Sin embargo, para la ejecución remota, SingleJar debe compilarse como parte del proceso de compilación de tu código, de modo que se oriente a la plataforma de ejecución remota. (Consulta la lógica de selección de objetivos).

No envíes objetos binarios de las herramientas de compilación requeridas por tu compilación con el código fuente, a menos que estés seguro de que se ejecutarán de manera segura en tu plataforma de ejecución. En su lugar, realiza una de las siguientes acciones:

  • Envía el código fuente de la herramienta o haz referencia externa a este, de modo que se pueda compilar para la plataforma de ejecución remota.

  • Instala previamente la herramienta en el entorno de ejecución remota (por ejemplo, un contenedor de la cadena de herramientas) si es lo suficientemente estable y usa las reglas de la cadena de herramientas para ejecutarla en tu compilación.

Administra reglas de WORKSPACE de estilo de configuración

Las reglas WORKSPACE de Bazel se pueden usar para sondear la plataforma host en busca de herramientas y bibliotecas que requiere la compilación, que, para las compilaciones locales, también es la plataforma de ejecución de Bazel. Si la compilación depende explícitamente de herramientas y artefactos de compilación locales, fallará durante la ejecución remota si la plataforma de ejecución remota no es idéntica a la plataforma de host.

Las siguientes acciones que realizan las reglas WORKSPACE no son compatibles con la ejecución remota:

  • Compilación de objetos binarios. La ejecución de acciones de compilación en reglas WORKSPACE genera objetos binarios incompatibles con la plataforma de ejecución remota si son diferentes de la plataforma host.

  • Instalación de paquetes de pip Los paquetes pip instalados a través de reglas WORKSPACE requieren que sus dependencias estén preinstaladas en la plataforma host. Esos paquetes, compilados específicamente para la plataforma host, no serán compatibles con la plataforma de ejecución remota si son diferentes a la plataforma host.

  • Vinculación con herramientas o artefactos locales. Los vínculos simbólicos a herramientas o bibliotecas instaladas en la plataforma host creadas a través de las reglas WORKSPACE harán que la compilación falle en la plataforma de ejecución remota, ya que Bazel no podrá localizarlas. En su lugar, crea symlinks con acciones de compilación estándar para que se pueda acceder a las herramientas y bibliotecas con symlink desde el árbol runfiles de Bazel. No uses repository_ctx.symlink para realizar un symlink de archivos de destino fuera del directorio de repositorio externo.

  • Mutación de la plataforma host. Evita crear archivos fuera del árbol runfiles de Bazel, crear variables de entorno y acciones similares, ya que pueden comportarse de forma inesperada en la plataforma de ejecución remota.

Para ayudar a encontrar un posible comportamiento no hermético, puedes usar el registro de reglas de Workspace.

Si una dependencia externa ejecuta operaciones específicas que dependen de la plataforma host, debes dividir esas operaciones entre WORKSPACE y reglas de compilación de la siguiente manera:

  • Inspección de la plataforma y enumeración de dependencias. Es seguro ejecutar estas operaciones de manera local mediante reglas WORKSPACE, que pueden verificar qué bibliotecas están instaladas, descargar paquetes que se deben compilar y preparar los artefactos necesarios para la compilación. Para la ejecución remota, estas reglas también deben admitir el uso de artefactos con verificación previa para proporcionar la información que normalmente se obtendría durante la inspección de la plataforma host. Los artefactos verificados previamente permiten que Bazel describa dependencias como si fueran locales. Para ello, usa sentencias condicionales o la marca --override_repository.

  • Generar o compilar artefactos específicos de destino y mutación de la plataforma. Estas operaciones deben ejecutarse mediante reglas de compilación regulares. Las acciones que producen artefactos específicos de destino para dependencias externas deben ejecutarse durante la compilación.

Si quieres generar artefactos previamente verificados para la ejecución remota con mayor facilidad, puedes usar reglas WORKSPACE para emitir archivos generados. Puedes ejecutar esas reglas en cada entorno de ejecución nuevo, por ejemplo, dentro de cada contenedor de la cadena de herramientas, y verificar los resultados de la compilación de ejecución remota en el repositorio de origen para hacer referencia.

Por ejemplo, en el caso de las reglas de TensorFlow para cuda y python, las reglas WORKSPACE producen lo siguiente BUILD files. Para la ejecución local, se usan los archivos producidos con la verificación del entorno del host. Para la ejecución remota, una declaración condicional en una variable de entorno permite que la regla use archivos que están registrados en el repositorio.

Los archivos BUILD declaran genrules que puede ejecutarse de forma local y remota, y realizar el procesamiento necesario que antes se realizaba a través de repository_ctx.symlink, como se muestra aquí.