diff --git a/pisi/atomicoperations.py b/pisi/atomicoperations.py index 7c63a534..410dc923 100644 --- a/pisi/atomicoperations.py +++ b/pisi/atomicoperations.py @@ -358,6 +358,13 @@ class Install(AtomicOperation): os.rename(oldconfig, path) + # Package file's path may not be relocated or content may not be changed but + # permission may be changed + def update_permissions(): + permissions = pisi.operations.delta.find_permission_changes(self.old_files, self.files) + for path, mode in permissions: + os.chmod(path, mode) + # Delta package does not contain the files that have the same hash as in # the old package's. Because it means the file has not changed. But some # of these files may be relocated to some other directory in the new package. @@ -411,6 +418,7 @@ class Install(AtomicOperation): if self.package_fname.endswith(ctx.const.delta_package_suffix): relocate_files() + update_permissions() self.package.extract_install(ctx.config.dest_dir()) diff --git a/pisi/operations/delta.py b/pisi/operations/delta.py index c6dc98e4..2d0a4533 100644 --- a/pisi/operations/delta.py +++ b/pisi/operations/delta.py @@ -10,6 +10,7 @@ # Please read the COPYING file. import os +import stat import gettext __trans = gettext.translation("pisi", fallback=True) @@ -137,3 +138,22 @@ def find_relocations(oldfiles, newfiles): relocations.append((files_old[h][0], files_new[h][i])) return relocations + +def find_permission_changes(oldfiles, newfiles): + + files_new = {} + for f in newfiles.list: + files_new.setdefault(f.hash, []).append(f) + + hashes_new = set(map(lambda f:f.hash, newfiles.list)) + hashes_old = set(map(lambda f:f.hash, oldfiles.list)) + unchanged = hashes_new.intersection(hashes_old) + + permissions = [] + for h in unchanged: + for _file in files_new[h]: + path = "/%s" % _file.path + if oct(stat.S_IMODE(os.stat(path)[stat.ST_MODE])) != _file.mode: + permissions.append((path, int(_file.mode, 8))) + + return permissions