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 06f73ad578)
pull/36250/head
Toshio Kuratomi 7 years ago
parent 4848652c7a
commit a7a03bbf4a

@ -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. * 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 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. * 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): #### Removed Modules (previously deprecated):
* accelerate. * accelerate.

@ -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) display.display(u"the full traceback was:\n\n%s" % to_text(traceback.format_exc()), log_only=log_only)
exit_code = 250 exit_code = 250
finally: finally:
# Remove ansible tempdir # Remove ansible tmpdir
shutil.rmtree(C.DEFAULT_LOCAL_TMP, True) shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
sys.exit(exit_code) sys.exit(exit_code)

@ -47,7 +47,7 @@ PASS_VARS = {
'shell_executable': '_shell', 'shell_executable': '_shell',
'socket': '_socket_path', 'socket': '_socket_path',
'syslog_facility': '_syslog_facility', 'syslog_facility': '_syslog_facility',
'tempdir': 'tempdir', 'tmpdir': 'tmpdir',
'verbosity': '_verbosity', 'verbosity': '_verbosity',
'version': 'ansible_version', 'version': 'ansible_version',
} }
@ -2199,7 +2199,7 @@ class AnsibleModule(object):
except: except:
# we don't have access to the cwd, probably because of sudo. # we don't have access to the cwd, probably because of sudo.
# Try and move to a neutral location to prevent errors # 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: try:
if os.access(cwd, os.F_OK | os.R_OK): if os.access(cwd, os.F_OK | os.R_OK):
os.chdir(cwd) os.chdir(cwd)
@ -2511,7 +2511,7 @@ class AnsibleModule(object):
# would end in something like: # would end in something like:
# file = _os.path.join(dir, pre + name + suf) # file = _os.path.join(dir, pre + name + suf)
# TypeError: can't concat bytes to str # 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.') 'Please use Python2.x or Python3.5 or greater.')
finally: finally:
if error_msg: if error_msg:
@ -2531,7 +2531,7 @@ class AnsibleModule(object):
try: try:
shutil.move(b_src, b_tmp_dest_name) shutil.move(b_src, b_tmp_dest_name)
except OSError: except OSError:
# cleanup will happen by 'rm' of tempdir # cleanup will happen by 'rm' of tmpdir
# copy2 will preserve some metadata # copy2 will preserve some metadata
shutil.copy2(b_src, b_tmp_dest_name) shutil.copy2(b_src, b_tmp_dest_name)

@ -988,7 +988,8 @@ def fetch_url(module, url, data=None, headers=None, method=None,
module.fail_json(msg='urlparse is not installed') module.fail_json(msg='urlparse is not installed')
# ensure we use proper tempdir # ensure we use proper tempdir
tempfile.tempdir = module.tempdir old_tempdir = tempfile.tempdir
tempfile.tempdir = module.tmpdir
# Get validate_certs from the module params # Get validate_certs from the module params
validate_certs = module.params.get('validate_certs', True) 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: except Exception as e:
info.update(dict(msg="An unknown error occurred: %s" % to_native(e), status=-1), info.update(dict(msg="An unknown error occurred: %s" % to_native(e), status=-1),
exception=traceback.format_exc()) exception=traceback.format_exc())
finally:
tempfile.tempdir = old_tempdir
return r, info return r, info

@ -68,7 +68,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
:kwarg tmp: Deprecated parameter. This is no longer used. An action plugin that calls :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 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, :kwarg task_vars: The variables (host vars, group vars, config vars,
etc) associated with this task. etc) associated with this task.
:returns: dictionary of results from the module :returns: dictionary of results from the module
@ -82,8 +82,8 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if tmp is not None: if tmp is not None:
result['warning'] = ['ActionModule.run() no longer honors the tmp parameter. Action' result['warning'] = ['ActionModule.run() no longer honors the tmp parameter. Action'
' plugins should set self._connection._shell.tempdir to share' ' plugins should set self._connection._shell.tmpdir to share'
' the tempdir'] ' the tmpdir']
del tmp del tmp
if self._task.async_val and not self._supports_async: 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: elif self._task.async_val and self._play_context.check_mode:
raise AnsibleActionFail('check mode and async cannot be used on same task.') 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() self._make_tmp_path()
return result return result
@ -201,7 +201,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
def _early_needs_tmp_path(self): 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) return getattr(self, 'TRANSFERS_FILES', False)
@ -239,7 +239,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
except KeyError: except KeyError:
admin_users = ['root', remote_user] # plugin does not support admin_users admin_users = ['root', remote_user] # plugin does not support admin_users
try: try:
remote_tmp = self._connection._shell.get_option('remote_temp') remote_tmp = self._connection._shell.get_option('remote_tmp')
except KeyError: except KeyError:
remote_tmp = '~/ansible' remote_tmp = '~/ansible'
@ -267,7 +267,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
else: else:
output = ('Authentication or permission failure. ' output = ('Authentication or permission failure. '
'In some cases, you may have been able to authenticate and did not have permissions on the target directory. ' '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'])) 'Failed command was: %s, exited with result %d' % (cmd, result['rc']))
if 'stdout' in result and result['stdout'] != u'': if 'stdout' in result and result['stdout'] != u'':
output = output + u", stdout output: %s" % result['stdout'] output = output + u", stdout output: %s" % result['stdout']
@ -289,10 +289,10 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if rc == '/': if rc == '/':
raise AnsibleError('failed to resolve remote temporary directory from %s: `%s` returned empty string' % (basefile, cmd)) 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: 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 return rc
def _should_remove_tmp_path(self, tmp_path): 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): def _remove_tmp_path(self, tmp_path):
'''Remove a temporary path we created. ''' '''Remove a temporary path we created. '''
if tmp_path is None and self._connection._shell.tempdir: if tmp_path is None and self._connection._shell.tmpdir:
tmp_path = self._connection._shell.tempdir tmp_path = self._connection._shell.tmpdir
if self._should_remove_tmp_path(tmp_path): if self._should_remove_tmp_path(tmp_path):
cmd = self._connection._shell.remove(tmp_path, recurse=True) 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})' 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.'))) % (tmp_rm_res.get('rc'), tmp_rm_res.get('stderr', 'No error string available.')))
else: else:
self._connection._shell.tempdir = None self._connection._shell.tmpdir = None
def _transfer_file(self, local_path, remote_path): def _transfer_file(self, local_path, remote_path):
self._connection.put_file(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: if tmp is not None:
display.warning('_execute_remote_stat no longer honors the tmp parameter. Action' display.warning('_execute_remote_stat no longer honors the tmp parameter. Action'
' plugins should set self._connection._shell.tempdir to share' ' plugins should set self._connection._shell.tmpdir to share'
' the tempdir') ' the tmpdir')
del tmp # No longer used del tmp # No longer used
module_args = dict( module_args = dict(
@ -647,7 +647,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
module_args['_ansible_shell_executable'] = self._play_context.executable module_args['_ansible_shell_executable'] = self._play_context.executable
# make sure all commands use the designated temporary directory # 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): def _update_connection_options(self, options, variables=None):
''' ensures connections have the appropriate information ''' ''' ensures connections have the appropriate information '''
@ -670,12 +670,12 @@ class ActionBase(with_metaclass(ABCMeta, object)):
''' '''
if tmp is not None: if tmp is not None:
display.warning('_execute_module no longer honors the tmp parameter. Action plugins' 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 del tmp # No longer used
if delete_remote_tmp is not None: if delete_remote_tmp is not None:
display.warning('_execute_module no longer honors the delete_remote_tmp parameter.' display.warning('_execute_module no longer honors the delete_remote_tmp parameter.'
' Action plugins should check self._connection._shell.tempdir to' ' Action plugins should check self._connection._shell.tmpdir to'
' see if a tempdir existed before they were called to determine' ' see if a tmpdir existed before they were called to determine'
' if they are responsible for removing it.') ' if they are responsible for removing it.')
del delete_remote_tmp # No longer used del delete_remote_tmp # No longer used
@ -696,22 +696,22 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if not shebang and module_style != 'binary': if not shebang and module_style != 'binary':
raise AnsibleError("module (%s) is missing interpreter line" % module_name) raise AnsibleError("module (%s) is missing interpreter line" % module_name)
tempdir = self._connection._shell.tempdir tmpdir = self._connection._shell.tmpdir
remote_module_path = None remote_module_path = None
if not self._is_pipelining_enabled(module_style, wrap_async): if not self._is_pipelining_enabled(module_style, wrap_async):
# we might need remote temp dir # we might need remote tmp dir
if tempdir is None: if tmpdir is None:
self._make_tmp_path() 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_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 args_file_path = None
if module_style in ('old', 'non_native_want_json', 'binary'): if module_style in ('old', 'non_native_want_json', 'binary'):
# we'll also need a temp file to hold our module arguments # we'll also need a tmp file to hold our module arguments
args_file_path = self._connection._shell.join_path(tempdir, 'args') args_file_path = self._connection._shell.join_path(tmpdir, 'args')
if remote_module_path or module_style != 'new': if remote_module_path or module_style != 'new':
display.debug("transferring module to remote %s" % remote_module_path) 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() environment_string = self._compute_environment_string()
remote_files = [] remote_files = []
if tempdir and remote_module_path: if tmpdir and remote_module_path:
remote_files = [tempdir, remote_module_path] remote_files = [tmpdir, remote_module_path]
if args_file_path: if args_file_path:
remote_files.append(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(), (async_module_style, shebang, async_module_data, async_module_path) = self._configure_module(module_name='async_wrapper', module_args=dict(),
task_vars=task_vars) task_vars=task_vars)
async_module_remote_filename = self._connection._shell.get_remote_filename(async_module_path) 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) self._transfer_data(remote_async_module_path, async_module_data)
remote_files.append(remote_async_module_path) 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 # maintain a fixed number of positional parameters for async_wrapper
async_cmd.append('_') async_cmd.append('_')
if not self._should_remove_tmp_path(tempdir): if not self._should_remove_tmp_path(tmpdir):
async_cmd.append("-preserve_tmp") async_cmd.append("-preserve_tmp")
cmd = " ".join(to_text(x) for x in async_cmd) 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() 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. # files have been transferred.
if remote_files: if remote_files:
# remove none/empty # remove none/empty
@ -806,9 +806,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
remove_internal_keys(data) remove_internal_keys(data)
if wrap_async: 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 # forget about it now
self._connection._shell.tempdir = None self._connection._shell.tmpdir = None
# FIXME: for backwards compat, figure out if still makes sense # FIXME: for backwards compat, figure out if still makes sense
data['changed'] = True data['changed'] = True

@ -147,11 +147,11 @@ class ActionModule(ActionBase):
if self._play_context.diff: if self._play_context.diff:
diff = self._get_diff_data(dest, path, task_vars) 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) xfered = self._transfer_file(path, remote_path)
# fix file permissions when the copy is done as a different user # 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,)) new_module_args.update(dict(src=xfered,))
@ -165,6 +165,6 @@ class ActionModule(ActionBase):
except AnsibleAction as e: except AnsibleAction as e:
result.update(e.result) result.update(e.result)
finally: finally:
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -25,6 +25,6 @@ class ActionModule(ActionBase):
if not wrap_async: if not wrap_async:
# remove a temporary path we created # remove a temporary path we created
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return results return results

@ -258,7 +258,7 @@ class ActionModule(ActionBase):
return result return result
# Define a remote directory that we will copy the file to. # 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 remote_path = None
@ -273,7 +273,7 @@ class ActionModule(ActionBase):
# fix file permissions when the copy is done as a different user # fix file permissions when the copy is done as a different user
if remote_path: if remote_path:
self._fixup_perms2((self._connection._shell.tempdir, remote_path)) self._fixup_perms2((self._connection._shell.tmpdir, remote_path))
if raw: if raw:
# Continue to next iteration if raw is defined. # 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. # Define content_tempfile in case we set it after finding content populated.
content_tempfile = None 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: if content is not None:
try: try:
# If content comes to us as a dict it should be decoded json. # 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)) result.update(dict(dest=dest, src=source, changed=changed))
# Delete tmp path # Delete tmp path
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -213,6 +213,6 @@ class ActionModule(ActionBase):
result.update(dict(changed=False, md5sum=local_md5, file=source, dest=dest, checksum=local_checksum)) result.update(dict(changed=False, md5sum=local_md5, file=source, dest=dest, checksum=local_checksum))
finally: finally:
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -52,6 +52,6 @@ class ActionModule(ActionBase):
if not wrap_async: if not wrap_async:
# remove a temporary path we created # remove a temporary path we created
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -77,6 +77,6 @@ class ActionModule(ActionBase):
finally: finally:
if not self._task.async_val: if not self._task.async_val:
# remove a temporary path we created # remove a temporary path we created
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -53,7 +53,7 @@ class ActionModule(ActionBase):
except AnsibleError as e: except AnsibleError as e:
raise AnsibleActionFail(to_native(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._transfer_file(src, tmp_src)
self._fixup_perms2((tmp_src,)) self._fixup_perms2((tmp_src,))
@ -68,5 +68,5 @@ class ActionModule(ActionBase):
except AnsibleAction as e: except AnsibleAction as e:
result.update(e.result) result.update(e.result)
finally: finally:
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -89,7 +89,8 @@ class ActionModule(ActionBase):
if not self._play_context.check_mode: if not self._play_context.check_mode:
# transfer the file to a remote tmp location # 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 # 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 # 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: except AnsibleAction as e:
result.update(e.result) result.update(e.result)
finally: finally:
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -85,6 +85,6 @@ class ActionModule(ActionBase):
result.update(e.result) result.update(e.result)
finally: finally:
if not self._task.async_val: if not self._task.async_val:
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -162,6 +162,6 @@ class ActionModule(ActionBase):
except AnsibleAction as e: except AnsibleAction as e:
result.update(e.result) result.update(e.result)
finally: finally:
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -84,7 +84,7 @@ class ActionModule(ActionBase):
if not remote_src: if not remote_src:
# transfer the file to a remote tmp location # 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) self._transfer_file(source, tmp_src)
# handle diff mode client side # handle diff mode client side
@ -92,7 +92,7 @@ class ActionModule(ActionBase):
if not remote_src: if not remote_src:
# fix file permissions when the copy is done as a different user # 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. # Build temporary module_args.
new_module_args = self._task.args.copy() new_module_args = self._task.args.copy()
new_module_args.update( new_module_args.update(
@ -120,5 +120,5 @@ class ActionModule(ActionBase):
except AnsibleAction as e: except AnsibleAction as e:
result.update(e.result) result.update(e.result)
finally: finally:
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -374,7 +374,7 @@ class ActionModule(ActionBase):
source = content_tempfile source = content_tempfile
except Exception as err: except Exception as err:
result['failed'] = True 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 return result
# all actions should occur on the remote server, run win_copy module # all actions should occur on the remote server, run win_copy module
elif remote_src: elif remote_src:
@ -487,15 +487,15 @@ class ActionModule(ActionBase):
result.update(query_return) result.update(query_return)
return result return result
if len(query_return['files']) > 0 or len(query_return['directories']) > 0 and self._connection._shell.tempdir is None: if len(query_return['files']) > 0 or len(query_return['directories']) > 0 and self._connection._shell.tmpdir is None:
self._connection._shell.tempdir = self._make_tmp_path() self._connection._shell.tmpdir = self._make_tmp_path()
if len(query_return['files']) == 1 and len(query_return['directories']) == 0: 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 # we only need to copy 1 file, don't mess around with zips
file_src = query_return['files'][0]['src'] file_src = query_return['files'][0]['src']
file_dest = query_return['files'][0]['dest'] file_dest = query_return['files'][0]['dest']
copy_result = self._copy_single_file(file_src, dest, file_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 result['changed'] = True
if copy_result.get('failed') is True: if copy_result.get('failed') is True:
@ -507,14 +507,14 @@ class ActionModule(ActionBase):
# TODO: handle symlinks # TODO: handle symlinks
result.update(self._copy_zip_file(dest, source_files['files'], result.update(self._copy_zip_file(dest, source_files['files'],
source_files['directories'], source_files['directories'],
task_vars, self._connection._shell.tempdir)) task_vars, self._connection._shell.tmpdir))
result['changed'] = True result['changed'] = True
else: else:
# no operations need to occur # no operations need to occur
result['failed'] = False result['failed'] = False
result['changed'] = 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_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 return result

@ -45,21 +45,21 @@ class ShellBase(AnsiblePlugin):
'LC_ALL': module_locale, 'LC_ALL': module_locale,
'LC_MESSAGES': module_locale} 'LC_MESSAGES': module_locale}
self.tempdir = None self.tmpdir = None
def _normalize_system_temps(self): def _normalize_system_tmpdirs(self):
# Normalize the temp directory strings. We don't use expanduser/expandvars because those # 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 # can vary between remote user and become user. Therefore the safest practice will be for
# this to always be specified as full paths) # 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. # which is almost certainly going to fail in a cornercase.
if not all(os.path.isabs(d) for d in normalized_paths): if not all(os.path.isabs(d) for d in normalized_paths):
raise AnsibleError('The configured system_temps contains a relative path: {0}. All' raise AnsibleError('The configured system_tmpdirs contains a relative path: {0}. All'
' system_temps must be absolute'.format(to_native(normalized_paths))) ' 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): 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 # 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 # *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: try:
self._normalize_system_temps() self._normalize_system_tmpdirs()
except AnsibleError: except AnsibleError:
pass pass
@ -128,10 +128,10 @@ class ShellBase(AnsiblePlugin):
basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48)) 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 # 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 # This is because we use system to create tmp dirs for unprivileged users who are
# sudo'ing to a second unprivileged user. # 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. # the default are, /tmp and /var/tmp.
# So we only allow one of those locations if system=True, using the # 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. # 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: if system:
tmpdir = tmpdir.rstrip('/') tmpdir = tmpdir.rstrip('/')
if tmpdir in self.get_option('system_temps'): if tmpdir in self.get_option('system_tmpdirs'):
basetmpdir = tmpdir basetmpdir = tmpdir
else: else:
basetmpdir = self.get_option('system_temps')[0] basetmpdir = self.get_option('system_tmpdirs')[0]
else: else:
if tmpdir is None: if tmpdir is None:
basetmpdir = self.get_option('remote_temp') basetmpdir = self.get_option('remote_tmp')
else: else:
basetmpdir = tmpdir basetmpdir = tmpdir

@ -12,7 +12,7 @@ DOCUMENTATION = '''
description: description:
- The only option when using 'winrm' as a connection plugin - The only option when using 'winrm' as a connection plugin
options: options:
remote_temp: remote_tmp:
description: description:
- Temporary directory to use on targets when copying files to the host. - Temporary directory to use on targets when copying files to the host.
default: '%TEMP%' default: '%TEMP%'
@ -1883,7 +1883,7 @@ class ShellModule(ShellBase):
# Windows does not have an equivalent for the system temp files, so # Windows does not have an equivalent for the system temp files, so
# the param is ignored # the param is ignored
basefile = self._escape(self._unquote(basefile)) 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 = ''' script = '''
$tmp_path = [System.Environment]::ExpandEnvironmentVariables('%s') $tmp_path = [System.Environment]::ExpandEnvironmentVariables('%s')

@ -7,29 +7,29 @@ class ModuleDocFragment(object):
# common shelldocumentation fragment # common shelldocumentation fragment
DOCUMENTATION = """ DOCUMENTATION = """
options: options:
remote_temp: remote_tmp:
description: description:
- Temporary directory to use on targets when executing tasks. - Temporary directory to use on targets when executing tasks.
default: '~/.ansible/tmp' default: '~/.ansible/tmp'
env: [{name: ANSIBLE_REMOTE_TEMP}] env: [{name: ANSIBLE_REMOTE_TEMP}, {name: ANSIBLE_REMOTE_TMP}]
ini: ini:
- section: defaults - section: defaults
key: remote_tmp key: remote_tmp
vars: vars:
- name: ansible_remote_tmp - name: ansible_remote_tmp
system_temps: system_tmpdirs:
description: description:
- "List of valid system temporary directories for Ansible to choose when it cannot use - "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." and executable."
default: [ /var/tmp, /tmp ] default: [ /var/tmp, /tmp ]
type: list type: list
env: [{name: ANSIBLE_SYSTEM_TMPS}] env: [{name: ANSIBLE_SYSTEM_TMPDIRS}]
ini: ini:
- section: defaults - section: defaults
key: system_tmps key: system_tmpdirs
vars: vars:
- name: ansible_system_tmps - name: ansible_system_tmpdirs
async_dir: async_dir:
description: description:
- Directory in which ansible will keep async job inforamtion - Directory in which ansible will keep async job inforamtion

@ -57,6 +57,6 @@ class ActionModule(ActionBase):
if not wrap_async: if not wrap_async:
# remove a temporary path we created # remove a temporary path we created
self._remove_tmp_path(self._connection._shell.tempdir) self._remove_tmp_path(self._connection._shell.tmpdir)
return result return result

@ -235,7 +235,7 @@ class TestActionBase(unittest.TestCase):
ret = None ret = None
if opt == 'admin_users': if opt == 'admin_users':
ret = ['root', 'toor', 'Administrator'] ret = ['root', 'toor', 'Administrator']
elif opt == 'remote_temp': elif opt == 'remote_tmp':
ret = '~/.ansible/tmp' ret = '~/.ansible/tmp'
return ret return ret
@ -419,7 +419,7 @@ class TestActionBase(unittest.TestCase):
mock_connection.socket_path = None mock_connection.socket_path = None
mock_connection._shell.get_remote_filename.return_value = 'copy.py' mock_connection._shell.get_remote_filename.return_value = 'copy.py'
mock_connection._shell.join_path.side_effect = os.path.join 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 # we're using a real play context here
play_context = PlayContext() play_context = PlayContext()

Loading…
Cancel
Save