mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Add support to directly set content in copy module
This commit is contained in:
parent
4da04b2176
commit
c7c7a63ee5
2 changed files with 37 additions and 5 deletions
|
@ -22,6 +22,7 @@ from ansible import errors
|
||||||
from ansible.runner.return_data import ReturnData
|
from ansible.runner.return_data import ReturnData
|
||||||
import base64
|
import base64
|
||||||
import stat
|
import stat
|
||||||
|
import tempfile
|
||||||
|
|
||||||
class ActionModule(object):
|
class ActionModule(object):
|
||||||
|
|
||||||
|
@ -37,10 +38,14 @@ class ActionModule(object):
|
||||||
options.update(complex_args)
|
options.update(complex_args)
|
||||||
options.update(utils.parse_kv(module_args))
|
options.update(utils.parse_kv(module_args))
|
||||||
source = options.get('src', None)
|
source = options.get('src', None)
|
||||||
|
content = options.get('content', None)
|
||||||
dest = options.get('dest', None)
|
dest = options.get('dest', None)
|
||||||
|
|
||||||
if (source is None and not 'first_available_file' in inject) or dest is None:
|
if (source is None and content is None and not 'first_available_file' in inject) or dest is None:
|
||||||
result=dict(failed=True, msg="src and dest are required")
|
result=dict(failed=True, msg="src or content and dest are required")
|
||||||
|
return ReturnData(conn=conn, result=result)
|
||||||
|
elif (source is not None or 'first_available_file' in inject) and content is not None:
|
||||||
|
result=dict(failed=True, msg="src and content are mutually exclusive")
|
||||||
return ReturnData(conn=conn, result=result)
|
return ReturnData(conn=conn, result=result)
|
||||||
|
|
||||||
# if we have first_available_file in our vars
|
# if we have first_available_file in our vars
|
||||||
|
@ -57,6 +62,17 @@ class ActionModule(object):
|
||||||
if not found:
|
if not found:
|
||||||
results=dict(failed=True, msg="could not find src in first_available_file list")
|
results=dict(failed=True, msg="could not find src in first_available_file list")
|
||||||
return ReturnData(conn=conn, result=results)
|
return ReturnData(conn=conn, result=results)
|
||||||
|
elif content is not None:
|
||||||
|
fd, tmp_content = tempfile.mkstemp()
|
||||||
|
f = os.fdopen(fd, 'w')
|
||||||
|
try:
|
||||||
|
f.write(content)
|
||||||
|
except Exception, err:
|
||||||
|
os.remove(tmp_content)
|
||||||
|
result = dict(failed=True, msg="could not write content temp file: %s" % err)
|
||||||
|
return ReturnData(conn=conn, result=result)
|
||||||
|
f.close()
|
||||||
|
source = tmp_content
|
||||||
else:
|
else:
|
||||||
source = utils.template(self.runner.basedir, source, inject)
|
source = utils.template(self.runner.basedir, source, inject)
|
||||||
source = utils.path_dwim(self.runner.basedir, source)
|
source = utils.path_dwim(self.runner.basedir, source)
|
||||||
|
@ -73,6 +89,10 @@ class ActionModule(object):
|
||||||
remote_md5 = self.runner._remote_md5(conn, tmp, dest)
|
remote_md5 = self.runner._remote_md5(conn, tmp, dest)
|
||||||
if remote_md5 == '3':
|
if remote_md5 == '3':
|
||||||
# Destination is a directory
|
# Destination is a directory
|
||||||
|
if content is not None:
|
||||||
|
os.remove(tmp_content)
|
||||||
|
result = dict(failed=True, msg="can not use content with a dir as dest")
|
||||||
|
return ReturnData(conn=conn, result=result)
|
||||||
dest = os.path.join(dest, os.path.basename(source))
|
dest = os.path.join(dest, os.path.basename(source))
|
||||||
remote_md5 = self.runner._remote_md5(conn, tmp, dest)
|
remote_md5 = self.runner._remote_md5(conn, tmp, dest)
|
||||||
|
|
||||||
|
@ -85,11 +105,15 @@ class ActionModule(object):
|
||||||
diff = {}
|
diff = {}
|
||||||
|
|
||||||
if self.runner.check:
|
if self.runner.check:
|
||||||
|
if content is not None:
|
||||||
|
os.remove(tmp_content)
|
||||||
return ReturnData(conn=conn, result=dict(changed=True), diff=diff)
|
return ReturnData(conn=conn, result=dict(changed=True), diff=diff)
|
||||||
|
|
||||||
# transfer the file to a remote tmp location
|
# transfer the file to a remote tmp location
|
||||||
tmp_src = tmp + os.path.basename(source)
|
tmp_src = tmp + os.path.basename(source)
|
||||||
conn.put_file(source, tmp_src)
|
conn.put_file(source, tmp_src)
|
||||||
|
if content is not None:
|
||||||
|
os.remove(tmp_content)
|
||||||
# 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 self.runner.sudo and self.runner.sudo_user != 'root':
|
if self.runner.sudo and self.runner.sudo_user != 'root':
|
||||||
self.runner._low_level_exec_command(conn, "chmod a+r %s" % tmp_src, tmp)
|
self.runner._low_level_exec_command(conn, "chmod a+r %s" % tmp_src, tmp)
|
||||||
|
@ -102,6 +126,8 @@ class ActionModule(object):
|
||||||
# no need to transfer the file, already correct md5, but still need to call
|
# no need to transfer the file, already correct md5, but still need to call
|
||||||
# the file module in case we want to change attributes
|
# the file module in case we want to change attributes
|
||||||
|
|
||||||
|
if content is not None:
|
||||||
|
os.remove(tmp_content)
|
||||||
tmp_src = tmp + os.path.basename(source)
|
tmp_src = tmp + os.path.basename(source)
|
||||||
module_args = "%s src=%s" % (module_args, tmp_src)
|
module_args = "%s src=%s" % (module_args, tmp_src)
|
||||||
if self.runner.check:
|
if self.runner.check:
|
||||||
|
|
12
library/copy
12
library/copy
|
@ -31,10 +31,15 @@ description:
|
||||||
options:
|
options:
|
||||||
src:
|
src:
|
||||||
description:
|
description:
|
||||||
- Local path to a file to copy to the remote server; can be absolute or relative.
|
- Local path to a file to copy to the remote server; can be absolute or relative. Mutually exclusive with content.
|
||||||
required: true
|
required: false
|
||||||
default: null
|
default: null
|
||||||
aliases: []
|
aliases: []
|
||||||
|
content:
|
||||||
|
description:
|
||||||
|
- Creates and/or set content of a file on the remote server. Mutually exclusive with content.
|
||||||
|
required: false
|
||||||
|
default: null
|
||||||
dest:
|
dest:
|
||||||
description:
|
description:
|
||||||
- Remote absolute path where the file should be copied to.
|
- Remote absolute path where the file should be copied to.
|
||||||
|
@ -76,7 +81,8 @@ def main():
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
# not checking because of daisy chain to file module
|
# not checking because of daisy chain to file module
|
||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
src=dict(required=True),
|
src=dict(required=False),
|
||||||
|
content=dict(required=False),
|
||||||
dest=dict(required=True),
|
dest=dict(required=True),
|
||||||
backup=dict(default=False, type='bool'),
|
backup=dict(default=False, type='bool'),
|
||||||
force = dict(default='yes', aliases=['thirsty'], type='bool'),
|
force = dict(default='yes', aliases=['thirsty'], type='bool'),
|
||||||
|
|
Loading…
Reference in a new issue