@ -42,6 +42,8 @@ class InventoryScript(object):
raise errors . AnsibleError ( " problem running %s ( %s ) " % ( ' ' . join ( cmd ) , e ) )
( stdout , stderr ) = sp . communicate ( )
self . data = stdout
# see comment about _meta below
self . host_vars_from_top = None
self . groups = self . _parse ( stderr )
def _parse ( self , err ) :
@ -52,11 +54,23 @@ class InventoryScript(object):
groups = dict ( all = all )
group = None
if ' failed ' in self . raw :
sys . stderr . write ( err + " \n " )
raise errors . AnsibleError ( " failed to parse executable inventory script results: %s " % self . raw )
for ( group_name , data ) in self . raw . items ( ) :
# in Ansible 1.3 and later, a "_meta" subelement may contain
# a variable "hostvars" which contains a hash for each host
# if this "hostvars" exists at all then do not call --host for each
# host. This is for efficiency and scripts should still return data
# if called with --host for backwards compat with 1.2 and earlier.
if group_name == ' _meta ' :
if ' hostvars ' in data :
self . host_vars_from_top = data [ ' hostvars ' ]
continue
group = groups [ group_name ] = Group ( group_name )
host = None
@ -85,6 +99,8 @@ class InventoryScript(object):
# Separate loop to ensure all groups are defined
for ( group_name , data ) in self . raw . items ( ) :
if group_name == ' _meta ' :
continue
if isinstance ( data , dict ) and ' children ' in data :
for child_name in data [ ' children ' ] :
if child_name in groups :
@ -93,6 +109,11 @@ class InventoryScript(object):
def get_host_variables ( self , host ) :
""" Runs <script> --host <hostname> to determine additional host variables """
if self . host_vars_from_top is not None :
got = self . host_vars_from_top . get ( host , { } )
return got
cmd = [ self . filename , " --host " , host . name ]
try :
sp = subprocess . Popen ( cmd , stdout = subprocess . PIPE , stderr = subprocess . PIPE )