Adapta reglas de Bazel para la ejecución remota

Informar un problema Ver fuente Nightly · 8.0 . 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Esta página está destinada a los usuarios de Bazel que escriben reglas de compilación y prueba personalizadas y que desean comprender los requisitos de las reglas de Bazel en el contexto de la 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 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 cuando se hace referencia a diferentes tipos de entornos o plataformas:

  • Plataforma de host: Es donde se ejecuta Bazel.
  • Plataforma de ejecución: Es donde se ejecutan las acciones de Bazel.
  • Plataforma de destino: Es 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, a saber:

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

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

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

Invoca herramientas de compilación a través de reglas de cadena de herramientas

Una regla de 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 enlazadores, usar y cómo configurarlas con los parámetros definidos por el creador de la regla. Una regla de cadena de herramientas permite que las reglas de compilación y 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 a través de PATH, JAVA_HOME o alguna otra variable local que podría no estar configurada en valores equivalentes (o en absoluto) en el entorno de ejecución remoto.

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

Administración de dependencias implícitas

Si una herramienta de compilación puede acceder a dependencias entre acciones de compilación, esas acciones 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 retienen el estado en todas las acciones de compilación y acceden a dependencias que no se incluyeron de forma explícita en la invocación de la herramienta, lo que provocará que falle la ejecución remota de las acciones de compilación.

Por ejemplo, cuando Bazel le indica a un compilador con estado que compile foo de forma local, el compilador retiene las referencias a los resultados de la compilación de foo. Cuando Bazel luego pide al compilador que compile bar, que depende de foo, sin declarar explícitamente esa dependencia en el archivo BUILD para incluirla en la invocación del compilador, la acción se ejecuta correctamente, siempre y cuando la misma instancia del compilador se ejecute 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, se perderán el estado del compilador y la dependencia implícita de bar en foo, y la compilación fallará.

Para ayudar a detectar y eliminar estos problemas de dependencias, 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 para preparar tu compilación para la ejecución remota. Para ello, identifica y resuelve los errores de compilación relacionados con las dependencias. Consulta Cómo solucionar problemas de ejecución remota de Bazel con la zona de pruebas de Docker para obtener más información.

Administración de objetos binarios que dependen de la plataforma

Por lo general, un objeto binario compilado en la plataforma de host no se puede ejecutar de forma segura en una plataforma de ejecución remota arbitraria debido a dependencias potencialmente no coincidentes. Por ejemplo, el objeto binario SingleJar que se proporciona con Bazel se orienta a la plataforma de host. Sin embargo, para la ejecución remota, SingleJar se debe compilar como parte del proceso de compilación de tu código para 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 que requiere tu compilación con tu código fuente, a menos que estés seguro de que se ejecutarán de forma segura en tu plataforma de ejecución. En su lugar, haz una de las siguientes acciones:

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

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

Cómo administrar reglas de WORKSPACE de estilo de configuración

Las reglas WORKSPACE de Bazel se pueden usar para sondear la plataforma de host en busca de herramientas y bibliotecas que requiera la compilación, que, para las compilaciones locales, también es la plataforma de ejecución de Bazel. Si la compilación depende de forma explícita 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 de 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 pip Los paquetes pip instalados a través de reglas WORKSPACE requieren que sus dependencias estén preinstaladas en la plataforma host. Estos paquetes, compilados específicamente para la plataforma de host, serán incompatibles con la plataforma de ejecución remota si son diferentes de la plataforma de host.

  • Creación de symlinks a herramientas o artefactos locales Los symlinks a herramientas o bibliotecas instaladas en la plataforma host creadas a través de reglas WORKSPACE harán que la compilación falle en la plataforma de ejecución remota, ya que Bazel no podrá encontrarlas. En su lugar, crea symlinks con acciones de compilación estándar para que se pueda acceder a las herramientas y bibliotecas vinculadas desde el árbol runfiles de Bazel. No uses repository_ctx.symlink para crear symlinks a archivos de destino fuera del directorio del 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 anfitrión, debes dividir esas operaciones entre WORKSPACE y las reglas de compilación de la siguiente manera:

  • Inspección de la plataforma y enumeración de dependencias. Estas operaciones se pueden ejecutar de forma segura de forma local a través de 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 verificados previamente 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 las dependencias como si fueran locales. Para ello, usa sentencias condicionales o la marca --override_repository.

  • Genera o compila artefactos específicos del objetivo y mutación de la plataforma. Estas operaciones deben ejecutarse a través de reglas de compilación normales. Las acciones que producen artefactos específicos del destino para dependencias externas deben ejecutarse durante la compilación.

Para generar artefactos verificados previamente 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, como dentro de cada contenedor de cadena de herramientas, y verificar los resultados de la compilación de ejecución remota en tu repo de origen para usarlos como referencia.

Por ejemplo, para las reglas de Tensorflow para cuda y python, las reglas WORKSPACE producen el siguiente BUILD files. Para la ejecución local, se usan los archivos que se producen cuando se verifica el entorno del host. Para la ejecución remota, una sentencia condicional en una variable de entorno permite que la regla use los archivos que se marcan en el repositorio.

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