Pasar comandos de forma libre a Ansible usando el formulario de argumentos complejos

9

Estoy usando libros de jugadas Ansible generados programáticamente. En general, debido a que los libros de jugadas son solo YAML, esto es sencillo. Sin embargo, cuando se usa la forma "simple" key=value, los libros de jugadas no son YAML puros, sino que incluyen contenido incrustado en una shlexforma analizable.

Para evitar la ambigüedad en esta forma (¿es eso key=valueemparejar un argumento con el comando o un argumento para ansible?) Y tener un solo formato para analizar y generar, estoy usando incondicionalmente el complejo mecanismo de argumentos demostrado por ejemplo en el ansible -positorio de ejemplos .

Esto usa una sintaxis del siguiente tipo:

action: module-name
args:
  key1: value1
  key2: value2

... que está bien y bien. Sin embargo, al intentar usar este formulario para los módulos shello command( cuya documentación describe el comando real como se pasa en un argumento llamado free_form), esto no funciona tan bien:

action: shell
args:
  free_form: echo hello_world >/tmp/something
  creates: /tmp/something

Cuando se invoca, esto ejecuta lo siguiente:

/bin/sh -c " free_form='echo hello_world >/tmp/something'  "

... que no es lo que estoy tratando de lograr.

¿Cuál es la forma correcta de usar módulos Ansible que toman comandos de "forma libre" usando sintaxis YAML pura?

Charles Duffy
fuente

Respuestas:

5

Respuesta corta: no utilice el command, raw, script, o shellmódulos. Escriba su propio módulo que acepte el comando como un argumento "normal".

Respuesta larga:

En la mayoría de los casos, puede hacer esto:

- shell: echo hello_world > /tmp/something
  args:
    creates: /tmp/something

Sin embargo, esto falla en algunos casos extremos:

- shell: echo hello_world > creates=something
  args:
    creates: creates=something  # The file is named "creates=something"

No conozco una forma general de manejar esto, pero una solución específica para bash es:

- shell: echo hello_world > "creates=something"
  args:
    creates: creates=something
Bola de nieve
fuente
¿Hay una estructura de datos que pueda pasar a cualquier generador YAML compatible para que emita - shell: ...? Si esta estructura es algo que solo se puede generar de manera confiable a mano, eso de alguna manera frustra el punto de la pregunta.
Charles Duffy
@CharlesDuffy: No creo que puedas escapar de la ...parte en general. Si nos fijamos en library/commands/command, encontrará una coincidencia de expresiones regulares bastante generoso creates=, removes=, chdir=, y así sucesivamente. Si necesita garantizar que se pueda pasar algún comando, deberá escribir su propio módulo.
Snowball
Justo 'nuff. Esto es, en mi opinión, un error importante de diseño ... pero, bueno, es lo que es.
Charles Duffy
0

Esto se aborda en la documentación de Ansible ahora.

# You can also use the 'args' form to provide the options. This command
# will change the working directory to somedir/ and will only run when
# /path/to/database doesn't exist.
- command: /usr/bin/make_database.sh arg1 arg2
  args:
    chdir: somedir/
    creates: /path/to/database

Tenga en cuenta que no hay ningún parámetro llamado 'free_form'.

Cristiano largo
fuente
¿La presencia de argsevita que los k=vpares sean analizados command, en caso de existir? (Si es así, esto aborda la ambigüedad de manera limpia; de lo contrario, parece que todavía existe).
Charles Duffy