From e6e69c089414835d448bbffffd21c4775f2b23f0 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Sat, 4 Apr 2015 10:25:55 -0400 Subject: [PATCH] finished implementing list-hosts, started adding list-tasks/list-tags but getting just task names and have to adjust for having blocks. --- v2/ansible/executor/playbook_executor.py | 160 ++++++++++++----------- v2/ansible/playbook/play.py | 10 ++ v2/bin/ansible-playbook | 36 +++-- 3 files changed, 118 insertions(+), 88 deletions(-) diff --git a/v2/ansible/executor/playbook_executor.py b/v2/ansible/executor/playbook_executor.py index 24b9f8c17b..865b06f108 100644 --- a/v2/ansible/executor/playbook_executor.py +++ b/v2/ansible/executor/playbook_executor.py @@ -59,12 +59,18 @@ class PlaybookExecutor: signal.signal(signal.SIGINT, self._cleanup) result = 0 + entrylist = [] + entry = {} try: for playbook_path in self._playbooks: pb = Playbook.load(playbook_path, variable_manager=self._variable_manager, loader=self._loader) - # FIXME: playbook entries are just plays, so we should rename them - for play in pb.get_entries(): + if self._tqm is None: # we are doing a listing + entry = {'playbook': playbook_path} + entry['plays'] = [] + + i = 1 + for play in pb.get_plays(): self._inventory.remove_restriction() # Create a temporary copy of the play here, so we can run post_validate @@ -73,54 +79,91 @@ class PlaybookExecutor: new_play = play.copy() new_play.post_validate(all_vars, fail_on_undefined=False) - for batch in self._get_serialized_batches(new_play): - if len(batch) == 0: - self._tqm.send_callback('v2_playbook_on_play_start', new_play) - self._tqm.send_callback('v2_playbook_on_no_hosts_matched') - result = 0 - break - # restrict the inventory to the hosts in the serialized batch - self._inventory.restrict_to_hosts(batch) - # and run it... - result = self._tqm.run(play=play) + if self._tqm is None: + # we are just doing a listing + + pname = new_play.get_name().strip() + if pname == 'PLAY: ': + pname = 'PLAY: #%d' % i + p = { 'name': pname } + + if self._options.listhosts: + p['pattern']=play.hosts + p['hosts']=set(self._inventory.get_hosts(new_play.hosts)) + + #TODO: play tasks are really blocks, need to figure out how to get task objects from them + elif self._options.listtasks: + p['tasks'] = [] + for task in play.get_tasks(): + p['tasks'].append(task) + #p['tasks'].append({'name': task.get_name().strip(), 'tags': task.tags}) + + elif self._options.listtags: + p['tags'] = set(new_play.tags) + for task in play.get_tasks(): + p['tags'].update(task) + #p['tags'].update(task.tags) + entry['plays'].append(p) + + else: + # we are actually running plays + for batch in self._get_serialized_batches(new_play): + if len(batch) == 0: + self._tqm.send_callback('v2_playbook_on_play_start', new_play) + self._tqm.send_callback('v2_playbook_on_no_hosts_matched') + result = 0 + break + # restrict the inventory to the hosts in the serialized batch + self._inventory.restrict_to_hosts(batch) + # and run it... + result = self._tqm.run(play=play) + if result != 0: + break + if result != 0: - break + raise AnsibleError("Play failed!: %d" % result) + + i = i + 1 # per play + + if entry: + entrylist.append(entry) # per playbook + + if entrylist: + return entrylist - if result != 0: - raise AnsibleError("Play failed!: %d" % result) finally: - self._cleanup() + if self._tqm is not None: + self._cleanup() - if result == 0: - #TODO: move to callback - # FIXME: this stat summary stuff should be cleaned up and moved - # to a new method, if it even belongs here... - self._display.banner("PLAY RECAP") + #TODO: move to callback + # FIXME: this stat summary stuff should be cleaned up and moved + # to a new method, if it even belongs here... + self._display.banner("PLAY RECAP") - hosts = sorted(self._tqm._stats.processed.keys()) - for h in hosts: - t = self._tqm._stats.summarize(h) + hosts = sorted(self._tqm._stats.processed.keys()) + for h in hosts: + t = self._tqm._stats.summarize(h) - self._display.display("%s : %s %s %s %s" % ( - hostcolor(h, t), - colorize('ok', t['ok'], 'green'), - colorize('changed', t['changed'], 'yellow'), - colorize('unreachable', t['unreachable'], 'red'), - colorize('failed', t['failures'], 'red')), - screen_only=True - ) + self._display.display("%s : %s %s %s %s" % ( + hostcolor(h, t), + colorize('ok', t['ok'], 'green'), + colorize('changed', t['changed'], 'yellow'), + colorize('unreachable', t['unreachable'], 'red'), + colorize('failed', t['failures'], 'red')), + screen_only=True + ) - self._display.display("%s : %s %s %s %s" % ( - hostcolor(h, t, False), - colorize('ok', t['ok'], None), - colorize('changed', t['changed'], None), - colorize('unreachable', t['unreachable'], None), - colorize('failed', t['failures'], None)), - log_only=True - ) + self._display.display("%s : %s %s %s %s" % ( + hostcolor(h, t, False), + colorize('ok', t['ok'], None), + colorize('changed', t['changed'], None), + colorize('unreachable', t['unreachable'], None), + colorize('failed', t['failures'], None)), + log_only=True + ) - self._display.display("", screen_only=True) - # END STATS STUFF + self._display.display("", screen_only=True) + # END STATS STUFF return result @@ -161,36 +204,3 @@ class PlaybookExecutor: serialized_batches.append(play_hosts) return serialized_batches - - def list_hosts_per_play(self): - - playlist = [] - try: - i = 1 - for playbook_path in self._playbooks: - pb = Playbook.load(playbook_path, variable_manager=self._variable_manager, loader=self._loader) - for play in pb.get_entries(): - - # Use templated copies in case hosts: depends on variables - all_vars = self._variable_manager.get_vars(loader=self._loader, play=play) - new_play = play.copy() - new_play.post_validate(all_vars, fail_on_undefined=False) - - pname = play.get_name().strip() - if pname == 'PLAY: ': - pname = 'PLAY: #%d' % i - - playlist.append( { - 'name': pname, - 'pattern': play.hosts, - 'hosts': set(self._inventory.get_hosts(new_play.hosts)), - } ) - i = i + 1 - - except AnsibleError: - raise - except Exception, e: - #TODO: log exception - raise AnsibleParserError("Failed to process plays: %s" % str(e)) - - return playlist diff --git a/v2/ansible/playbook/play.py b/v2/ansible/playbook/play.py index a472d07089..34c4d3e560 100644 --- a/v2/ansible/playbook/play.py +++ b/v2/ansible/playbook/play.py @@ -27,6 +27,7 @@ from ansible.playbook.become import Become from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles from ansible.playbook.role import Role from ansible.playbook.taggable import Taggable +from ansible.playbook.block import Block from ansible.utils.vars import combine_vars @@ -233,6 +234,15 @@ class Play(Base, Taggable, Become): def get_roles(self): return self.roles[:] + def get_tasks(self): + tasklist = [] + for task in self.pre_tasks + self.tasks + self.post_tasks: + if isinstance(task, Block): + tasklist.append(task.block + task.rescue + task.always) + else: + tasklist.append(task) + return tasklist + def serialize(self): data = super(Play, self).serialize() diff --git a/v2/bin/ansible-playbook b/v2/bin/ansible-playbook index 4dc6d6bad9..e2cca10484 100755 --- a/v2/bin/ansible-playbook +++ b/v2/bin/ansible-playbook @@ -134,20 +134,30 @@ def main(args): display = Display() pbex = PlaybookExecutor(playbooks=args, inventory=inventory, variable_manager=variable_manager, loader=loader, display=display, options=options) - if options.listhosts: - for p in pbex.list_hosts_per_play(): - print("\n %s (%s): host count=%d" % (p['name'], p['pattern'], len(p['hosts']))) - for host in p['hosts']: - print(" %s" % host) - sys.exit(0) - elif options.listtasks: - print('TODO: implement') - sys.exit(0) - elif options.listtags: - print('TODO: implement') - sys.exit(0) + results = pbex.run() + + if isinstance(results, list): + for p in results: + + print('') + print('playbook: %s' % p['playbook']) + print('') + + for play in p['plays']: + if options.listhosts: + print("\n %s (%s): host count=%d" % (play['name'], play['pattern'], len(play['hosts']))) + for host in play['hosts']: + print(" %s" % host) + if options.listtasks: #TODO: do we want to display block info? + print("\n %s: task count=%d" % (play['name'], len(play['tasks']))) + for task in play['tasks']: + print(" %s" % task) + if options.listtags: + print("\n %s: tags count=%d" % (play['name'], len(play['tags']))) + for tag in play['tags']: + print(" %s" % tag) else: - return pbex.run() + return results if __name__ == "__main__": #display(" ", log_only=True)