mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Implment copy with an actual minion-side module such that we can get md5sum's and
onchange events like Puppet's file providers do.
This commit is contained in:
parent
440bac4a95
commit
6cceaa5f6a
3 changed files with 84 additions and 9 deletions
|
@ -1,5 +1,9 @@
|
||||||
- pattern: '*'
|
- pattern: '*'
|
||||||
tasks:
|
tasks:
|
||||||
|
- do:
|
||||||
|
- copy a file
|
||||||
|
- copy
|
||||||
|
- [ "/srv/a", "/srv/b" ]
|
||||||
- do:
|
- do:
|
||||||
- configure template & module variables
|
- configure template & module variables
|
||||||
- setup
|
- setup
|
||||||
|
|
|
@ -122,16 +122,46 @@ class Runner(object):
|
||||||
try:
|
try:
|
||||||
return [ host, True, json.loads(result) ]
|
return [ host, True, json.loads(result) ]
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
|
||||||
return [ host, False, result ]
|
return [ host, False, result ]
|
||||||
|
|
||||||
elif self.module_name == 'copy':
|
elif self.module_name == 'copy':
|
||||||
# SFTP file copy module is not really a module
|
|
||||||
|
# TODO: major refactoring pending
|
||||||
|
# do sftp then run actual copy module to get change info
|
||||||
|
|
||||||
self.remote_log(conn, 'COPY remote:%s local:%s' % (self.module_args[0], self.module_args[1]))
|
self.remote_log(conn, 'COPY remote:%s local:%s' % (self.module_args[0], self.module_args[1]))
|
||||||
|
source = self.module_args[0]
|
||||||
|
dest = self.module_args[1]
|
||||||
|
tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1])
|
||||||
|
|
||||||
ftp = conn.open_sftp()
|
ftp = conn.open_sftp()
|
||||||
ftp.put(self.module_args[0], self.module_args[1])
|
ftp.put(source, tmp_dest)
|
||||||
ftp.close()
|
ftp.close()
|
||||||
|
|
||||||
|
# install the copy module
|
||||||
|
|
||||||
|
self.module_name = 'copy'
|
||||||
|
outpath = self._copy_module(conn)
|
||||||
|
self._exec_command(conn, "chmod +x %s" % outpath)
|
||||||
|
|
||||||
|
# run the copy module
|
||||||
|
|
||||||
|
self.module_args = [ tmp_dest, dest ]
|
||||||
|
cmd = self._command(outpath)
|
||||||
|
result = self._exec_command(conn, cmd)
|
||||||
|
|
||||||
|
# remove the module
|
||||||
|
self._exec_command(conn, "rm -f %s" % outpath)
|
||||||
|
# remove the temp file
|
||||||
|
self._exec_command(conn, "rm -f %s" % tmp_dest)
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
try:
|
||||||
|
return [ host, True, json.loads(result) ]
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
return [ host, False, result ]
|
||||||
|
|
||||||
return [ host, True, 1 ]
|
return [ host, True, 1 ]
|
||||||
|
|
||||||
elif self.module_name == 'template':
|
elif self.module_name == 'template':
|
||||||
|
@ -155,17 +185,16 @@ class Runner(object):
|
||||||
|
|
||||||
# install the template module
|
# install the template module
|
||||||
self.module_name = 'template'
|
self.module_name = 'template'
|
||||||
self.module_args = [ source, temppath ]
|
|
||||||
outpath = self._copy_module(conn)
|
outpath = self._copy_module(conn)
|
||||||
|
self._exec_command(conn, "chmod +x %s" % outpath)
|
||||||
|
|
||||||
# run the template module
|
# run the template module
|
||||||
self.module_args = [ temppath, dest, metadata ]
|
self.module_args = [ temppath, dest, metadata ]
|
||||||
self._exec_command(conn, "chmod +x %s" % outpath)
|
|
||||||
result = self._exec_command(conn, self._command(outpath))
|
result = self._exec_command(conn, self._command(outpath))
|
||||||
|
# clean up
|
||||||
self._exec_command(conn, "rm -f %s" % outpath)
|
self._exec_command(conn, "rm -f %s" % outpath)
|
||||||
self._exec_command(conn, "rm -f %s" % temppath)
|
self._exec_command(conn, "rm -f %s" % temppath)
|
||||||
|
|
||||||
# TODO: remove tmppath
|
|
||||||
conn.close()
|
conn.close()
|
||||||
try:
|
try:
|
||||||
return [ host, True, json.loads(result) ]
|
return [ host, True, json.loads(result) ]
|
||||||
|
@ -219,9 +248,12 @@ class Runner(object):
|
||||||
hosts = self.match_hosts()
|
hosts = self.match_hosts()
|
||||||
|
|
||||||
# attack pool of hosts in N forks
|
# attack pool of hosts in N forks
|
||||||
pool = multiprocessing.Pool(self.forks)
|
|
||||||
hosts = [ (self,x) for x in hosts ]
|
hosts = [ (self,x) for x in hosts ]
|
||||||
|
if self.forks > 1:
|
||||||
|
pool = multiprocessing.Pool(self.forks)
|
||||||
results = pool.map(_executor_hook, hosts)
|
results = pool.map(_executor_hook, hosts)
|
||||||
|
else:
|
||||||
|
results = [ _executor_hook(x) for x in hosts ]
|
||||||
|
|
||||||
# sort hosts by ones we successfully contacted
|
# sort hosts by ones we successfully contacted
|
||||||
# and ones we did not
|
# and ones we did not
|
||||||
|
|
41
library/copy
41
library/copy
|
@ -1 +1,40 @@
|
||||||
# copy is built-in to ansible's core, so the module here is just a placeholder
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
import json
|
||||||
|
except ImportError:
|
||||||
|
import simplejson as json
|
||||||
|
|
||||||
|
source = sys.argv[1]
|
||||||
|
dest = sys.argv[2]
|
||||||
|
|
||||||
|
# raise an error if there is no source file
|
||||||
|
if not os.path.exists(source):
|
||||||
|
print json.dumps({
|
||||||
|
"failed" : 1,
|
||||||
|
"msg" : "Source %s failed to transfer" % source
|
||||||
|
})
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
md5sum = None
|
||||||
|
changed = False
|
||||||
|
if os.path.exists(dest):
|
||||||
|
md5sum = os.popen("md5sum %s" % dest).read()
|
||||||
|
|
||||||
|
os.system("cp %s %s" % (source, dest))
|
||||||
|
|
||||||
|
md5sum2 = os.popen("md5sum %s" % dest).read()
|
||||||
|
|
||||||
|
if md5sum != md5sum2:
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
# mission accomplished
|
||||||
|
print json.dumps({
|
||||||
|
"md5sum" : md5sum2,
|
||||||
|
"changed" : changed
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue