Skip to content

Commit

Permalink
fix unarchive integration tests when LC_ALL is not set to en_US.UTF-8 (
Browse files Browse the repository at this point in the history
  • Loading branch information
s-hertel authored and mattclay committed Jun 28, 2019
1 parent 7ed7d37 commit 23f0ca0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 23 deletions.
48 changes: 25 additions & 23 deletions lib/ansible/modules/files/unarchive.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@ class UnarchiveError(Exception):

class ZipArchive(object):

def __init__(self, src, dest, file_args, module):
def __init__(self, src, b_dest, file_args, module):
self.src = src
self.dest = dest
self.b_dest = b_dest
self.file_args = file_args
self.opts = module.params['extra_opts']
self.module = module
Expand Down Expand Up @@ -435,9 +435,9 @@ def is_unarchived(self):
# DEBUG
# err += "%s%s %10d %s\n" % (ztype, permstr, size, path)

dest = os.path.join(self.dest, path)
b_dest = os.path.join(self.b_dest, to_bytes(path, errors='surrogate_or_strict'))
try:
st = os.lstat(dest)
st = os.lstat(b_dest)
except Exception:
change = True
self.includes.append(path)
Expand Down Expand Up @@ -504,7 +504,7 @@ def is_unarchived(self):

# Compare file checksums
if stat.S_ISREG(st.st_mode):
crc = crc32(dest)
crc = crc32(b_dest)
if crc != self._crc32(path):
change = True
err += 'File %s differs in CRC32 checksum (0x%08x vs 0x%08x)\n' % (path, self._crc32(path), crc)
Expand Down Expand Up @@ -602,7 +602,7 @@ def unarchive(self):
# cmd.extend(map(shell_escape, self.includes))
if self.excludes:
cmd.extend(['-x'] + self.excludes)
cmd.extend(['-d', self.dest])
cmd.extend(['-d', self.b_dest])
rc, out, err = self.module.run_command(cmd)
return dict(cmd=cmd, rc=rc, out=out, err=err)

Expand All @@ -618,9 +618,9 @@ def can_handle_archive(self):

class TgzArchive(object):

def __init__(self, src, dest, file_args, module):
def __init__(self, src, b_dest, file_args, module):
self.src = src
self.dest = dest
self.b_dest = b_dest
self.file_args = file_args
self.opts = module.params['extra_opts']
self.module = module
Expand Down Expand Up @@ -655,15 +655,16 @@ def files_in_archive(self, force_refresh=False):
if self._files_in_archive and not force_refresh:
return self._files_in_archive

cmd = [self.cmd_path, '--list', '-C', self.dest]
cmd = [self.cmd_path, '--list', '-C', self.b_dest]
if self.zipflag:
cmd.append(self.zipflag)
if self.opts:
cmd.extend(['--show-transformed-names'] + self.opts)
if self.excludes:
cmd.extend(['--exclude=' + f for f in self.excludes])
cmd.extend(['-f', self.src])
rc, out, err = self.module.run_command(cmd, cwd=self.dest, environ_update=dict(LANG='C', LC_ALL='C', LC_MESSAGES='C'))
rc, out, err = self.module.run_command(cmd, cwd=self.b_dest, environ_update=dict(LANG='C', LC_ALL='C', LC_MESSAGES='C'))

if rc != 0:
raise UnarchiveError('Unable to list files in the archive')

Expand Down Expand Up @@ -691,7 +692,7 @@ def files_in_archive(self, force_refresh=False):
return self._files_in_archive

def is_unarchived(self):
cmd = [self.cmd_path, '--diff', '-C', self.dest]
cmd = [self.cmd_path, '--diff', '-C', self.b_dest]
if self.zipflag:
cmd.append(self.zipflag)
if self.opts:
Expand All @@ -705,7 +706,7 @@ def is_unarchived(self):
if self.excludes:
cmd.extend(['--exclude=' + f for f in self.excludes])
cmd.extend(['-f', self.src])
rc, out, err = self.module.run_command(cmd, cwd=self.dest, environ_update=dict(LANG='C', LC_ALL='C', LC_MESSAGES='C'))
rc, out, err = self.module.run_command(cmd, cwd=self.b_dest, environ_update=dict(LANG='C', LC_ALL='C', LC_MESSAGES='C'))

# Check whether the differences are in something that we're
# setting anyway
Expand Down Expand Up @@ -742,7 +743,7 @@ def is_unarchived(self):
return dict(unarchived=unarchived, rc=rc, out=out, err=err, cmd=cmd)

def unarchive(self):
cmd = [self.cmd_path, '--extract', '-C', self.dest]
cmd = [self.cmd_path, '--extract', '-C', self.b_dest]
if self.zipflag:
cmd.append(self.zipflag)
if self.opts:
Expand All @@ -756,7 +757,7 @@ def unarchive(self):
if self.excludes:
cmd.extend(['--exclude=' + f for f in self.excludes])
cmd.extend(['-f', self.src])
rc, out, err = self.module.run_command(cmd, cwd=self.dest, environ_update=dict(LANG='C', LC_ALL='C', LC_MESSAGES='C'))
rc, out, err = self.module.run_command(cmd, cwd=self.b_dest, environ_update=dict(LANG='C', LC_ALL='C', LC_MESSAGES='C'))
return dict(cmd=cmd, rc=rc, out=out, err=err)

def can_handle_archive(self):
Expand All @@ -778,23 +779,23 @@ def can_handle_archive(self):

# Class to handle tar files that aren't compressed
class TarArchive(TgzArchive):
def __init__(self, src, dest, file_args, module):
super(TarArchive, self).__init__(src, dest, file_args, module)
def __init__(self, src, b_dest, file_args, module):
super(TarArchive, self).__init__(src, b_dest, file_args, module)
# argument to tar
self.zipflag = ''


# Class to handle bzip2 compressed tar files
class TarBzipArchive(TgzArchive):
def __init__(self, src, dest, file_args, module):
super(TarBzipArchive, self).__init__(src, dest, file_args, module)
def __init__(self, src, b_dest, file_args, module):
super(TarBzipArchive, self).__init__(src, b_dest, file_args, module)
self.zipflag = '-j'


# Class to handle xz compressed tar files
class TarXzArchive(TgzArchive):
def __init__(self, src, dest, file_args, module):
super(TarXzArchive, self).__init__(src, dest, file_args, module)
def __init__(self, src, b_dest, file_args, module):
super(TarXzArchive, self).__init__(src, b_dest, file_args, module)
self.zipflag = '-J'


Expand Down Expand Up @@ -833,6 +834,7 @@ def main():

src = module.params['src']
dest = module.params['dest']
b_dest = to_bytes(dest, errors='surrogate_or_strict')
remote_src = module.params['remote_src']
file_args = module.load_file_common_arguments(module.params)

Expand All @@ -856,10 +858,10 @@ def main():
module.fail_json(msg="Source '%s' not readable, %s" % (src, to_native(e)))

# is dest OK to receive tar file?
if not os.path.isdir(dest):
if not os.path.isdir(b_dest):
module.fail_json(msg="Destination '%s' is not a directory" % dest)

handler = pick_handler(src, dest, file_args, module)
handler = pick_handler(src, b_dest, file_args, module)

res_args = dict(handler=handler.__class__.__name__, dest=dest, src=src)

Expand Down Expand Up @@ -892,7 +894,7 @@ def main():
if res_args.get('diff', True) and not module.check_mode:
# do we need to change perms?
for filename in handler.files_in_archive:
file_args['path'] = os.path.join(dest, filename)
file_args['path'] = os.path.join(b_dest, to_bytes(filename, errors='surrogate_or_strict'))

try:
res_args['changed'] = module.set_fs_attributes_if_different(file_args, res_args['changed'], expand=False)
Expand Down
34 changes: 34 additions & 0 deletions test/integration/targets/unarchive/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,40 @@
- name: remove nonascii test
file: path="{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz" state=absent

- name: test non-ascii with different LC_ALL
block:
- name: create our unarchive destination
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: directory

- name: test that unarchive works with an archive that contains non-ascii filenames
unarchive:
# Both the filename of the tarball and the filename inside the tarball have
# nonascii chars
src: "test-unarchive-nonascii-くらとみ.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
mode: "u+rwX,go+rX"
remote_src: no
register: nonascii_result0

- name: Check that file is really there
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz/storage/àâæçéèïîôœ(copy)!@#$%^&-().jpg"
register: nonascii_stat0

- name: Assert that nonascii tests succeeded
assert:
that:
- "nonascii_result0.changed == true"
- "nonascii_stat0.stat.exists == true"

- name: remove nonascii test
file: path="{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz" state=absent

environment:
LC_ALL: C

# Test that unarchiving is performed if files are missing
# https://github.com/ansible/ansible-modules-core/issues/1064
- name: create our unarchive destination
Expand Down

0 comments on commit 23f0ca0

Please sign in to comment.