Implement user,group,mode,selinux settings for unarchive.

This is a partial fix for #234.  Still have to figure out how to
make change reporting work as we can no longer rely on tar's --compare
option
pull/18777/head
Toshio Kuratomi 10 years ago committed by Matt Clay
parent 44354e31e4
commit f9a6ec95b0

@ -76,16 +76,33 @@ EXAMPLES = '''
''' '''
import os import os
from zipfile import ZipFile
class UnarchiveError(Exception):
pass
# class to handle .zip files # class to handle .zip files
class ZipFile(object): class ZipFile(object):
def __init__(self, src, dest, module): def __init__(self, src, dest, module):
self.src = src self.src = src
self.dest = dest self.dest = dest
self.module = module self.module = module
self.cmd_path = self.module.get_bin_path('unzip') self.cmd_path = self.module.get_bin_path('unzip')
self._files_in_archive = []
@property
def files_in_archive(self, force_refresh=False):
if self._files_in_archive and not force_refresh:
return self._files_in_archive
archive = ZipFile(self.src)
try:
self._files_in_archive = archive.namelist()
except:
raise UnarchiveError('Unable to list files in the archive')
return self._files_in_archive
def is_unarchived(self): def is_unarchived(self):
return dict(unarchived=False) return dict(unarchived=False)
@ -107,13 +124,29 @@ class ZipFile(object):
# class to handle gzipped tar files # class to handle gzipped tar files
class TgzFile(object): class TgzFile(object):
def __init__(self, src, dest, module): def __init__(self, src, dest, module):
self.src = src self.src = src
self.dest = dest self.dest = dest
self.module = module self.module = module
self.cmd_path = self.module.get_bin_path('tar') self.cmd_path = self.module.get_bin_path('tar')
self.zipflag = 'z' self.zipflag = 'z'
self._files_in_archive = []
@property
def files_in_archive(self, force_refresh=False):
if self._files_in_archive and not force_refresh:
return self._files_in_archive
cmd = '%s -t%sf "%s"' % (self.cmd_path, self.zipflag, self.src)
rc, out, err = self.module.run_command(cmd)
if rc != 0:
raise UnarchiveError('Unable to list files in the archive')
for filename in out.splitlines():
if filename:
self._files_in_archive.append(filename)
return self._files_in_archive
def is_unarchived(self): def is_unarchived(self):
cmd = '%s -v -C "%s" --diff -%sf "%s"' % (self.cmd_path, self.dest, self.zipflag, self.src) cmd = '%s -v -C "%s" --diff -%sf "%s"' % (self.cmd_path, self.dest, self.zipflag, self.src)
@ -129,41 +162,35 @@ class TgzFile(object):
def can_handle_archive(self): def can_handle_archive(self):
if not self.cmd_path: if not self.cmd_path:
return False return False
cmd = '%s -t%sf "%s"' % (self.cmd_path, self.zipflag, self.src)
rc, out, err = self.module.run_command(cmd) try:
if rc == 0: if self.files_in_archive:
if len(out.splitlines(True)) > 0:
return True return True
except UnarchiveError:
pass
# Errors and no files in archive assume that we weren't able to
# properly unarchive it
return False return False
# class to handle tar files that aren't compressed # class to handle tar files that aren't compressed
class TarFile(TgzFile): class TarFile(TgzFile):
def __init__(self, src, dest, module): def __init__(self, src, dest, module):
self.src = src super(TarFile, self).__init__(src, dest, module)
self.dest = dest
self.module = module
self.cmd_path = self.module.get_bin_path('tar')
self.zipflag = '' self.zipflag = ''
# class to handle bzip2 compressed tar files # class to handle bzip2 compressed tar files
class TarBzip(TgzFile): class TarBzip(TgzFile):
def __init__(self, src, dest, module): def __init__(self, src, dest, module):
self.src = src super(TarFile, self).__init__(src, dest, module)
self.dest = dest
self.module = module
self.cmd_path = self.module.get_bin_path('tar')
self.zipflag = 'j' self.zipflag = 'j'
# class to handle xz compressed tar files # class to handle xz compressed tar files
class TarXz(TgzFile): class TarXz(TgzFile):
def __init__(self, src, dest, module): def __init__(self, src, dest, module):
self.src = src super(TarFile, self).__init__(src, dest, module)
self.dest = dest
self.module = module
self.cmd_path = self.module.get_bin_path('tar')
self.zipflag = 'J' self.zipflag = 'J'
@ -193,6 +220,7 @@ def main():
src = os.path.expanduser(module.params['src']) src = os.path.expanduser(module.params['src'])
dest = os.path.expanduser(module.params['dest']) dest = os.path.expanduser(module.params['dest'])
copy = module.params['copy'] copy = module.params['copy']
file_args = module.load_file_common_arguments(module.params)
# did tar file arrive? # did tar file arrive?
if not os.path.exists(src): if not os.path.exists(src):
@ -217,20 +245,25 @@ def main():
res_args['check_results'] = handler.is_unarchived() res_args['check_results'] = handler.is_unarchived()
if res_args['check_results']['unarchived']: if res_args['check_results']['unarchived']:
res_args['changed'] = False res_args['changed'] = False
module.exit_json(**res_args) else:
# do the unpack
# do the unpack try:
try: res_args['extract_results'] = handler.unarchive()
res_args['extract_results'] = handler.unarchive() if res_args['extract_results']['rc'] != 0:
if res_args['extract_results']['rc'] != 0: module.fail_json(msg="failed to unpack %s to %s" % (src, dest), **res_args)
module.fail_json(msg="failed to unpack %s to %s" % (src, dest), **res_args) except IOError:
except IOError: module.fail_json(msg="failed to unpack %s to %s" % (src, dest))
module.fail_json(msg="failed to unpack %s to %s" % (src, dest)) else:
res_args['changed'] = True
res_args['changed'] = True # do we need to change perms?
for filename in handler.files_in_archive:
file_args['path'] = os.path.join(dest, filename)
res_args['changed'] = module.set_fs_attributes_if_different(file_args, res_args['changed'])
module.exit_json(**res_args) module.exit_json(**res_args)
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
main() if __name__ == '__main__':
main()

Loading…
Cancel
Save