Support process substitution?

Does Ansible not support bash’s process substitution?

My project maintains separate inventory files, and there are some playbooks that need hosts from certain combinations of them. Instead of having pre-concatenated files that could go out of sync, I’d like to do something like:

$ ansible-playbook -i <(cat inventorya inventoryb) playbook.yml

I get this error though when I try it:

ERROR: provided hosts list is empty

I haven’t looked at the Ansible source, but this may be because process substitution uses an fifo under the hood, and Ansible may be strictly looking for a file, but this is just wild speculation.

(Ansible 1.7.1)

-Paul

To be honest, I’ve never even seen that syntax used before – redirection of input/output obviously yes…

It’s a sign you can be writing systems management software for well over a decade and not learn all the bash things.

Basically right now it takes either a string - for a very deprecated use case we don’t really document, or a filename or directory name.

A quick way to solve what you want to do, BTW, is just put both in the same directory

-i directoryname

will load all files int he one directory

and then use “–limit groupname” to limit ansible to just what you want to select.

(Be careful to not forget the limit!)

That’s the way pretty much everyone approaches that, anyway :slight_smile:

Another option would be use “-i directoryname” and just be particular about what your “hosts:” stanza would address.

I’m open to make this loading be more generic provided we be careful to not break any current possibilities, but am not entirely sure what is involved.

another form:

cat inventorya inventoryb |ansible-playbook -i /dev/stdin playbook.yml

It still won't work as you think, it will only work if inventorya and
inventoryb contain the hosts in comma separated lists, as -i looks for
an existing file or directory in the string unless there is a comma,
then it takes it as a list.

To clarify, process substitution is a Bash shell syntax that replaces the <( … ) with a filename, but that filename is a named pipe (aka a FIFO) that a sub-shell has opened for writing by the commands inside the parentheses. The command that you pass this to (in Paul’s example, ansible-playbook) must open the given “file” and read it from start to end without trying to seek back and forth.

I tried this with the ‘ansible’ command a while ago and it failed the same way. I assumed that the code wanted to do seeks around the file rather than just read it all, and that was the reason for the failure. I didn’t investigate any deeper.

I thought it could be a nice way to accommodate dynamic inventory sources, but there might be a good reason you wouldn’t want to support it.

-Greg

Yeah I’m obviously more familiar with that one.

Ultimately, I’m not sure it makes sense - there are multiple inputs to Ansible, and it would be unclear which thing got to be STDIN.

Ansible does already have a concept of dynamic inventory sources that has somewhat reserved that phrase:

http://docs.ansible.com/intro_dynamic_inventory.html

If a bit of tweaking is necessary to allow for reading files from named pipes, I’m ok with it – provided everything else works as advertised.