From e7bb41ff890f4e211109134da7b9bffea6fb24f5 Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Fri, 24 Feb 2012 23:25:30 -0500 Subject: [PATCH 1/4] simple logging setup using logger. /usr/bin/logger should probably be a constant or defined in some sort of config as well as the log priority --- lib/ansible/runner.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 2517e51455b..fddac73919d 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -120,6 +120,7 @@ class Runner(object): return [ host, True, json.loads(result) ] else: # SFTP file copy module is not really a module + self.remote_log(conn, 'COPY remote:%s local:%s' % (self.module_args[0], self.module_args[1])) ftp = conn.open_sftp() ftp.put(self.module_args[0], self.module_args[1]) ftp.close() @@ -132,8 +133,14 @@ class Runner(object): cmd = "%s %s" % (outpath, " ".join(self.module_args)) return cmd + + def remote_log(self, conn, msg): + stdin, stdout, stderr = conn.exec_command('/usr/bin/logger -t ansible -p auth.info %r' % msg) + def _exec_command(self, conn, cmd): ''' execute a command over SSH ''' + msg = '%s: %s' % (self.module_name, cmd) + self.remote_log(conn, msg) stdin, stdout, stderr = conn.exec_command(cmd) results = "\n".join(stdout.readlines()) return results From ee95a5b0a406b93fd81e8a0d70ff9ebfd3299332 Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Fri, 24 Feb 2012 23:35:09 -0500 Subject: [PATCH 2/4] use shlex.split() instead of split() to keep quoting sane for commands --- bin/ansible | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/ansible b/bin/ansible index 92316fcd67b..448ef0f5a73 100755 --- a/bin/ansible +++ b/bin/ansible @@ -25,6 +25,7 @@ from optparse import OptionParser import json import os import getpass +import shlex import ansible.runner import ansible.playbook import ansible.constants as C @@ -68,7 +69,7 @@ class Cli(object): return ansible.runner.Runner( module_name=options.module_name, module_path=options.module_path, - module_args=options.module_args.split(' '), + module_args=shlex.split(options.module_args), remote_user=options.remote_user, remote_pass=sshpass, host_list=options.host_list, From edb968305092e246bfc0525e9a90f25496b31a5a Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Sat, 25 Feb 2012 01:00:37 -0500 Subject: [PATCH 3/4] touch up the example API code --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e683493662a..34380744e94 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,8 @@ track of which hosts were successfully contacted seperately from hosts that had communication problems. The format of the return, if successful, is entirely up to the module. - import ansible + + import ansible.runner runner = ansible.runner.Runner( pattern='*', module_name='inventory', @@ -91,6 +92,7 @@ is entirely up to the module. ) data = runner.run() +data is a dictionary: { 'contacted' : { 'xyz.example.com' : [ 'any kind of datastructure is returnable' ], From 160470bc49cd47abe8ba42b04ee6bae8eb91d705 Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Sat, 25 Feb 2012 01:06:18 -0500 Subject: [PATCH 4/4] - add match_hosts() method to runner.Runner() - add pattern parameter to self._matches() and match_hosts() so you can query for matches against the host list - these are useful when writing scripts and you want to tell the user what hosts you will be running on before actually executing anything. --- lib/ansible/runner.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index fddac73919d..ed0d184dd0a 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -73,11 +73,13 @@ class Runner(object): return host_list - def _matches(self, host_name): + def _matches(self, host_name, pattern=None): ''' returns if a hostname is matched by the pattern ''' if host_name == '': return False - if fnmatch.fnmatch(host_name, self.pattern): + if not pattern: + pattern = self.pattern + if fnmatch.fnmatch(host_name, pattern): return True return False @@ -161,11 +163,15 @@ class Runner(object): sftp.close() return out_path + def match_hosts(self, pattern=None): + ''' return all matched hosts ''' + return [ h for h in self.host_list if self._matches(h, pattern) ] + def run(self): ''' xfer & run module on all matched hosts ''' # find hosts that match the pattern - hosts = [ h for h in self.host_list if self._matches(h) ] + hosts = self.match_hosts() # attack pool of hosts in N forks pool = multiprocessing.Pool(self.forks)