From 0501fe0a83697e5d1b1b292e11ccf497a31ccb8e Mon Sep 17 00:00:00 2001 From: Eduardo Robles Elvira Date: Thu, 8 Aug 2013 10:55:10 +0200 Subject: [PATCH] deltatar: setting and checking mtime and ctime in dirs and files --- deltatar/deltatar.py | 43 +++++++++++++++++++++++++++++++++++++------ testing/test_deltatar.py | 2 +- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 2b37bd9..47b4a29 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -21,7 +21,9 @@ import logging import datetime import binascii +import operator import os +import copy import shutil import re import stat @@ -351,8 +353,8 @@ class DeltaTar(object): u'type': ptype, u'path': unicode(path), u'mode': mode, - u'mtime': stinfo.st_mtime, - u'ctime': stinfo.st_ctime, + u'mtime': int(stinfo.st_mtime), + u'ctime': int(stinfo.st_ctime), u'uid': stinfo.st_uid, u'gid': stinfo.st_gid, u'inode': stinfo.st_ino, @@ -363,9 +365,9 @@ class DeltaTar(object): ''' Return if the dicts are equal in the stat keys ''' - keys = [u'gid', u'type', u'mode',u'size', u'uid', + keys = [u'gid', u'type', u'mode',u'size', u'uid', u'mtime', u'ctime', # TODO: check how to restore this correctly if possible - #u'mtime', u'ctime', u'inode' + # u'inode' ] if (not d1 and d2 != None) or (d1 != None and not d2): @@ -999,6 +1001,7 @@ class DeltaTar(object): helper.delete(upath) helper.restore(ipath, l_no) + helper.restore_directories_permissions() os.chdir(cwd) helper.cleanup() @@ -1028,6 +1031,10 @@ class RestoreHelper(object): _cwd = None + # list of directories to be restored. This is done as a last step, see + # tarfile.extractall for details. + _directories = [] + def __init__(self, deltatar, cwd, index_list): ''' Constructor opens the tars and init the data structures. @@ -1035,6 +1042,7 @@ class RestoreHelper(object): Index list must be provided in reverse order (newer first) ''' self._data = [] + self._directories = [] self._deltatar = deltatar self._cwd = cwd @@ -1099,7 +1107,6 @@ class RestoreHelper(object): # we go from index to index, finding the path in the index, then finding # the index with the most recent snapshot of the file being restored cur_index = 1 - while cur_index < len(self._data): data = self._data[cur_index] it = data['iterator'] @@ -1146,6 +1153,24 @@ class RestoreHelper(object): self._deltatar.logger.warn(('Error restoring file %s from index, ' 'snapshot not found in any index') % path) + def restore_directories_permissions(self): + ''' + Restore directory permissions when everything have been restored + ''' + 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) + except tarfile.ExtractError, e: + self._deltatar.logger.warn('tarfile: %s' % e) + @classmethod def new_volume_handler(deltarobj, cwd, backup_path, tarobj, base_name, volume_number): ''' @@ -1209,5 +1234,11 @@ class RestoreHelper(object): member.path = unprefixed member.name = unprefixed + + if op_type == 'directory': + self._directories.append(member) + member = copy.copy(member) + member.mode = 0700 + # finally, restore the file - index_data['tarobj'].extract(member) \ No newline at end of file + index_data['tarobj'].extract(member) diff --git a/testing/test_deltatar.py b/testing/test_deltatar.py index 8c45314..903e75e 100644 --- a/testing/test_deltatar.py +++ b/testing/test_deltatar.py @@ -1053,7 +1053,6 @@ class DeltaTarTest(BaseTest): assert deltatar._equal_stat_dicts(sitem, titem) - class DeltaTar2Test(DeltaTarTest): ''' Same as DeltaTar but with specific ":" mode @@ -1117,3 +1116,4 @@ class DeltaTarGzipAes256ConcatTest(DeltaTarTest): ''' MODE = '#gz.aes256' PASSWORD = 'some magic key' +1 \ No newline at end of file -- 1.7.1