From: Eduardo Robles Elvira Date: Sat, 28 Sep 2013 10:29:30 +0000 (+0200) Subject: migrating tar restore to use the same code as index restore X-Git-Tag: v2.2~93 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=ec57ce530ced46bc30beb4a889bc400d6a8145b8;p=python-delta-tar migrating tar restore to use the same code as index restore previous commit was a mess because it mixed two commits, my fault. it mixed both the mtime directories fix and the generalization of tar restore with index restore. this commit continues the work towards this generalization, fixing the TarPathIterator (which was just not tested), doing the removed os.chdir in restore_backup (which resulted in cwd data loss when running the tests), fixing also the indentation at the end of the restore_backup function, and setting correctly the new_volume_handler in RestoreHelper when restoring from a tarball. However, there are still some unit tests related to multivolume handling that still fail. --- diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index a4cbbf8..83664c6 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -865,7 +865,8 @@ class DeltaTar(object): ''' Allows this iterator to be used with the "with" statement ''' - self.f.close() + if self.f: + self.f.close() self.f = None def next(self): @@ -903,10 +904,10 @@ class DeltaTar(object): Returns a tar iterator that iterates jsonized member items that contain an additional "member" field, used by RestoreHelper. ''' - def TarPathIterator(object): - def __init__(self, delta_tar, index_path): + class TarPathIterator(object): + def __init__(self, delta_tar, tar_path): self.delta_tar = delta_tar - self.index_path = index_path + self.tar_path = tar_path self.tar_obj = None self.__enter__() @@ -922,14 +923,20 @@ class DeltaTar(object): Allows this iterator to be used with the "with" statement ''' if self.tar_obj is None: - self.tar_obj = self.delta_tar.open_index(self.index_path, 'r') + self.tar_obj = tarfile.TarFile.open(self.tar_path, + mode='r' + self.delta_tar.mode, + format=tarfile.GNU_FORMAT, + concat_compression='#gz' in self.delta_tar.mode, + password=self.delta_tar.password, + new_volume_handler=None) return self def __exit__(self, type, value, tb): ''' Allows this iterator to be used with the "with" statement ''' - self.tar_obj.close() + if self.tar_obj: + self.tar_obj.close() self.tar_obj = None def next(self): @@ -937,6 +944,9 @@ class DeltaTar(object): Read each member and return it as a stat dict ''' self.last_member = tarinfo = self.tar_obj.next() + if not tarinfo: + raise StopIteration + ptype = 'unknown' if tarinfo.isfile(): ptype = 'file' @@ -956,7 +966,8 @@ class DeltaTar(object): u'inode': -1, # cannot restore u'size': tarinfo.size, u'member': tarinfo - } + }, 0 + return TarPathIterator(self, tar_path) def jsonize_path_iterator(self, iter, strip=0): @@ -1167,12 +1178,17 @@ class DeltaTar(object): if not os.path.exists(target_path): os.makedirs(target_path) + # make backup_tar_path absolute so that iterate_tar_path works fine + if backup_tar_path and not os.path.isabs(backup_tar_path): + backup_tar_path = os.path.abspath(backup_tar_path) + cwd = os.getcwd() + os.chdir(target_path) if mode == 'tar': index_it = self.iterate_tar_path(backup_tar_path) helper = RestoreHelper(self, cwd, backup_path=backup_tar_path, - tarobj=index_it.tarobj) + tarobj=index_it.tar_obj) elif mode == "diff": helper = RestoreHelper(self, cwd, backup_indexes_paths) index_it = self.iterate_index_path(helper._data[0]["path"]) @@ -1230,10 +1246,10 @@ class DeltaTar(object): else: helper.delete(upath) - helper.restore_directories_permissions() - index_it.release() - os.chdir(cwd) - helper.cleanup() + helper.restore_directories_permissions() + index_it.release() + os.chdir(cwd) + helper.cleanup() def _parse_json_line(self, f, l_no): ''' @@ -1306,6 +1322,9 @@ class RestoreHelper(object): if not os.path.isabs(backup_path): backup_path = os.path.normpath(os.path.join(cwd, backup_path)) + # update the new_volume_handler of tar_obj + tarobj.new_volume_handler = partial(self.new_volume_handler, + self._deltatar, self._cwd, True, os.path.dirname(backup_path)) s = dict( curr_vol_no = None, vol_fd = None, @@ -1316,9 +1335,7 @@ class RestoreHelper(object): iterator = None, last_itelement = None, last_lno = 0, - new_volume_handler = partial(self.new_volume_handler, - self._deltatar, self._cwd, True, - os.path.dirname(backup_path)) + new_volume_handler = tarobj.new_volume_handler ) self._data.append(s) @@ -1367,6 +1384,8 @@ class RestoreHelper(object): # to preserve parent directory mtime, we save it parent_dir = os.path.dirname(upath) + if not os.path.exists(parent_dir): + os.makedirs(parent_dir) parent_dir_mtime = int(os.stat(parent_dir).st_mtime) # if path is found in the first index as to be snapshotted, deal with it