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 variablespull/4420/head
parent
2678508d42
commit
06f73ad578
|
@ -82,6 +82,9 @@ See [Porting Guide](http://docs.ansible.com/ansible/devel/porting_guides.html) f
|
||||||
* `osx_say` module was renamed into `say`.
|
* `osx_say` module was renamed into `say`.
|
||||||
* 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
|
||||||
|
* 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…
Reference in New Issue