提交 79f259e5 编写于 作者: L Lukáš Doktor 提交者: Cleber Rosa

avocado.utils.archive: Fix file permissions in zip files

Zip files are stored with permissions, but python's zipfile does not
reflect that. This patch adjusts the symlink fix to also update file
permissions.
Signed-off-by: NLukáš Doktor <ldoktor@redhat.com>
上级 75609ceb
......@@ -165,26 +165,29 @@ class ArchiveFile(object):
"""
self._engine.extractall(path)
if self.is_zip:
self._update_symlinks(path)
self._update_zip_extra_attrs(path)
def _update_symlinks(self, dst_dir='.'):
def _update_zip_extra_attrs(self, dst_dir):
if platform.system() != "Linux":
LOG.warn("Symlink handling in zip files not supported on Windows.")
LOG.warn("Attr handling in zip files only supported on Linux.")
return
# Walk all files and re-create files as symlinks
for path, info in self._engine.NameToInfo.iteritems():
if info.external_attr >> 16 & stat.S_IFLNK == stat.S_IFLNK:
dst = os.path.join(dst_dir, path)
if not os.path.exists(dst):
LOG.warn("Paths in this zip file are stored in unsupported "
"format, not updating the attributes. (%s)", msg)
return
attr = info.external_attr >> 16
if attr & stat.S_IFLNK == stat.S_IFLNK:
dst = os.path.join(dst_dir, path)
try:
src = open(dst, 'r').read()
except IOError as details:
msg = ("Zip file symlink path '%s' is stored in "
"unsupported format, symlinks were not updated: %s"
% (path, details))
LOG.warn(msg)
return
src = open(dst, 'r').read()
os.remove(dst)
os.symlink(src, dst)
continue # Don't override any other attributes on links
mode = attr & 511 # Mask only permissions
if mode and mode != 436: # If mode is stored and is not default
os.chmod(dst, mode)
def close(self):
"""
......
......@@ -93,16 +93,17 @@ class ArchiveTest(unittest.TestCase):
def test_tbz2_2_file(self):
self.compress_and_check_file('.tbz2')
def test_zip_symlinks(self):
def test_zip_extra_attrs(self):
"""
Check that utils.archive can extract symlinks from zip file,
which is not supported on today's python's zipfile
Check that utils.archive reflects extra attrs of file like symlinks
and file permissions.
"""
def get_path(*args):
""" Get path with decompressdir prefix """
return os.path.join(self.decompressdir, *args)
# File types
zip_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
"..", ".data",
os.path.pardir, ".data",
"test_archive__symlinks.zip"))
archive.uncompress(zip_path, self.decompressdir)
self.assertTrue(os.path.islink(get_path("link_to_dir")))
......@@ -123,6 +124,17 @@ class ArchiveTest(unittest.TestCase):
self.assertEqual(act, exp)
self.assertEqual(os.path.realpath(get_path("link_to_dir")),
get_path("dir"))
# File permissions
self.assertEqual(os.stat(get_path("dir", "file2")).st_mode & 0o777,
0o664)
self.assertEqual(os.stat(get_path("file")).st_mode & 0o777, 0o753)
self.assertEqual(os.stat(get_path("dir")).st_mode & 0o777, 0o775)
self.assertEqual(os.stat(get_path("link_to_file2")).st_mode & 0o777,
0o664)
self.assertEqual(os.stat(get_path("link_to_dir")).st_mode & 0o777,
0o775)
self.assertEqual(os.stat(get_path("link_to_file")).st_mode & 0o777,
0o753)
def tearDown(self):
try:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册