From e4304a0ac5ef777832a2f4db8899507d0d0dfacc Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Fri, 2 Mar 2012 22:38:55 -0500 Subject: [PATCH] Make sure tempdirs are cleaned up after execution steps, fix notifiers, make sure service module is installed by setup.py --- examples/playbook.yml | 2 +- lib/ansible/playbook.py | 3 +- lib/ansible/runner.py | 67 +++++++++++++++++++++-------------------- setup.py | 1 + 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/examples/playbook.yml b/examples/playbook.yml index c097226bc3..188e24fcd7 100644 --- a/examples/playbook.yml +++ b/examples/playbook.yml @@ -4,7 +4,7 @@ - name: configure template & module variables for future template calls action: setup http_port=80 max_clients=200 - name: write the apache config file - action: template src=/srv/httpd.j2 dest=/etc/httpd/conf + action: template src=/srv/httpd.j2 dest=/etc/httpd.conf notify: - restart apache - name: ensure apache is running diff --git a/lib/ansible/playbook.py b/lib/ansible/playbook.py index 92d205ce4d..396ca9ac35 100755 --- a/lib/ansible/playbook.py +++ b/lib/ansible/playbook.py @@ -223,8 +223,7 @@ class PlayBook(object): # for this particular pattern group for x in handlers: - attribs = x["do"] - name = attribs[0] + name = x['name'] if match_name == name: # flag the handler with the list of hosts # it needs to be run on, it will be run later diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 5cdb09e6e1..8d28dfb201 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -153,8 +153,6 @@ class Runner(object): def _return_from_module(self, conn, host, result): ''' helper function to handle JSON parsing of results ''' - # disconnect from paramiko/SSH - conn.close() try: # try to parse the JSON response return [ host, True, json.loads(result) ] @@ -165,7 +163,7 @@ class Runner(object): def _delete_remote_files(self, conn, files): ''' deletes one or more remote files ''' for filename in files: - self._exec_command(conn, "rm -f %s" % filename) + self._exec_command(conn, "rm -rf %s" % filename) def _transfer_file(self, conn, source, dest): ''' transfers a remote file ''' @@ -174,32 +172,34 @@ class Runner(object): sftp.put(source, dest) sftp.close() - def _transfer_module(self, conn): + def _transfer_module(self, conn, tmp): ''' transfers a module file to the remote side to execute it, but does not execute it yet ''' - outpath = self._copy_module(conn) + outpath = self._copy_module(conn, tmp) self._exec_command(conn, "chmod +x %s" % outpath) return outpath - def _execute_module(self, conn, outpath): + def _execute_module(self, conn, outpath, tmp): ''' runs a module that has already been transferred ''' cmd = self._command(outpath) result = self._exec_command(conn, cmd) - self._delete_remote_files(conn, [ outpath ]) + self._delete_remote_files(conn, [ tmp ]) return result - def _execute_normal_module(self, conn, host): + def _execute_normal_module(self, conn, host, tmp): ''' transfer & execute a module that is not 'copy' or 'template' because those require extra work. ''' - module = self._transfer_module(conn) - result = self._execute_module(conn, module) - return self._return_from_module(conn, host, result) + module = self._transfer_module(conn, tmp) + result = self._execute_module(conn, module, tmp) + self._delete_remote_files(conn, tmp) + result = self._return_from_module(conn, host, result) + return result def _parse_kv(self, args): ''' helper function to convert a string of key/value items to a dict ''' @@ -210,7 +210,7 @@ class Runner(object): options[k]=v return options - def _execute_copy(self, conn, host): + def _execute_copy(self, conn, host, tmp): ''' handler for file transfer operations ''' # load up options @@ -219,7 +219,7 @@ class Runner(object): dest = options['dest'] # transfer the file to a remote tmp location - tmp_path = self._get_tmp_path(conn) + tmp_path = tmp tmp_src = tmp_path + source.split('/')[-1] self._transfer_file(conn, source, tmp_src) @@ -229,11 +229,11 @@ class Runner(object): # run the copy module self.module_args = [ "src=%s" % tmp_src, "dest=%s" % dest ] - result = self._execute_module(conn, module) - self._delete_remote_files(conn, tmp_src) + result = self._execute_module(conn, module, tmp) + self._delete_remote_files(conn, tmp_path) return self._return_from_module(conn, host, result) - def _execute_template(self, conn, host): + def _execute_template(self, conn, host, tmp): ''' handler for template operations ''' # load up options @@ -243,18 +243,19 @@ class Runner(object): metadata = options.get('metadata', '/etc/ansible/setup') # first copy the source template over + tpath = tmp tempname = os.path.split(source)[-1] - temppath = self._get_tmp_path(conn) + tempname + temppath = tpath + tempname self._transfer_file(conn, source, temppath) # install the template module self.module_name = 'template' - module = self._transfer_module(conn) + module = self._transfer_module(conn, tmp) # run the template module self.module_args = [ "src=%s" % temppath, "dest=%s" % dest, "metadata=%s" % metadata ] - result = self._execute_module(conn, module) - self._delete_remote_files(conn, [ temppath ]) + result = self._execute_module(conn, module, tmp) + self._delete_remote_files(conn, [ tpath ]) return self._return_from_module(conn, host, result) @@ -271,18 +272,24 @@ class Runner(object): # module, call the appropriate executor function ok, conn = self._connect(host) + tmp = self._get_tmp_path(conn) + result = None if not ok: - return [ host, False, conn ] + result = [ host, False, conn ] if self.module_name not in [ 'copy', 'template' ]: - return self._execute_normal_module(conn, host) + result = self._execute_normal_module(conn, host, tmp) elif self.module_name == 'copy': - return self._execute_copy(conn, host) + result = self._execute_copy(conn, host, tmp) elif self.module_name == 'template': - return self._execute_template(conn, host) + result = self._execute_template(conn, host, tmp) else: # this would be a coding error in THIS module # shouldn't occur raise Exception("???") + self._delete_remote_files(conn, tmp) + conn.close() + return result + def _command(self, outpath): ''' form up a command string for running over SSH ''' @@ -304,19 +311,15 @@ class Runner(object): def _get_tmp_path(self, conn): ''' gets a temporary path on a remote box ''' + result = self._exec_command(conn, "mktemp -d /tmp/ansible.XXXXXX") + return result.split("\n")[0] + '/' - if conn not in self._tmp_paths: - output = self._exec_command(conn, "mktemp -d /tmp/ansible.XXXXXX") - self._tmp_paths[conn] = output.split("\n")[0] + '/' - - return self._tmp_paths[conn] - - def _copy_module(self, conn): + def _copy_module(self, conn, tmp): ''' transfer a module over SFTP, does not run it ''' in_path = os.path.expanduser( os.path.join(self.module_path, self.module_name) ) - out_path = self._get_tmp_path(conn) + self.module_name + out_path = tmp + self.module_name sftp = conn.open_sftp() sftp.put(in_path, out_path) sftp.close() diff --git a/setup.py b/setup.py index 382f188cb9..e501072ee2 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,7 @@ setup(name='ansible', 'library/ohai', 'library/copy', 'library/setup', + 'library/service', 'library/template', 'library/git', ]),