Commit cbc12f0d by Michael DeHaan

Various performance streamlining and making the file features usable in all…

Various performance streamlining and making the file features usable in all modules without daisy chaining.
parent 60b9316a
......@@ -179,22 +179,6 @@ class Runner(object):
# *****************************************************
def _delete_remote_files(self, conn, files):
''' deletes one or more remote files '''
if os.getenv("ANSIBLE_KEEP_REMOTE_FILES","0") == "1":
# ability to turn off temp file deletion for debug purposes
return
if type(files) in [ str, unicode ]:
files = [ files ]
for filename in files:
if filename.find('/tmp/') == -1:
raise Exception("safeguard deletion, removal of %s is not going to happen" % filename)
self._low_level_exec_command(conn, "rm -rf %s" % filename, None)
# *****************************************************
def _transfer_str(self, conn, tmp, name, data):
''' transfer string to remote file '''
......@@ -230,12 +214,12 @@ class Runner(object):
if 'port' not in args:
args += " port=%s" % C.ZEROMQ_PORT
(remote_module_path, is_new_style) = self._copy_module(conn, tmp, module_name, args, inject)
cmd = "chmod u+x %s" % remote_module_path
(remote_module_path, is_new_style, shebang) = self._copy_module(conn, tmp, module_name, args, inject)
cmd_mod = ""
if self.sudo and self.sudo_user != 'root':
# deal with possible umask issues once sudo'ed to other user
cmd = "chmod a+rx %s" % remote_module_path
self._low_level_exec_command(conn, cmd, tmp)
cmd_mod = "chmod a+r %s; " % remote_module_path
cmd = ""
if not is_new_style:
......@@ -251,6 +235,13 @@ class Runner(object):
else:
cmd = " ".join([str(x) for x in [remote_module_path, async_jid, async_limit, async_module]])
if not shebang:
raise errors.AnsibleError("module is missing interpreter line")
cmd = shebang.replace("#!","") + " " + cmd
if tmp.find("tmp") != -1:
cmd = cmd + "; rm -rf %s > /tmp/del.log 2>&1" % tmp
cmd = cmd_mod + cmd
res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
return ReturnData(conn=conn, result=res)
......@@ -429,19 +420,6 @@ class Runner(object):
else:
result = self.action_plugins['async'].run(conn, tmp, module_name, module_args, inject)
if result.is_successful() and 'daisychain' in result.result:
result2 = self._executor_internal_inner(host, result.result['daisychain'], result.result.get('daisychain_args', {}), inject, port, is_chained=True)
changed = False
if result.result.get('changed',False) or result2.result.get('changed',False):
changed = True
result.result.update(result2.result)
result.result['changed'] = changed
del result.result['daisychain']
if self.module_name != 'raw':
self._delete_remote_files(conn, tmp)
conn.close()
if not result.comm_ok:
......@@ -576,7 +554,13 @@ class Runner(object):
module_data = "\n".join(module_lines)
self._transfer_str(conn, tmp, module_name, module_data)
return (out_path, is_new_style)
lines = module_data.split("\n")
shebang = None
if lines[0].startswith("#!"):
shebang = lines[0]
return (out_path, is_new_style, shebang)
# *****************************************************
......
......@@ -40,7 +40,7 @@ class ActionModule(object):
module_name = 'command'
module_args += " #USE_SHELL"
(module_path, is_new_style) = self.runner._copy_module(conn, tmp, module_name, module_args, inject)
(module_path, is_new_style, shebang) = self.runner._copy_module(conn, tmp, module_name, module_args, inject)
self.runner._low_level_exec_command(conn, "chmod a+rx %s" % module_path, tmp)
return self.runner._execute_module(conn, tmp, 'async_wrapper', module_args,
......
......@@ -84,14 +84,13 @@ class ActionModule(object):
# run the copy module
module_args = "%s src=%s" % (module_args, tmp_src)
return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject).daisychain('file', module_args)
return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject)
else:
# no need to transfer the file, already correct md5, but still need to set src so the file module
# does not freak out. It's just the basename of the file.
# no need to transfer the file, already correct md5, but still need to call
# the file module in case we want to change attributes
tmp_src = tmp + os.path.basename(source)
module_args = "%s src=%s" % (module_args, tmp_src)
result = dict(changed=False, md5sum=remote_md5, transferred=False)
return ReturnData(conn=conn, result=result).daisychain('file', module_args)
return self.runner._execute_module(conn, tmp, 'file', module_args, inject=inject)
......@@ -80,8 +80,9 @@ class ActionModule(object):
if self.runner.sudo and self.runner.sudo_user != 'root':
self.runner._low_level_exec_command(conn, "chmod a+r %s" % xfered,
tmp)
# run the copy module, queue the file module
# run the copy module
module_args = "%s src=%s dest=%s" % (module_args, xfered, dest)
return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject).daisychain('file', module_args)
return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject)
......@@ -53,10 +53,3 @@ class ReturnData(object):
def is_successful(self):
return self.comm_ok and ('failed' not in self.result) and (self.result.get('rc',0) == 0)
def daisychain(self, module_name, module_args):
''' request a module call follow this one '''
if self.is_successful():
self.result['daisychain'] = module_name
self.result['daisychain_args'] = module_args
return self
......@@ -83,7 +83,7 @@ def main():
# file not written yet? That means it is running
module.exit_json(results_file=log_path, ansible_job_id=jid, started=1)
else:
module_fail_json(ansible_job_id=jid, results_file=log_path,
module.fail_json(ansible_job_id=jid, results_file=log_path,
msg="Could not parse job output: %s" % data)
if not 'started' in data:
......
......@@ -64,18 +64,19 @@ def main():
module = AnsibleModule(
# not checking because of daisy chain to file module
check_invalid_arguments = False,
argument_spec = dict(
src=dict(required=True),
dest=dict(required=True),
backup=dict(default=False, choices=BOOLEANS),
)
),
add_file_common_args=True
)
src = os.path.expanduser(module.params['src'])
dest = os.path.expanduser(module.params['dest'])
backup = module.boolean(module.params.get('backup', False))
file_args = module.load_file_common_arguments(module.params)
if not os.path.exists(src):
module.fail_json(msg="Source %s failed to transfer" % (src))
if not os.access(src, os.R_OK):
......@@ -122,15 +123,16 @@ def main():
else:
changed = False
res_args = {
'dest':dest,
'src':src,
'md5sum':md5sum_src,
'changed':changed
}
res_args = dict(
dest = dest, src = src, md5sum = md5sum_src, changed = changed
)
if backup_file:
res_args['backup_file'] = backup_file
module.params['dest'] = dest
file_args = module.load_file_common_arguments(module.params)
res_args['changed'] = module.set_file_attributes_if_different(file_args, res_args['changed'])
module.exit_json(**res_args)
# this is magic, see lib/ansible/module_common.py
......
......@@ -108,9 +108,7 @@ def url_do_get(module, url, dest):
module.params['path'] = actualdest
else:
actualdest = dest
info['daisychain_args'] = module.params
info['daisychain_args']['state'] = 'file'
info['daisychain_args']['dest'] = actualdest
info['actualdest'] = actualdest
request = urllib2.Request(url)
......@@ -177,12 +175,12 @@ def main():
module = AnsibleModule(
# not checking because of daisy chain to file module
check_invalid_arguments = False,
argument_spec = dict(
url = dict(required=True),
dest = dict(required=True),
thirsty = dict(default='no', choices=BOOLEANS)
)
),
add_file_common_args=True
)
url = module.params['url']
......@@ -237,6 +235,12 @@ def main():
os.remove(tmpsrc)
# allow file attribute changes
module.params['path'] = dest
file_args = module.load_file_common_arguments(module.params)
file_args['path'] = dest
changed = module.set_file_attributes_if_different(file_args, changed)
# Mission complete
module.exit_json(url=url, dest=dest, src=tmpsrc, md5sum=md5sum_src,
changed=changed, msg=info.get('msg',''),
......
# this is a virtual module that is entirely implemented server side
DOCUMENTATION = '''
---
module: template
......
......@@ -181,7 +181,9 @@ class TestRunner(unittest.TestCase):
assert self._run('file', ['dest=' + filedemo, 'src=/dev/null', 'state=link'])['failed']
assert os.path.isfile(filedemo)
assert self._run('file', ['dest=' + filedemo, 'mode=604', 'state=file'])['changed']
res = self._run('file', ['dest=' + filedemo, 'mode=604', 'state=file'])
print res
assert res['changed']
assert os.path.isfile(filedemo) and os.stat(filedemo).st_mode == 0100604
assert self._run('file', ['dest=' + filedemo, 'state=absent'])['changed']
......@@ -271,6 +273,7 @@ class TestRunner(unittest.TestCase):
"src=%s" % input,
"dest=%s" % output,
])
print result
assert os.path.exists(output)
out = file(output).read()
assert out.find("first") != -1
......@@ -283,4 +286,5 @@ class TestRunner(unittest.TestCase):
"src=%s" % input,
"dest=%s" % output,
])
print result
assert result['changed'] == False
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment