使用复杂参数形式将自由格式命令传递给Ansible


9

我正在使用以编程方式生成的Ansible剧本。通常,因为剧本只是YAML,所以这很简单。但是,当使用“简单” key=value形式时,剧本不是纯粹的YAML,它们包含嵌入了shlex-parsable形式的内容。

为了避免这种形式的歧义(key=value将命令的参数与ansible的参数配对?),并且只有一种格式可以解析和生成,我无条件地使用ansible中的示例演示的复杂args机制-examples存储库

这使用以下语法:

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

...很好。但是,当尝试将这种形式用于shellcommand模块时(其文档将实际命令描述为在名为的参数中传递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语法接受“自由格式”命令的正确方法是什么?

Answers:


5

简短的回答:不使用commandrawscript,或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: ...?如果这种结构只能通过手工可靠地生成,那么这在一定程度上使问题无法解决。
Charles Duffy 2014年

@CharlesDuffy:我认为您...一般都无法逃脱。如果你看一下library/commands/command,你会发现一个漂亮大方正则表达式匹配creates=removes=chdir=,等等。如果需要确保可以传递任何命令,则必须编写自己的模块。
雪球2014年

公平的诺夫。在我看来,这是一个重大的设计失误……但事实就是如此。
2014年

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存在,应该存在吗?(如果是这样,这将清楚地解决歧义;否则,它似乎仍然存在)。
查尔斯·达菲,2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.