set_fact support for list of dictionaries?

What is the status on complex data storage for set_fact? It seems like its not quite possible yet when I have tried multiple methods.

  • name: testing

set_fact: vms=“[‘{ {{ item.item }}: {{ item.stdout.strip(’\n’) }} }']”
with_items:

  • “{{ hostips }}”

I found these links that got me close enough, but I am guessing that this is not yet supported.

https://groups.google.com/forum/#!topic/ansible-project/cPbCD6R9TnE

http://stackoverflow.com/questions/23507589/is-it-possible-to-set-a-fact-of-an-array-in-ansible

Thanks.

You are passing it a string above.

Don’t do that.

Try this:

  • set_fact:
    x:

I have an outstanding PR for that:

https://github.com/ansible/ansible/pull/8019

Oh nice.

This isn’t related to your commit - I’m starting to worry a bit about continual buildup of inline code cruft in Runner - so we may hold off on this a little bit until we can refactor things a bit to find a good place for things like this. This is a hard thing to stress on submissions, but over time, things build up.

In general, making some smaller functions and having the runner code call them would be a good idea.

​Agreed. Maybe the way on how to refactor this can be discussed on -devel?

Yeah it’s more of a devel topic, but since we’ve started the thread, I’ll share a bit.

I already have several things in mind - but they are hard to detail over text for me for an extent. While I generally want to make this project as maximally open to code review as possible, with some exception, reviewing outside refactorings is one of those things that I want to audit like a razor and I need to be really really really careful, so in general, unless discussed first, we /don’t/ take outside refactoring requests because they are too dangerous. Some contributions are really easy - especially new things - to take in - and we have increasing test and integration coverage - though subtlety still lurks in places. So just saying that so someone doesn’t try - refactoring changes in certain places can also invalidate a lot of pull requests, though Runner is not one of those things that are in major flux.

It’s really something James and I have some plans for, and it’s going to start being a major priority over the coming releases or two. It’s also a bit more of a philosophy - when some code is touched, clean it up a bit and leave it more organized than it was originally.

I’ve also taken a few (aborted) stabs in this direction, so I have a feeling of where it needs to go. It will probably start with just breaking more things into smaller functions, for starters, but eventually I want to see task objects passed into Runner directly.

For new folk, I do want to stress though that the tree is in good shape - we just want to make it even easier to contribute to, and easier to stretch in new directions, without making it harder to follow.

Is this related to this odd set_fact behavior I’m encountering with ansible 1.7.1?

http://pastebin.com/iBwfp7gA

I don’t want to use foo.stdout_lines because I intend to sometimes pass in foo via -e, hence why I’m trying to define a fact.

Brian

You’re replying to an old thread from July which was a little long, so I’m not sure what this inquiry was about.

“Is this related to this odd set_fact behavior I’m encountering with ansible 1.7.1?”

Could use some help clarifying what the pronoun “this” refers to. Sorry, internets make this hard sometime :slight_smile:

I found a probably even older thread with a solution to my particular issue, demonstrated by the pastebin from my original message.

This doesn’t work…

  • set_fact: directories=“{{ directories_output.stdout_lines }}”

This does work…

  • set_fact:
    directories: “{{ directories_output.stdout_lines }}”

That’s pretty screwy.

By work I mean, usable as an array in a Jinja2 template in a typical for loop.

Brian

It’s not the least bit screwy.

If you are doing key=value stuff all on one line, Ansible doesn’t know what is a string or not.

Jinja2 templating happens before values are past.

You are correct in that the long form set_fact does hold types nicely, and is what you want.

Also you actually mean this (note spacing):

  • set_fact:
    directories: “{{ directories_output.stdout_lines }}”

This is because directories is not a parameter to the task, it’s passed to the “set_fact” module.