Ejecutar Comandos Shell
Uno de los principales objetivos de los rulebooks es hacer extremadamente fácil llamar a comandos shell.
Los comandos shell pueden ejecutarse localmente (en el servidor Clarive) o remotamente (es decir, en un nodo remoto). Necesitará decidir dónde ejecutar sus comandos.
Ejecutar Comandos Localmente¶
Los comandos locales se ejecutan en un shell en el servidor Clarive, siempre dentro de un contenedor Docker.
do: # Esta es la forma larga de ejecutar un comando shell: - shell: cmd: ls args: - "-l" - "-a"
Lo cual, afortunadamente, puede acortarse a algo como esto:
do: - shell: ls -la # oh, esto es mucho mejor
Si prefiere separar sus argumentos, también hay una versión concisa:
do: - shell: - apt - install - build-essential - openssl # que se convierte en "apt install build-essential openssl" en el shell
O en notación de array concisa:
do: - shell: [ 'apt', 'install', 'build-essential', 'openssl' ] # igual, se convierte en "apt install build-essential openssl" en el shell
O mejor aún, usando la notación directa. Desafortunadamente, la notación directa
no tiene un argumento de array (args), pero definitivamente es el camino a seguir.
do: - ls -lart # sí, esto es mucho mejor - "ls -lart" # ídem
Si necesita ejecutar múltiples comandos a la vez, puede separarlos con nueva línea:
do: - shell: cmd: | echo hello >> /clarive/myfile echo world >> /clarive/myfile cat /clarive/myfile # o así: - shell: | echo hello >> /clarive/myfile echo world >> /clarive/myfile cat /clarive/myfile # o aún: - | echo hello >> /clarive/myfile echo world >> /clarive/myfile cat /clarive/myfile
Asignar la salida a una variable¶
Ahora, la mejor característica de los comandos shell de rulebook es que puede asignar valores
de comando a variables. Necesita anteponer el comando shell: con la variable
que desea usar.
do: - result = shell: ls -lart /clarive - echo: "exit code was ${result.rc}, output: ${result.output}"
Los comandos siempre devuelven un objeto hash con 2 subclaves:
{ rc: 0, # el código de salida del comando output: '...' # la salida capturada combinando stderr y stdout }
Puede asignar una secuencia de comandos multilínea de la misma manera, pero debe usar shell::
do: - ret = shell: | echo hello >> /clarive/myfile echo world >> /clarive/myfile cat /clarive/myfile - echo: "OUTPUT = {{ ret.output }}" - echo: "EXIT CODE OF LAST COMMAND = {{ ret.rc }}"
Note
Los comandos shell fallidos (código de salida <> 0) que no se asignan a variables lanzarán errores que interrumpirán su rulebook.
Por lo tanto, asignar comandos a variables es una buena manera de capturar errores y procesarlos usted mismo.
Aquí hay un ejemplo de variable capturada con control de errores:
do: # captura y control de errores combinados - ret = shell: | ls -lart /clarive/ ls -lart /clarive/this_folder_not_here - echo: "OUTPUT = {{ ret.output }}" - if: "{{ ret.rc }}" then: # use log: para salida coloreada en el visor de logs del job - log: msg: "We failed with rc={{ ret.rc }}" level: error else: - echo: "Everything okay"
Eso producirá la siguiente salida:
ls: cannot access '/clarive/not_exists': No such file or directory We failed with rc=2
Comandos con pipe¶
A veces puede querer canalizar varios comandos shell juntos, redirigiendo
la salida de un comando al siguiente. Esto es bastante trivial y lo gestiona
el ejecutor del shell (una función C open3()):
do: - cat /etc/hosts | wc -l
Si desea canalizar la salida de vuelta a su rulebook, entonces debe configurar
un callback stdout o stderr. El proceso shell invocará el
callback con fragmentos de salida.
do: - shell: cmd: find / pipe_out: - echo: "Got a stdout chunk here: ${chunk}"
O procesarlo con ClaJS directamente:
do: - shell: cmd: find / pipe_out: | print( "Got it here now: " + cla.stash('chunk') );
Seleccionar una Imagen Docker¶
Los comandos que se ejecutan en el servidor siempre se ejecutan en un contenedor Docker.
Por defecto, los comandos se ejecutan en la imagen predeterminada de clarive.
Pero puede controlar fácilmente qué imagen de contenedor se está usando con el op image:.
do: # descargar e instalar una imagen python desde Docker Hub # (si aún no la tiene instalada) - image: python - python --version
Puede alternar entre imágenes a medida que avanza:
do: # python primero - image: python - python --version # luego ruby - image: ruby - ruby --version - gem install json
O ejecutarlo dentro de un bloque image: con do:, lo que
lo agrupa bien:
do: # tenga cuidado de indentar correctamente image y do - image: ruby - do: - gem install json - gem install mongo
Important
Cada comando que se ejecuta en una imagen Docker
ejecutará docker run -it cada vez. Use los comandos multilínea
mostrados arriba para ejecutarlos en la misma sesión de ejecución de contenedor.
Ejecutar comandos remotamente¶
Puede ejecutar comandos shell en servidores remotos usando las
opciones host: o worker: del op shell:. Pero primero
necesita tener el servidor remoto conectado al servidor Clarive
usando uno de los siguientes métodos:
-
Clarive Worker - probablemente la forma más fácil, simplemente descargue un worker en la máquina remota y regístrelo con su servidor.
-
SSH - el servidor Clarive necesita tener su clave pública en las
authorized_keysdel servidor de destino para los usuarios con los que pretende conectarse. -
Clarive ClaX Agent - el agente ClaX necesita estar ejecutándose como un proceso InetD o agente independiente escuchando en un puerto dado.
En este documento solo se cubre el Clarive Worker, ya que los agentes SSH y ClaX son más adecuados para reglas de Clarive y no para rulebooks.
Ejecutar un comando en el Clarive Worker¶
Antes de ejecutar cualquier comando, asegúrese de que el Clarive Worker esté registrado e iniciado.
Supongamos que su worker se registró con el id myworkerid.
cla-worker run --id myworkerid --token [el token que se le dio con el comando register]
Para ejecutar un comando shell con el Clarive Worker:
do: - ret = shell: worker: myworkerid cmd: ls -lart /tmp/ - echo: "OUTPUT = {{ ret.output }}" - echo: "EXIT CODE OF LAST COMMAND = {{ ret.rc }}"
En caso de que solo quiera elegir cualquier worker disponible para su comando, puede usar el asterisco:
do: - ret = shell: worker: '*' # solo el primer worker disponible cmd: ls -lart /tmp/
En caso de que establezca algunas etiquetas para identificar su worker, use eso para encontrar el primer worker disponible que pueda manejar una o un conjunto de etiquetas:
cla-worker run --id myworkerid --token [...] --tags node,npm
Luego ejecute el comando destinado a los workers etiquetados:
do: - ret = shell: worker: { tags: ['npm','node'] } cmd: | cd /opt/build/myproject npm run tests
¡Eso es todo! Asegúrese de leer también cómo enviar y recuperar archivos del worker en la documentación.