#!/usr/bin/env python # (c) 2012, Stephen Fromm # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . import os import sys import socket import logging import ansible.playbook import ansible.runner import ansible.constants as C from ansible import errors from ansible import callbacks from ansible import utils from ansible import inventory DEFAULT_PLAYBOOK = 'local.yml' def main(args): """ Set up and run a local playbook """ usage = "%prog [options]" parser = utils.base_parser(constants=C, usage=usage, connect_opts=False, runas_opts=False) parser.set_defaults(module_name='git', transport='local', one_line=False, tree=None) parser.add_option('-d', '--directory', dest='dest', default=None, help='Directory to checkout git repository') parser.add_option('-U', '--url', dest='url', default=None, help='URL of git repository') parser.add_option('-C', '--checkout', dest='checkout', default="HEAD", help='Branch/Tag/Commit to checkout. Defaults to HEAD.') parser.remove_option('-k') # Remove ssh password option parser.remove_option('-K') # Remove sudo password option parser.remove_option('-T') # Remove ssh timeout option options, args = parser.parse_args(args) clirunner_cb = callbacks.CliRunnerCallbacks() clirunner_cb.options = options # ---------------------------------------------- # First git clone/pull git_opts = "repo=%s dest=%s version=%s" % (options.url, options.dest, options.checkout) pattern = "localhost" inventory_manager = inventory.Inventory([pattern]) """ Ideally, changes should be reported via logging and not to STDOUT """ runner = ansible.runner.Runner( module_name=options.module_name, module_args=git_opts, module_path=options.module_path, inventory=inventory_manager, forks=options.forks, pattern=pattern, callbacks=clirunner_cb, transport=options.transport, debug=options.debug ) try: runner.run() except errors.AnsibleError, e: print >>sys.stderr, "ERROR: %s" % e return 1 # ---------------------------------------------- # Second, run the playbook """ Change to the directory where the git checkout is located. Insert 'local.yml' as the first playbook to be run. This supports multiple playbooks being supplied on the CLI, similar to ansible-playbook. This then loops on all the playbooks, instantiates and runs a playbook. A couple things of note: * The transport uses the default set above, local * The host_list argument to Playbook is set to a list of names. These are localhost, the fqdn, and hostname. This last point is problematic because it will run a playbook 3 times if the playbook is for 'all' hosts. We do not necessarily want to override 'hosts' in the playbook because they may be generic across the entire infrastructure -- not host specific. Finally, this should use the logging module in some manner and not print data to STDOUT. """ if os.path.exists("%s/%s" % (options.dest, DEFAULT_PLAYBOOK)): args.insert(0, DEFAULT_PLAYBOOK) os.chdir(options.dest) hostname = socket.getfqdn() stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks() pbrunner_cb = callbacks.PlaybookRunnerCallbacks(stats) local_host = [pattern, hostname, hostname.split('.')[0]] for playbook in args: pb = ansible.playbook.PlayBook( playbook=playbook, host_list=local_host, module_path=options.module_path, debug=options.debug, runner_callbacks=pbrunner_cb, callbacks=playbook_cb, transport=options.transport, stats=stats ) """ This just takes the reporting from ansible-playbook. Ideally, this should use logging to report success/failure/changes. """ try: pb.run() hosts = sorted(pb.stats.processed.keys()) print "RECAP\n\n" for h in hosts: t = pb.stats.summarize(h) print "%-30s : ok=%4s changed=%4s unreachable=%4s failed=%4s " % (h, t['ok'], t['changed'], t['unreachable'], t['failures'] ) print "\n" except errors.AnsibleError, e: print >>sys.stderr, "ERROR: %s" % e return 1 return 0 if __name__ == '__main__': try: sys.exit(main(sys.argv[1:])) except errors.AnsibleError, e: print >>sys.stderr, "ERROR: %s" % e sys.exit(1)