Fixing issues raised in #41540 when a zip file is created on a Windows system. The issue has two parts, first directories that end up in the archive end up in the results of aarchive.list twice as they show up as both files and directories because of the logic to handle the fact that Windows doesn't mark them as directories. This issue shows up when an extraction is run a second time since the module verified the file types and the subdirectory is not a file. The second issue is related to permissions, if Salt is told to extract permissions (which is the default) then the directory and files end up being unreadable since the permissions are not available. This change sets the permissions to what the default umask for the user running Salt is.

This commit is contained in:
Gareth J. Greenaway 2017-06-05 20:52:46 -07:00
parent cc6c98a8d8
commit 66a136e6d8

View File

@ -6,6 +6,7 @@ A module to wrap (non-Windows) archive calls
''' '''
from __future__ import absolute_import from __future__ import absolute_import
import contextlib # For < 2.7 compat import contextlib # For < 2.7 compat
import copy
import errno import errno
import logging import logging
import os import os
@ -241,13 +242,16 @@ def list_(name,
else: else:
files.append(path) files.append(path)
for path in files: _files = copy.deepcopy(files)
for path in _files:
# ZIP files created on Windows do not add entries # ZIP files created on Windows do not add entries
# to the archive for directories. So, we'll need to # to the archive for directories. So, we'll need to
# manually add them. # manually add them.
dirname = ''.join(path.rpartition('/')[:2]) dirname = ''.join(path.rpartition('/')[:2])
if dirname: if dirname:
dirs.add(dirname) dirs.add(dirname)
if dirname in files:
files.remove(dirname)
return list(dirs), files, links return list(dirs), files, links
except zipfile.BadZipfile: except zipfile.BadZipfile:
raise CommandExecutionError('{0} is not a ZIP file'.format(name)) raise CommandExecutionError('{0} is not a ZIP file'.format(name))
@ -1010,7 +1014,15 @@ def unzip(zip_file,
continue continue
zfile.extract(target, dest, password) zfile.extract(target, dest, password)
if extract_perms: if extract_perms:
os.chmod(os.path.join(dest, target), zfile.getinfo(target).external_attr >> 16) perm = zfile.getinfo(target).external_attr >> 16
if perm == 0:
umask_ = os.umask(0)
os.umask(umask_)
if target.endswith('/'):
perm = 0o777 & ~umask_
else:
perm = 0o666 & ~umask_
os.chmod(os.path.join(dest, target), perm)
except Exception as exc: except Exception as exc:
pass pass
finally: finally: