From: Eduardo Robles Elvira Date: Fri, 20 Sep 2013 08:14:03 +0000 (+0200) Subject: fixing some restore problems X-Git-Tag: v2.2~100 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=42c04ead6a843bc56a431f201a5bdfa80c1da36b;p=python-delta-tar fixing some restore problems * files that are not in the index being restored are now removed * directories' mtime was not being restored sometimes because it wasn't finding the tarobj --- diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 8527671..e050453 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -1124,11 +1124,15 @@ class DeltaTar(object): op_type = ipath['type'] # filter paths - # TODO: think about changes of type "dir converted to file" and - # how can that affect filtering op_type if self.filter_path(upath, '.', op_type == 'directory') == NO_MATCH: continue + # if types of the file mismatch, the file needs to be deleted + # and re-restored + if ipath is not None and dpath is not None and\ + dpath['type'] != ipath['type']: + helper.delete(upath) + # if file not found in dpath, we can directly restore from index if not dpath: # if the file doesn't exist and it needs to be deleted, it @@ -1145,14 +1149,18 @@ class DeltaTar(object): # we have to restore the file, but first we need to delete the # current existing file. # we don't delete the file if it's a directory, because it might - # just have changed mtime, so it's quite improductive to remove + # just have changed mtime, so it's quite inefficient to remove # it - if ipath and (ipath['type'] != 'directory' or - ipath['path'].startswith('delete://')): - helper.delete(upath) if ipath: + if ipath['type'] != 'directory' or ipath['path'].startswith('delete://'): + helper.delete(upath) helper.restore(ipath, l_no) + # if the file is not in the index (so it comes from the target + # directory) then we have to delete it + else: + helper.delete(upath) + helper.restore_directories_permissions() index_it.release() os.chdir(cwd) @@ -1341,17 +1349,38 @@ class RestoreHelper(object): ''' Restore directory permissions when everything have been restored ''' + try: + import grp, pwd + except ImportError: + grp = pwd = None + self._directories.sort(key=operator.attrgetter('name')) self._directories.reverse() - tarobj = self._data[0]['tarobj'] # Set correct owner, mtime and filemode on directories. for member in self._directories: dirpath = member.name try: - tarobj.chmod(member, dirpath) - tarobj.utime(member, dirpath) - tarobj.chown(member, dirpath) + os.chmod(dirpath, member.mode) + os.utime(dirpath, (member.mtime, member.mtime)) + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(member.gname)[2] + except KeyError: + g = member.gid + try: + u = pwd.getpwnam(member.uname)[2] + except KeyError: + u = member.uid + try: + if member.issym() and hasattr(os, "lchown"): + os.lchown(dirpath, u, g) + else: + os.chown(dirpath, u, g) + except EnvironmentError: + raise tarfile.ExtractError("could not change owner") + except tarfile.ExtractError, e: self._deltatar.logger.warn('tarfile: %s' % e)