Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Made $groups and $group_names variables accessible in with_items #1024

Merged
merged 2 commits into from

2 participants

@tima

This patch is specifically for use in with_items: in a playbook as mentioned in the Advanced Playbooks docs for Jinja templates.

@mpdehaan
Collaborator

Seems like we could just make group_list call the keys() method on the result of getting the groups in inventory.py, rather than duplicating the traversal logic?

@tima

Looking through the code I was under the impression that groups in there were not resolved to just host names. I'm mistaken?

@mpdehaan
Collaborator
@tima

If I have a host inventory:

[newengland]
Host1
Host2

[midatlantic]
Host3
Host4

[northeast]
newengland
midatlantic

From what I saw, if I just use the keys method and call groups['northeast'] I'd get newengland and midatlantic not Host1-4. From the code I found in the Host class that didn't seem like the correct answer especially because you can resolve a group inside another group. I was thinking about the MongoDB example as I went.

Hope that helps better explain what I was thinking.

@mpdehaan
Collaborator

Yeah makes sense, you're right.

Here's what I was talking about in Runner code that generates the variable that is made available in playbooks:

group_hosts = {}
for g in self.inventory.groups:
     group_hosts[g.name] = [ h.name for h in g.hosts ]
inject['groups'] = group_hosts

So yeah, from what you say, that won't contain ancestors -- and in that case, we must fix this as well, as part of this patch, so that it does.

Does that sort of make sense?

@tima

It does. I can make the change to the code above and resubmit this patch. Sound good?

@mpdehaan
Collaborator
@tima tima Made groups.groupname and group_names variables accessible in playbooks.
Also modified code that feeds the groups data structure to templates so
that it resolves groups inside of groups to hostnames.
9d5a79f
@tima

OK. Resubmitted. That should do it.

@mpdehaan mpdehaan merged commit 58ad934 into from
@mpdehaan
Collaborator

merging, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 7, 2012
  1. @tima
Commits on Sep 10, 2012
  1. @tima

    Made groups.groupname and group_names variables accessible in playbooks.

    tima authored
    Also modified code that feeds the groups data structure to templates so
    that it resolves groups inside of groups to hostnames.
This page is out of date. Refresh to see the latest.
Showing with 17 additions and 11 deletions.
  1. +13 −1 lib/ansible/inventory/__init__.py
  2. +4 −10 lib/ansible/runner/__init__.py
View
14 lib/ansible/inventory/__init__.py
@@ -35,7 +35,7 @@ class Inventory(object):
"""
__slots__ = [ 'host_list', 'groups', '_restriction', '_also_restriction', '_subset', '_is_script',
- 'parser', '_vars_per_host', '_vars_per_group', '_hosts_cache' ]
+ 'parser', '_vars_per_host', '_vars_per_group', '_hosts_cache', '_groups_list' ]
def __init__(self, host_list=C.DEFAULT_HOST_LIST):
@@ -49,6 +49,7 @@ def __init__(self, host_list=C.DEFAULT_HOST_LIST):
self._vars_per_host = {}
self._vars_per_group = {}
self._hosts_cache = {}
+ self._groups_list = {}
# the inventory object holds a list of groups
self.groups = []
@@ -213,6 +214,17 @@ def groups_for_host(self, host):
continue
return results
+ def groups_list(self):
+ if not self._groups_list:
+ groups = {}
+ for g in self.groups:
+ groups[g.name] = [h.name for h in g.get_hosts()]
+ ancestors = g.get_ancestors()
+ for a in ancestors:
+ groups[a.name] = [h.name for h in a.get_hosts()]
+ self._groups_list = groups
+ return self._groups_list
+
def get_groups(self):
return self.groups
View
14 lib/ansible/runner/__init__.py
@@ -250,17 +250,15 @@ def _executor_internal(self, host):
inject.update(self.module_vars)
inject.update(self.setup_cache[host])
inject['hostvars'] = self.setup_cache
+ inject['group_names'] = host_variables.get('group_names', [])
+ inject['groups'] = self.inventory.groups_list()
# allow with_items to work in playbooks...
# apt and yum are converted into a single call, others run in a loop
items = self.module_vars.get('items', [])
if isinstance(items, basestring) and items.startswith("$"):
- items = items.replace("$","")
- if items in inject:
- items = inject[items]
- else:
- raise errors.AnsibleError("unbound variable in with_items: %s" % items)
+ items = utils.varLookup(items, inject)
if type(items) != list:
raise errors.AnsibleError("with_items only takes a list: %s" % items)
@@ -321,11 +319,7 @@ def _executor_internal_inner(self, host, inject, port, is_chained=False):
# 'hostvars' variable contains variables for each host name
# ... and is set elsewhere
# 'inventory_hostname' is also set elsewhere
- group_hosts = {}
- for g in self.inventory.groups:
- group_hosts[g.name] = [ h.name for h in g.hosts ]
- inject['groups'] = group_hosts
-
+ inject['groups'] = self.inventory.groups_list()
# allow module args to work as a dictionary
# though it is usually a string
new_args = ""
Something went wrong with that request. Please try again.