Passando comandos de forma livre para o Ansible usando o formulário complex-args

9

Estou usando playbooks Ansible gerados programaticamente. Em geral, como os playbooks são apenas YAML, isso é direto. No entanto, ao usar o key=valueformulário "simples" , os playbooks não são YAML puros - eles incluem conteúdo incorporado em um shlexformulário comparável.

Para evitar a ambiguidade neste formulário (esse key=valuepar é um argumento para o comando ou um argumento para ansible?) E tem apenas um único formato para analisar e gerar, estou usando incondicionalmente o mecanismo args complexo demonstrado por exemplo no ansible repositório -examples .

Isso usa uma sintaxe do seguinte tipo:

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

... o que é bom e bom. No entanto, ao tentar usar este formulário para os módulos shellou command( cuja documentação descreve o comando real como sendo passado em um argumento chamado free_form), isso não funciona tão bem:

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

Quando invocado, isso executa o seguinte:

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

... o que não é o que estou tentando realizar.

Qual é a maneira correta de usar módulos Ansible que tomam comandos "de forma livre" usando a sintaxe YAML pura?

Charles Duffy
fonte

Respostas:

5

Resposta curta: Não use o command, raw, script, ou shellmódulos. Escreva seu próprio módulo que aceita o comando como um argumento "normal".

Resposta longa:

Na maioria dos casos, você pode fazer isso:

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

No entanto, isso falha em alguns casos extremos:

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

Não conheço uma maneira geral de lidar com isso, mas uma solução específica para o bash é:

- shell: echo hello_world > "creates=something"
  args:
    creates: creates=something
Bola de neve
fonte
Existe uma estrutura de dados que eu possa transmitir a qualquer gerador YAML compatível para que ele seja emitido - shell: ...? Se essa estrutura é algo que só pode ser gerado de forma confiável com a mão, isso acaba com o argumento da questão.
Charles Duffy
@ CharlesDuffy: Eu não acho que você possa escapar da ...parte em geral. Se você olhar library/commands/command, você vai encontrar uma correspondência regex bastante generosa creates=, removes=, chdir=, e assim por diante. Se você precisar garantir que qualquer comando possa ser transmitido, precisará escrever seu próprio módulo.
Snowball
Fair 'nuff. Isso é, na minha opinião, um erro significativo de design ... mas, bem, é o que é.
Charles Duffy
0

Isso é abordado na documentação do Ansible agora.

# 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

Observe que não há parâmetro chamado 'free_form'.

Christian Long
fonte
A presença de argsimpede que os k=vpares sejam analisados command, deve existir algum? (Se sim, isso aborda a ambiguidade de maneira limpa; caso contrário, parece que ainda existe).
22816 Charles Duffy