What is free_form command and cmd parameter in command module

  1. when using command module " Either a free form command or cmd parameter is required". what is “free form command” and “cmd parameter”?
  2. when executing ansible localhost -m command -a "cmd=date", nothing happens.but if I put cmd: date in a task, it worked. so “cmd parameter” can only be used in playbook but not in ad hoc command?
  3. it there and document about which parameter can’t be used in ad hoc command?

none, they should all work as ‘adhoc’ creates a temporary play and task and uses the commands you pass for that

It looks to me like adhoc supports exactly two ways of parsing -a values:

  1. If the value beings with { and ends with }, the contents will be parsed as JSON. So ansible localhost -m command -a '{"cmd": "date"}' works as expected.

  2. Otherwise, ansible.parsing.splitter.parse_kv() will be used with check_raw=True (since the action is command), which only splits off the following parameters: creates, removes, chdir, executable, warn, stdin, stdin_add_newline, strip_empty_ends. Since cmd is not on that list, cmd=date will be passed as _raw_params on and thus treated as the command to execute.

So if you don’t want to provide JSON, you are limited to a small explicit set of parameters you can use for command and all other actions in MODULE_REQUIRE_ARGS. The current list of actions is command, win_command, ansible.windows.win_command, shell, win_shell, ansible.windows.win_shell, raw, script (with ansible.builtin. and ansible.legacy. prepended to everything that has no . and also added to the list).

For all other actions, the complete -a value is split up (as expected).

2 Likes

I had just finished looking into it deeper, but felix already explained the issue. I’ll be adding notes to the ‘module_require_args’ modules to warn about this issue.

1 Like

We also have a fix planned, but it requires many pieces.

  • controller argspec parsing
  • modules declare free_form (attribute)"
  • use the previous 2 to pass the information to splitter so it knows what are options vs ‘free form’

Is there a way to specify additional task level keywords and values to ad hoc invocations? Lots of them are covered by specific parameters / options to the ansible command itself, but more recent ones like timeout don’t have obvious ways to twiddle their knobs.

At least in the case of timeout, there’s an env var for config Ansible Configuration Settings — Ansible Community Documentation.

ANSIBLE_TASK_TIMEOUT=10 ansible localhost -m ping

Ah, true. Yet one more one-off though. It is rather scattered, reflecting the evolutionary nature of the thing.

I’m wondering if the “planned fix that requires many pieces” that @bcoca alluded to might address this more generically.

But on 2nd thought, it may be easier to throw together a simple one-task playbook than deal with yet more rarely needed/used flags.

# ansible localhost -m command -a '{"cmd": "date"}'
localhost | FAILED | rc=2 >>
[Errno 2] No such file or directory

:smiling_face_with_tear:

@aaron1989041 which version of ansible-core are you running? I get

localhost | CHANGED | rc=0 >>
Tue Apr  2 06:23:38 AM CEST 2024

when running it :slight_smile: (using the latest ansible-core devel version right now).

1 Like
# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Jun 28 2022, 15:30:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Jun 28 2022, 15:30:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

@aaron1989041 please note that Ansible 2.9 is quite old and will have been End of Life for almost two years soon (Releases and maintenance — Ansible Core Documentation).

I would assume that this way of passing JSON arguments was only added in a newer version of ansible-base/ansible-core.

1 Like

I would assume that this way of passing JSON arguments was only added in a newer version of ansible-base/ansible-core.

Added in 2.14 Add support for json in adhoc -a by jborean93 · Pull Request #78114 · ansible/ansible · GitHub (specifically for this use case).

3 Likes