From b053df41822a7304fa814612200b4b31b6d53141 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 5 Feb 2012 12:48:52 -0500 Subject: [PATCH] Some refactoring of runner.py -- more to come to eliminate repeated code --- lib/ansible/runner.py | 170 ++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 91 deletions(-) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index b202cc1f616..e1b1ee252ba 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -98,111 +98,99 @@ class Runner(object): except: return [ False, traceback.format_exc() ] - def _executor(self, host): - ''' - callback executed in parallel for each host. - returns (hostname, connected_ok, extra) - where extra is the result of a successful connect - or a traceback string - ''' - # TODO: try/catch around JSON handling + def _return_from_module(self, conn, host, result): + conn.close() + try: + return [ host, True, json.loads(result) ] + except: + return [ host, False, result ] - ok, conn = self._connect(host) - if not ok: - return [ host, False, conn ] + def _delete_remote_files(self, conn, files): + for filename in files: + self._exec_command(conn, "rm -f %s" % filename) - if self.module_name not in [ 'copy', 'template' ]: - # transfer a module, set it executable, and run it - outpath = self._copy_module(conn) - self._exec_command(conn, "chmod +x %s" % outpath) - cmd = self._command(outpath) - result = self._exec_command(conn, cmd) - self._exec_command(conn, "rm -f %s" % outpath) - conn.close() - try: - return [ host, True, json.loads(result) ] - except: - return [ host, False, result ] + def _execute_normal_module(self, conn, host): + ''' transfer a module, set it executable, and run it ''' - elif self.module_name == 'copy': + outpath = self._copy_module(conn) + self._exec_command(conn, "chmod +x %s" % outpath) + cmd = self._command(outpath) + result = self._exec_command(conn, cmd) + self._delete_remote_files(conn, outpath) + return self._return_from_module(conn, host, result) - # TODO: major refactoring pending - # do sftp then run actual copy module to get change info + def _execute_copy(self, conn, host): + ''' transfer a file + copy module, run copy module, clean up ''' - self.remote_log(conn, 'COPY remote:%s local:%s' % (self.module_args[0], self.module_args[1])) - source = self.module_args[0] - dest = self.module_args[1] - tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1]) + self.remote_log(conn, 'COPY remote:%s local:%s' % (self.module_args[0], self.module_args[1])) + source = self.module_args[0] + dest = self.module_args[1] + tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1]) - ftp = conn.open_sftp() - ftp.put(source, tmp_dest) - ftp.close() + ftp = conn.open_sftp() + ftp.put(source, tmp_dest) + ftp.close() - # install the copy module + # install the copy module - self.module_name = 'copy' - outpath = self._copy_module(conn) - self._exec_command(conn, "chmod +x %s" % outpath) + self.module_name = 'copy' + outpath = self._copy_module(conn) + self._exec_command(conn, "chmod +x %s" % outpath) - # run the copy module + # run the copy module - self.module_args = [ tmp_dest, dest ] - cmd = self._command(outpath) - result = self._exec_command(conn, cmd) - - # remove the module - self._exec_command(conn, "rm -f %s" % outpath) - # remove the temp file - self._exec_command(conn, "rm -f %s" % tmp_dest) + self.module_args = [ tmp_dest, dest ] + cmd = self._command(outpath) + result = self._exec_command(conn, cmd) + self._delete_remote_files(conn, [outpath, tmp_dest]) + + return self._return_from_module(conn, host, result) + + def _execute_template(self, conn, host): + source = self.module_args[0] + dest = self.module_args[1] + metadata = '/etc/ansible/setup' - conn.close() - try: - return [ host, True, json.loads(result) ] - except: - traceback.print_exc() - return [ host, False, result ] + # first copy the source template over + tempname = os.path.split(source)[-1] + temppath = self._get_tmp_path(conn, tempname) + self.remote_log(conn, 'COPY remote:%s local:%s' % (source, temppath)) + ftp = conn.open_sftp() + ftp.put(source, temppath) + ftp.close() - return [ host, True, 1 ] + # install the template module + self.module_name = 'template' + outpath = self._copy_module(conn) + self._exec_command(conn, "chmod +x %s" % outpath) + # run the template module + self.module_args = [ temppath, dest, metadata ] + result = self._exec_command(conn, self._command(outpath)) + # clean up + self._delete_remote_files(conn, [ outpath, temppath ]) + return self._return_from_module(conn, host, result) + + + def _executor(self, host): + ''' + callback executed in parallel for each host. + returns (hostname, connected_ok, extra) + where extra is the result of a successful connect + or a traceback string + ''' + + ok, conn = self._connect(host) + if not ok: + return [ host, False, conn ] + if self.module_name not in [ 'copy', 'template' ]: + return self._execute_normal_module(conn, host) + elif self.module_name == 'copy': + return self._execute_copy(conn, host) elif self.module_name == 'template': - # template runs COPY then the template module - # TODO: DRY/refactor these - # TODO: things like _copy_module should take the name as a param - # TODO: make it possible to override the /etc/ansible/setup file - # location for templating files as non-root - - source = self.module_args[0] - dest = self.module_args[1] - metadata = '/etc/ansible/setup' - - # first copy the source template over - tempname = os.path.split(source)[-1] - temppath = self._get_tmp_path(conn, tempname) - self.remote_log(conn, 'COPY remote:%s local:%s' % (source, temppath)) - ftp = conn.open_sftp() - ftp.put(source, temppath) - ftp.close() - - # install the template module - self.module_name = 'template' - outpath = self._copy_module(conn) - self._exec_command(conn, "chmod +x %s" % outpath) - - # run the template module - self.module_args = [ temppath, dest, metadata ] - result = self._exec_command(conn, self._command(outpath)) - # clean up - self._exec_command(conn, "rm -f %s" % outpath) - self._exec_command(conn, "rm -f %s" % temppath) - - conn.close() - try: - return [ host, True, json.loads(result) ] - except: - traceback.print_exc() - return [ host, False, result ] - - return [ host, False, 1 ] + return self._execute_template(conn, host) + else: + raise Exception("???") def _command(self, outpath): ''' form up a command string '''