Передача команд свободной формы в Ansible с использованием формы complex-args

9

Я использую программно сгенерированные Ansible playbooks. В общем, потому что пьесы просто YAML, это просто. Однако при использовании «простой» key=valueформы playbooks не являются чистым YAML - они включают в себя контент, встроенный в shlexформу -parsable.

Чтобы избежать неоднозначности в этой форме (это key=valueпара аргумент команды или аргумент для ansible?), И иметь только один формат для анализа и генерации, я безоговорочно использую механизм сложных аргументов, продемонстрированный на примере в ansible Примеры репозитория .

Это использует синтаксис следующего вида:

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

... что хорошо и хорошо. Однако при попытке использовать эту форму для модулей shellили command( документация которых описывает фактическую команду как передаваемую в аргументе с именем free_form), это работает не так хорошо:

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

При вызове выполняется следующее:

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

... что очень не то, что я пытаюсь сделать.

Как правильно использовать модули Ansible, принимающие команды «свободной формы» с использованием чистого синтаксиса YAML?

Чарльз Даффи
источник

Ответы:

5

Короткий ответ: Не используйте command, raw, scriptили shellмодули. Напишите свой собственный модуль, который принимает команду как «нормальный» аргумент.

Длинный ответ:

В большинстве случаев вы можете сделать это:

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

Тем не менее, это не удается в некоторых крайних случаях:

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

Я не знаю общего способа справиться с этим, но решение для bash:

- shell: echo hello_world > "creates=something"
  args:
    creates: creates=something
Снежный шар
источник
Есть ли структура данных, которую я могу передать любому совместимому генератору YAML, чтобы он излучал - shell: ...? Если эта структура является чем-то, что может быть надежно сгенерировано только вручную, это в некоторой степени противоречит сути вопроса.
Чарльз Даффи
@CharlesDuffy: я не думаю, что вы вообще можете избежать роли .... Если вы посмотрите на library/commands/command, вы найдете довольно щедр соответствие регулярных выражений creates=, removes=, chdir=и так далее. Если вам нужно гарантировать, что любая команда будет пропущена, вам придется написать свой собственный модуль.
Снежок
Ярмарка Это, на мой взгляд, существенная ошибка в дизайне ... но, в общем-то, так оно и есть.
Чарльз Даффи
0

Об этом говорится в документации Ansible сейчас.

# 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

Обратите внимание, что нет параметра с именем «free_form».

Кристиан Лонг
источник
Имеет ли наличие argsпрепятствует анализу k=vпар command, должны ли они существовать? (Если это так, то это решает проблему неоднозначности; в противном случае, похоже, она все еще существует).
Чарльз Даффи