From a7a03bbf4a7e4d76e2665eade8170fc70c927ab7 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Thu, 15 Feb 2018 09:01:02 -0800 Subject: [PATCH] Normalize usage of temp and tmp on tmp (#36221) * Normalize usage of temp and tmp on tmp * Rename system_tmps system_tmpdirs * Add ANSIBLE_REMOTE_TMP spelling of environment variables (cherry picked from commit 06f73ad578d840c7ea5875b7cd4ffd08e2d9d0e8) --- CHANGELOG.md | 3 + bin/ansible | 2 +- lib/ansible/module_utils/basic.py | 8 +-- lib/ansible/module_utils/urls.py | 5 +- lib/ansible/plugins/action/__init__.py | 64 +++++++++---------- lib/ansible/plugins/action/assemble.py | 6 +- lib/ansible/plugins/action/command.py | 2 +- lib/ansible/plugins/action/copy.py | 8 +-- lib/ansible/plugins/action/fetch.py | 2 +- lib/ansible/plugins/action/normal.py | 2 +- lib/ansible/plugins/action/package.py | 2 +- lib/ansible/plugins/action/patch.py | 4 +- lib/ansible/plugins/action/script.py | 5 +- lib/ansible/plugins/action/service.py | 2 +- lib/ansible/plugins/action/template.py | 2 +- lib/ansible/plugins/action/unarchive.py | 6 +- lib/ansible/plugins/action/win_copy.py | 14 ++-- lib/ansible/plugins/shell/__init__.py | 30 ++++----- lib/ansible/plugins/shell/powershell.py | 4 +- .../module_docs_fragments/shell_common.py | 14 ++-- .../async_fail/action_plugins/normal.py | 2 +- test/units/plugins/action/test_action.py | 4 +- 22 files changed, 99 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd6df369388..a8b905eb365 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,9 @@ See [Porting Guide](http://docs.ansible.com/ansible/devel/porting_guides.html) f * Task debugger functionality was moved into `StrategyBase`, and extended to allow explicit invocation from use of the `debugger` keyword. The `debug` strategy is still functional, and is now just a trigger to enable this functionality * Reorganized the documentation into distinct guides for different target audiences. +* The ANSIBLE_REMOTE_TMP environment variable has been added to supplement (and + override) ANSIBLE_REMOTE_TEMP. This matches with the spelling of the config + value. ANSIBLE_REMOTE_TEMP will be deprecated in the future. #### Removed Modules (previously deprecated): * accelerate. diff --git a/bin/ansible b/bin/ansible index c3d96201158..cc4bfd7a694 100755 --- a/bin/ansible +++ b/bin/ansible @@ -157,7 +157,7 @@ if __name__ == '__main__': display.display(u"the full traceback was:\n\n%s" % to_text(traceback.format_exc()), log_only=log_only) exit_code = 250 finally: - # Remove ansible tempdir + # Remove ansible tmpdir shutil.rmtree(C.DEFAULT_LOCAL_TMP, True) sys.exit(exit_code) diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 3a8fa29249a..a7cf24ab70f 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -47,7 +47,7 @@ PASS_VARS = { 'shell_executable': '_shell', 'socket': '_socket_path', 'syslog_facility': '_syslog_facility', - 'tempdir': 'tempdir', + 'tmpdir': 'tmpdir', 'verbosity': '_verbosity', 'version': 'ansible_version', } @@ -2199,7 +2199,7 @@ class AnsibleModule(object): except: # we don't have access to the cwd, probably because of sudo. # Try and move to a neutral location to prevent errors - for cwd in [self.tempdir, os.path.expandvars('$HOME'), tempfile.gettempdir()]: + for cwd in [self.tmpdir, os.path.expandvars('$HOME'), tempfile.gettempdir()]: try: if os.access(cwd, os.F_OK | os.R_OK): os.chdir(cwd) @@ -2511,7 +2511,7 @@ class AnsibleModule(object): # would end in something like: # file = _os.path.join(dir, pre + name + suf) # TypeError: can't concat bytes to str - error_msg = ('Failed creating temp file for atomic move. This usually happens when using Python3 less than Python3.5. ' + error_msg = ('Failed creating tmp file for atomic move. This usually happens when using Python3 less than Python3.5. ' 'Please use Python2.x or Python3.5 or greater.') finally: if error_msg: @@ -2531,7 +2531,7 @@ class AnsibleModule(object): try: shutil.move(b_src, b_tmp_dest_name) except OSError: - # cleanup will happen by 'rm' of tempdir + # cleanup will happen by 'rm' of tmpdir # copy2 will preserve some metadata shutil.copy2(b_src, b_tmp_dest_name) diff --git a/lib/ansible/module_utils/urls.py b/lib/ansible/module_utils/urls.py index e0347035c88..d4de90edb16 100644 --- a/lib/ansible/module_utils/urls.py +++ b/lib/ansible/module_utils/urls.py @@ -988,7 +988,8 @@ def fetch_url(module, url, data=None, headers=None, method=None, module.fail_json(msg='urlparse is not installed') # ensure we use proper tempdir - tempfile.tempdir = module.tempdir + old_tempdir = tempfile.tempdir + tempfile.tempdir = module.tmpdir # Get validate_certs from the module params validate_certs = module.params.get('validate_certs', True) @@ -1052,5 +1053,7 @@ def fetch_url(module, url, data=None, headers=None, method=None, except Exception as e: info.update(dict(msg="An unknown error occurred: %s" % to_native(e), status=-1), exception=traceback.format_exc()) + finally: + tempfile.tempdir = old_tempdir return r, info diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index 7ab5be7cd0f..0e037135884 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -68,7 +68,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): :kwarg tmp: Deprecated parameter. This is no longer used. An action plugin that calls another one and wants to use the same remote tmp for both should set - self._connection._shell.tempdir rather than this parameter. + self._connection._shell.tmpdir rather than this parameter. :kwarg task_vars: The variables (host vars, group vars, config vars, etc) associated with this task. :returns: dictionary of results from the module @@ -82,8 +82,8 @@ class ActionBase(with_metaclass(ABCMeta, object)): if tmp is not None: result['warning'] = ['ActionModule.run() no longer honors the tmp parameter. Action' - ' plugins should set self._connection._shell.tempdir to share' - ' the tempdir'] + ' plugins should set self._connection._shell.tmpdir to share' + ' the tmpdir'] del tmp if self._task.async_val and not self._supports_async: @@ -93,7 +93,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): elif self._task.async_val and self._play_context.check_mode: raise AnsibleActionFail('check mode and async cannot be used on same task.') - if self._connection._shell.tempdir is None and self._early_needs_tmp_path(): + if self._connection._shell.tmpdir is None and self._early_needs_tmp_path(): self._make_tmp_path() return result @@ -201,7 +201,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): def _early_needs_tmp_path(self): ''' - Determines if a temp path should be created before the action is executed. + Determines if a tmp path should be created before the action is executed. ''' return getattr(self, 'TRANSFERS_FILES', False) @@ -239,7 +239,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): except KeyError: admin_users = ['root', remote_user] # plugin does not support admin_users try: - remote_tmp = self._connection._shell.get_option('remote_temp') + remote_tmp = self._connection._shell.get_option('remote_tmp') except KeyError: remote_tmp = '~/ansible' @@ -267,7 +267,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): else: output = ('Authentication or permission failure. ' 'In some cases, you may have been able to authenticate and did not have permissions on the target directory. ' - 'Consider changing the remote temp path in ansible.cfg to a path rooted in "/tmp". ' + 'Consider changing the remote tmp path in ansible.cfg to a path rooted in "/tmp". ' 'Failed command was: %s, exited with result %d' % (cmd, result['rc'])) if 'stdout' in result and result['stdout'] != u'': output = output + u", stdout output: %s" % result['stdout'] @@ -289,10 +289,10 @@ class ActionBase(with_metaclass(ABCMeta, object)): if rc == '/': raise AnsibleError('failed to resolve remote temporary directory from %s: `%s` returned empty string' % (basefile, cmd)) - self._connection._shell.tempdir = rc + self._connection._shell.tmpdir = rc if not use_system_tmp: - self._connection._shell.env.update({'ANSIBLE_REMOTE_TEMP': self._connection._shell.tempdir}) + self._connection._shell.env.update({'ANSIBLE_REMOTE_TMP': self._connection._shell.tmpdir}) return rc def _should_remove_tmp_path(self, tmp_path): @@ -302,8 +302,8 @@ class ActionBase(with_metaclass(ABCMeta, object)): def _remove_tmp_path(self, tmp_path): '''Remove a temporary path we created. ''' - if tmp_path is None and self._connection._shell.tempdir: - tmp_path = self._connection._shell.tempdir + if tmp_path is None and self._connection._shell.tmpdir: + tmp_path = self._connection._shell.tmpdir if self._should_remove_tmp_path(tmp_path): cmd = self._connection._shell.remove(tmp_path, recurse=True) @@ -316,7 +316,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): display.warning('Error deleting remote temporary files (rc: %s, stderr: %s})' % (tmp_rm_res.get('rc'), tmp_rm_res.get('stderr', 'No error string available.'))) else: - self._connection._shell.tempdir = None + self._connection._shell.tmpdir = None def _transfer_file(self, local_path, remote_path): self._connection.put_file(local_path, remote_path) @@ -493,8 +493,8 @@ class ActionBase(with_metaclass(ABCMeta, object)): ''' if tmp is not None: display.warning('_execute_remote_stat no longer honors the tmp parameter. Action' - ' plugins should set self._connection._shell.tempdir to share' - ' the tempdir') + ' plugins should set self._connection._shell.tmpdir to share' + ' the tmpdir') del tmp # No longer used module_args = dict( @@ -647,7 +647,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): module_args['_ansible_shell_executable'] = self._play_context.executable # make sure all commands use the designated temporary directory - module_args['_ansible_tempdir'] = self._connection._shell.tempdir + module_args['_ansible_tmpdir'] = self._connection._shell.tmpdir def _update_connection_options(self, options, variables=None): ''' ensures connections have the appropriate information ''' @@ -670,12 +670,12 @@ class ActionBase(with_metaclass(ABCMeta, object)): ''' if tmp is not None: display.warning('_execute_module no longer honors the tmp parameter. Action plugins' - ' should set self._connection._shell.tempdir to share the tempdir') + ' should set self._connection._shell.tmpdir to share the tmpdir') del tmp # No longer used if delete_remote_tmp is not None: display.warning('_execute_module no longer honors the delete_remote_tmp parameter.' - ' Action plugins should check self._connection._shell.tempdir to' - ' see if a tempdir existed before they were called to determine' + ' Action plugins should check self._connection._shell.tmpdir to' + ' see if a tmpdir existed before they were called to determine' ' if they are responsible for removing it.') del delete_remote_tmp # No longer used @@ -696,22 +696,22 @@ class ActionBase(with_metaclass(ABCMeta, object)): if not shebang and module_style != 'binary': raise AnsibleError("module (%s) is missing interpreter line" % module_name) - tempdir = self._connection._shell.tempdir + tmpdir = self._connection._shell.tmpdir remote_module_path = None if not self._is_pipelining_enabled(module_style, wrap_async): - # we might need remote temp dir - if tempdir is None: + # we might need remote tmp dir + if tmpdir is None: self._make_tmp_path() - tempdir = self._connection._shell.tempdir + tmpdir = self._connection._shell.tmpdir remote_module_filename = self._connection._shell.get_remote_filename(module_path) - remote_module_path = self._connection._shell.join_path(tempdir, remote_module_filename) + remote_module_path = self._connection._shell.join_path(tmpdir, remote_module_filename) args_file_path = None if module_style in ('old', 'non_native_want_json', 'binary'): - # we'll also need a temp file to hold our module arguments - args_file_path = self._connection._shell.join_path(tempdir, 'args') + # we'll also need a tmp file to hold our module arguments + args_file_path = self._connection._shell.join_path(tmpdir, 'args') if remote_module_path or module_style != 'new': display.debug("transferring module to remote %s" % remote_module_path) @@ -733,8 +733,8 @@ class ActionBase(with_metaclass(ABCMeta, object)): environment_string = self._compute_environment_string() remote_files = [] - if tempdir and remote_module_path: - remote_files = [tempdir, remote_module_path] + if tmpdir and remote_module_path: + remote_files = [tmpdir, remote_module_path] if args_file_path: remote_files.append(args_file_path) @@ -748,7 +748,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): (async_module_style, shebang, async_module_data, async_module_path) = self._configure_module(module_name='async_wrapper', module_args=dict(), task_vars=task_vars) async_module_remote_filename = self._connection._shell.get_remote_filename(async_module_path) - remote_async_module_path = self._connection._shell.join_path(tempdir, async_module_remote_filename) + remote_async_module_path = self._connection._shell.join_path(tmpdir, async_module_remote_filename) self._transfer_data(remote_async_module_path, async_module_data) remote_files.append(remote_async_module_path) @@ -770,7 +770,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): # maintain a fixed number of positional parameters for async_wrapper async_cmd.append('_') - if not self._should_remove_tmp_path(tempdir): + if not self._should_remove_tmp_path(tmpdir): async_cmd.append("-preserve_tmp") cmd = " ".join(to_text(x) for x in async_cmd) @@ -784,7 +784,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): cmd = self._connection._shell.build_module_command(environment_string, shebang, cmd, arg_path=args_file_path).strip() - # Fix permissions of the tempdir path and tempdir files. This should be called after all + # Fix permissions of the tmpdir path and tmpdir files. This should be called after all # files have been transferred. if remote_files: # remove none/empty @@ -806,9 +806,9 @@ class ActionBase(with_metaclass(ABCMeta, object)): remove_internal_keys(data) if wrap_async: - # async_wrapper will clean up its tempdir on its own so we want the controller side to + # async_wrapper will clean up its tmpdir on its own so we want the controller side to # forget about it now - self._connection._shell.tempdir = None + self._connection._shell.tmpdir = None # FIXME: for backwards compat, figure out if still makes sense data['changed'] = True diff --git a/lib/ansible/plugins/action/assemble.py b/lib/ansible/plugins/action/assemble.py index 499943e0d99..8b69026a76f 100644 --- a/lib/ansible/plugins/action/assemble.py +++ b/lib/ansible/plugins/action/assemble.py @@ -147,11 +147,11 @@ class ActionModule(ActionBase): if self._play_context.diff: diff = self._get_diff_data(dest, path, task_vars) - remote_path = self._connection._shell.join_path(self._connection._shell.tempdir, 'src') + remote_path = self._connection._shell.join_path(self._connection._shell.tmpdir, 'src') xfered = self._transfer_file(path, remote_path) # fix file permissions when the copy is done as a different user - self._fixup_perms2((self._connection._shell.tempdir, remote_path)) + self._fixup_perms2((self._connection._shell.tmpdir, remote_path)) new_module_args.update(dict(src=xfered,)) @@ -165,6 +165,6 @@ class ActionModule(ActionBase): except AnsibleAction as e: result.update(e.result) finally: - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/command.py b/lib/ansible/plugins/action/command.py index 7b263f6b28d..79f1a7ff034 100644 --- a/lib/ansible/plugins/action/command.py +++ b/lib/ansible/plugins/action/command.py @@ -25,6 +25,6 @@ class ActionModule(ActionBase): if not wrap_async: # remove a temporary path we created - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return results diff --git a/lib/ansible/plugins/action/copy.py b/lib/ansible/plugins/action/copy.py index 28c606fb6cd..887901bbf6c 100644 --- a/lib/ansible/plugins/action/copy.py +++ b/lib/ansible/plugins/action/copy.py @@ -258,7 +258,7 @@ class ActionModule(ActionBase): return result # Define a remote directory that we will copy the file to. - tmp_src = self._connection._shell.join_path(self._connection._shell.tempdir, 'source') + tmp_src = self._connection._shell.join_path(self._connection._shell.tmpdir, 'source') remote_path = None @@ -273,7 +273,7 @@ class ActionModule(ActionBase): # fix file permissions when the copy is done as a different user if remote_path: - self._fixup_perms2((self._connection._shell.tempdir, remote_path)) + self._fixup_perms2((self._connection._shell.tmpdir, remote_path)) if raw: # Continue to next iteration if raw is defined. @@ -417,7 +417,7 @@ class ActionModule(ActionBase): # Define content_tempfile in case we set it after finding content populated. content_tempfile = None - # If content is defined make a temp file and write the content into it. + # If content is defined make a tmp file and write the content into it. if content is not None: try: # If content comes to us as a dict it should be decoded json. @@ -549,6 +549,6 @@ class ActionModule(ActionBase): result.update(dict(dest=dest, src=source, changed=changed)) # Delete tmp path - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/fetch.py b/lib/ansible/plugins/action/fetch.py index 64f81a1032b..bc07d6a4fa1 100644 --- a/lib/ansible/plugins/action/fetch.py +++ b/lib/ansible/plugins/action/fetch.py @@ -213,6 +213,6 @@ class ActionModule(ActionBase): result.update(dict(changed=False, md5sum=local_md5, file=source, dest=dest, checksum=local_checksum)) finally: - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/normal.py b/lib/ansible/plugins/action/normal.py index 3b73174a0cd..766cebc5a36 100644 --- a/lib/ansible/plugins/action/normal.py +++ b/lib/ansible/plugins/action/normal.py @@ -52,6 +52,6 @@ class ActionModule(ActionBase): if not wrap_async: # remove a temporary path we created - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/package.py b/lib/ansible/plugins/action/package.py index 0e220318057..964d077eabb 100644 --- a/lib/ansible/plugins/action/package.py +++ b/lib/ansible/plugins/action/package.py @@ -77,6 +77,6 @@ class ActionModule(ActionBase): finally: if not self._task.async_val: # remove a temporary path we created - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/patch.py b/lib/ansible/plugins/action/patch.py index d2d9dc10fd0..535b9720f5b 100644 --- a/lib/ansible/plugins/action/patch.py +++ b/lib/ansible/plugins/action/patch.py @@ -53,7 +53,7 @@ class ActionModule(ActionBase): except AnsibleError as e: raise AnsibleActionFail(to_native(e)) - tmp_src = self._connection._shell.join_path(self._connection._shell.tempdir, os.path.basename(src)) + tmp_src = self._connection._shell.join_path(self._connection._shell.tmpdir, os.path.basename(src)) self._transfer_file(src, tmp_src) self._fixup_perms2((tmp_src,)) @@ -68,5 +68,5 @@ class ActionModule(ActionBase): except AnsibleAction as e: result.update(e.result) finally: - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/script.py b/lib/ansible/plugins/action/script.py index 83ab129cd0c..a1c474ce6b2 100644 --- a/lib/ansible/plugins/action/script.py +++ b/lib/ansible/plugins/action/script.py @@ -89,7 +89,8 @@ class ActionModule(ActionBase): if not self._play_context.check_mode: # transfer the file to a remote tmp location - tmp_src = self._connection._shell.join_path(self._connection._shell.tempdir, os.path.basename(source)) + tmp_src = self._connection._shell.join_path(self._connection._shell.tmpdir, + os.path.basename(source)) # Convert raw_params to text for the purpose of replacing the script since # parts and tmp_src are both unicode strings and raw_params will be different @@ -133,6 +134,6 @@ class ActionModule(ActionBase): except AnsibleAction as e: result.update(e.result) finally: - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/service.py b/lib/ansible/plugins/action/service.py index 12893b2656e..fc084194c1b 100644 --- a/lib/ansible/plugins/action/service.py +++ b/lib/ansible/plugins/action/service.py @@ -85,6 +85,6 @@ class ActionModule(ActionBase): result.update(e.result) finally: if not self._task.async_val: - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/template.py b/lib/ansible/plugins/action/template.py index 71bcb8da9d5..7e625bee5db 100644 --- a/lib/ansible/plugins/action/template.py +++ b/lib/ansible/plugins/action/template.py @@ -162,6 +162,6 @@ class ActionModule(ActionBase): except AnsibleAction as e: result.update(e.result) finally: - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/unarchive.py b/lib/ansible/plugins/action/unarchive.py index e0610f93b28..8686c2ac3a0 100644 --- a/lib/ansible/plugins/action/unarchive.py +++ b/lib/ansible/plugins/action/unarchive.py @@ -84,7 +84,7 @@ class ActionModule(ActionBase): if not remote_src: # transfer the file to a remote tmp location - tmp_src = self._connection._shell.join_path(self._connection._shell.tempdir, 'source') + tmp_src = self._connection._shell.join_path(self._connection._shell.tmpdir, 'source') self._transfer_file(source, tmp_src) # handle diff mode client side @@ -92,7 +92,7 @@ class ActionModule(ActionBase): if not remote_src: # fix file permissions when the copy is done as a different user - self._fixup_perms2((self._connection._shell.tempdir, tmp_src)) + self._fixup_perms2((self._connection._shell.tmpdir, tmp_src)) # Build temporary module_args. new_module_args = self._task.args.copy() new_module_args.update( @@ -120,5 +120,5 @@ class ActionModule(ActionBase): except AnsibleAction as e: result.update(e.result) finally: - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/action/win_copy.py b/lib/ansible/plugins/action/win_copy.py index a29ef4e9e3c..3b4616c7551 100644 --- a/lib/ansible/plugins/action/win_copy.py +++ b/lib/ansible/plugins/action/win_copy.py @@ -374,7 +374,7 @@ class ActionModule(ActionBase): source = content_tempfile except Exception as err: result['failed'] = True - result['msg'] = "could not write content temp file: %s" % to_native(err) + result['msg'] = "could not write content tmp file: %s" % to_native(err) return result # all actions should occur on the remote server, run win_copy module elif remote_src: @@ -487,15 +487,15 @@ class ActionModule(ActionBase): result.update(query_return) return result - if len(query_return['files']) > 0 or len(query_return['directories']) > 0 and self._connection._shell.tempdir is None: - self._connection._shell.tempdir = self._make_tmp_path() + if len(query_return['files']) > 0 or len(query_return['directories']) > 0 and self._connection._shell.tmpdir is None: + self._connection._shell.tmpdir = self._make_tmp_path() if len(query_return['files']) == 1 and len(query_return['directories']) == 0: # we only need to copy 1 file, don't mess around with zips file_src = query_return['files'][0]['src'] file_dest = query_return['files'][0]['dest'] copy_result = self._copy_single_file(file_src, dest, file_dest, - task_vars, self._connection._shell.tempdir) + task_vars, self._connection._shell.tmpdir) result['changed'] = True if copy_result.get('failed') is True: @@ -507,14 +507,14 @@ class ActionModule(ActionBase): # TODO: handle symlinks result.update(self._copy_zip_file(dest, source_files['files'], source_files['directories'], - task_vars, self._connection._shell.tempdir)) + task_vars, self._connection._shell.tmpdir)) result['changed'] = True else: # no operations need to occur result['failed'] = False result['changed'] = False - # remove the content temp file and remote tmp file if it was created + # remove the content tmp file and remote tmp file if it was created self._remove_tempfile_if_content_defined(content, content_tempfile) - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/lib/ansible/plugins/shell/__init__.py b/lib/ansible/plugins/shell/__init__.py index 80d90a34ae6..0c035b1c54d 100644 --- a/lib/ansible/plugins/shell/__init__.py +++ b/lib/ansible/plugins/shell/__init__.py @@ -45,21 +45,21 @@ class ShellBase(AnsiblePlugin): 'LC_ALL': module_locale, 'LC_MESSAGES': module_locale} - self.tempdir = None + self.tmpdir = None - def _normalize_system_temps(self): - # Normalize the temp directory strings. We don't use expanduser/expandvars because those + def _normalize_system_tmpdirs(self): + # Normalize the tmp directory strings. We don't use expanduser/expandvars because those # can vary between remote user and become user. Therefore the safest practice will be for # this to always be specified as full paths) - normalized_paths = [d.rstrip('/') for d in self.get_option('system_temps')] + normalized_paths = [d.rstrip('/') for d in self.get_option('system_tmpdirs')] - # Make sure all system_temps are absolute otherwise they'd be relative to the login dir + # Make sure all system_tmpdirs are absolute otherwise they'd be relative to the login dir # which is almost certainly going to fail in a cornercase. if not all(os.path.isabs(d) for d in normalized_paths): - raise AnsibleError('The configured system_temps contains a relative path: {0}. All' - ' system_temps must be absolute'.format(to_native(normalized_paths))) + raise AnsibleError('The configured system_tmpdirs contains a relative path: {0}. All' + ' system_tmpdirs must be absolute'.format(to_native(normalized_paths))) - self.set_option('system_temps', normalized_paths) + self.set_option('system_tmpdirs', normalized_paths) def set_options(self, task_keys=None, var_options=None, direct=None): @@ -70,9 +70,9 @@ class ShellBase(AnsiblePlugin): # We can remove the try: except in the future when we make ShellBase a proper subset of # *all* shells. Right now powershell and third party shells which do not use the - # shell_common documentation fragment (and so do not have system_temps) will fail + # shell_common documentation fragment (and so do not have system_tmpdirs) will fail try: - self._normalize_system_temps() + self._normalize_system_tmpdirs() except AnsibleError: pass @@ -128,10 +128,10 @@ class ShellBase(AnsiblePlugin): basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48)) # When system is specified we have to create this in a directory where - # other users can read and access the temp directory. + # other users can read and access the tmp directory. # This is because we use system to create tmp dirs for unprivileged users who are # sudo'ing to a second unprivileged user. - # The 'system_temps' setting defines dirctories we can use for this purpose + # The 'system_tmpdirs' setting defines dirctories we can use for this purpose # the default are, /tmp and /var/tmp. # So we only allow one of those locations if system=True, using the # passed in tmpdir if it is valid or the first one from the setting if not. @@ -139,13 +139,13 @@ class ShellBase(AnsiblePlugin): if system: tmpdir = tmpdir.rstrip('/') - if tmpdir in self.get_option('system_temps'): + if tmpdir in self.get_option('system_tmpdirs'): basetmpdir = tmpdir else: - basetmpdir = self.get_option('system_temps')[0] + basetmpdir = self.get_option('system_tmpdirs')[0] else: if tmpdir is None: - basetmpdir = self.get_option('remote_temp') + basetmpdir = self.get_option('remote_tmp') else: basetmpdir = tmpdir diff --git a/lib/ansible/plugins/shell/powershell.py b/lib/ansible/plugins/shell/powershell.py index 22b9016d0ab..92a2fa40c35 100644 --- a/lib/ansible/plugins/shell/powershell.py +++ b/lib/ansible/plugins/shell/powershell.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' description: - The only option when using 'winrm' as a connection plugin options: - remote_temp: + remote_tmp: description: - Temporary directory to use on targets when copying files to the host. default: '%TEMP%' @@ -1883,7 +1883,7 @@ class ShellModule(ShellBase): # Windows does not have an equivalent for the system temp files, so # the param is ignored basefile = self._escape(self._unquote(basefile)) - basetmpdir = tmpdir if tmpdir else self.get_option('remote_temp') + basetmpdir = tmpdir if tmpdir else self.get_option('remote_tmp') script = ''' $tmp_path = [System.Environment]::ExpandEnvironmentVariables('%s') diff --git a/lib/ansible/utils/module_docs_fragments/shell_common.py b/lib/ansible/utils/module_docs_fragments/shell_common.py index b3a1f84a238..f82dc572e6a 100644 --- a/lib/ansible/utils/module_docs_fragments/shell_common.py +++ b/lib/ansible/utils/module_docs_fragments/shell_common.py @@ -7,29 +7,29 @@ class ModuleDocFragment(object): # common shelldocumentation fragment DOCUMENTATION = """ options: - remote_temp: + remote_tmp: description: - Temporary directory to use on targets when executing tasks. default: '~/.ansible/tmp' - env: [{name: ANSIBLE_REMOTE_TEMP}] + env: [{name: ANSIBLE_REMOTE_TEMP}, {name: ANSIBLE_REMOTE_TMP}] ini: - section: defaults key: remote_tmp vars: - name: ansible_remote_tmp - system_temps: + system_tmpdirs: description: - "List of valid system temporary directories for Ansible to choose when it cannot use - ``remote_temp``, normally due to permission issues. These must be world readable, writable, + ``remote_tmp``, normally due to permission issues. These must be world readable, writable, and executable." default: [ /var/tmp, /tmp ] type: list - env: [{name: ANSIBLE_SYSTEM_TMPS}] + env: [{name: ANSIBLE_SYSTEM_TMPDIRS}] ini: - section: defaults - key: system_tmps + key: system_tmpdirs vars: - - name: ansible_system_tmps + - name: ansible_system_tmpdirs async_dir: description: - Directory in which ansible will keep async job inforamtion diff --git a/test/integration/targets/async_fail/action_plugins/normal.py b/test/integration/targets/async_fail/action_plugins/normal.py index 2429eeb329f..297cbd9b9b1 100644 --- a/test/integration/targets/async_fail/action_plugins/normal.py +++ b/test/integration/targets/async_fail/action_plugins/normal.py @@ -57,6 +57,6 @@ class ActionModule(ActionBase): if not wrap_async: # remove a temporary path we created - self._remove_tmp_path(self._connection._shell.tempdir) + self._remove_tmp_path(self._connection._shell.tmpdir) return result diff --git a/test/units/plugins/action/test_action.py b/test/units/plugins/action/test_action.py index 1c9ad74ae10..52fa3bea1be 100644 --- a/test/units/plugins/action/test_action.py +++ b/test/units/plugins/action/test_action.py @@ -235,7 +235,7 @@ class TestActionBase(unittest.TestCase): ret = None if opt == 'admin_users': ret = ['root', 'toor', 'Administrator'] - elif opt == 'remote_temp': + elif opt == 'remote_tmp': ret = '~/.ansible/tmp' return ret @@ -419,7 +419,7 @@ class TestActionBase(unittest.TestCase): mock_connection.socket_path = None mock_connection._shell.get_remote_filename.return_value = 'copy.py' mock_connection._shell.join_path.side_effect = os.path.join - mock_connection._shell.tempdir = '/var/tmp/mytempdir' + mock_connection._shell.tmpdir = '/var/tmp/mytempdir' # we're using a real play context here play_context = PlayContext()