From: Philipp Gesang Date: Fri, 25 Aug 2017 09:12:39 +0000 (+0200) Subject: add restore helper handling for reconstructed indices X-Git-Tag: v2.2~7^2~47 X-Git-Url: http://developer.intra2net.com/git/?p=python-delta-tar;a=commitdiff_plain;h=65b35c42f15acfff815055105400dde1e39dd703 add restore helper handling for reconstructed indices --- diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 2983ac2..f51cee7 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -1176,7 +1176,7 @@ class DeltaTar(object): """ class RawIndexIterator(object): - def __init__(self, delta_tar, tar_path, index): + def __init__(self, delta_tar, index): self.delta_tar = delta_tar self.index = index self.__enter__() @@ -1185,8 +1185,7 @@ class DeltaTar(object): return self def release(self): - if self.tar_obj: - self.tar_obj.close() + pass def __enter__(self): ''' @@ -1202,7 +1201,7 @@ class DeltaTar(object): def __next__(self): idxent = self.iter.__next__ () - return idxent + return idxent, 0 return RawIndexIterator(self, index) @@ -1443,7 +1442,9 @@ class DeltaTar(object): return [(index1, exn)] elif mode == "disaster": index_it = self.iterate_disaster_index (backup_index) - helper = RestoreHelper (self, cwd, disaster=disaster) + helper = RestoreHelper (self, cwd, backup_path=backup_tar_path, + backup_index=backup_index, + disaster=disaster) dir_it = self._recursive_walk_dir('.') @@ -1547,6 +1548,7 @@ class DeltaTar(object): return self.restore_backup(target_path, backup_index=backup_index, + backup_tar_path=backup_tar_path, disaster=tarfile.TOLERANCE_RESCUE) @@ -1593,7 +1595,8 @@ class RestoreHelper(object): _disaster = tarfile.TOLERANCE_STRICT def __init__(self, deltatar, cwd, index_list=None, backup_path=False, - tarobj=None, disaster=tarfile.TOLERANCE_STRICT): + backup_index=None, tarobj=None, + disaster=tarfile.TOLERANCE_STRICT): ''' Constructor opens the tars and init the data structures. @@ -1629,7 +1632,23 @@ class RestoreHelper(object): else: self.canchown = False - if index_list is not None: + if isinstance (backup_index, list) is True: + def dummy_volume_handler (*_a, **_kwa): + pass + self._data = \ + [{ "curr_vol_no" : None + , "vol_fd" : None + , "offset" : -1 + , "tarobj" : None + , "path" : backup_path + , "is_full" : True + , "iterator" : None + , "last_itelement" : None + , "last_lno" : 0 + , "new_volume_handler" : dummy_volume_handler + , "decryptor" : self._deltatar.decryptor + }] + elif index_list is not None: for index in index_list: is_full = index == index_list[-1] @@ -1748,10 +1767,7 @@ class RestoreHelper(object): # if path is found in the newest index as to be snapshotted, deal with it # and finish if path.startswith('snapshot://'): - try: - self.restore_file(itpath, data, path, l_no, upath) - except Exception: - raise + self.restore_file(itpath, data, path, l_no, upath) # now we restore parent_directory mtime os.utime(parent_dir, (parent_dir_mtime, parent_dir_mtime)) diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index c052fa5..5477c04 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -381,6 +381,7 @@ class EncryptionError(TarError): pass class EndOfFile(Exception): """Signal end of file condition when they’re not an error.""" + pass #--------------------------- # internal stream interface @@ -3315,6 +3316,14 @@ class TarIter: # support functionality for rescue mode #--------------------------------------------------------- +def locate_tar_hdr_candidates (fd): + raise NotImplementedError ("too soon") + + +def readable_tar_objects_offsets (ifd, cands): + raise NotImplementedError ("too soon") + + def locate_gz_hdr_candidates (fd): """ Walk over instances of the GZ magic in the payload, collecting their @@ -3523,6 +3532,21 @@ def reconstruct_offsets_gz (fname): os.close (ifd) +def reconstruct_offsets_tar (fname): + """ + From the given file, retrieve all tar header-like offsets (“candidates”). + Then check each of those locations whether they can be processed as tar + data. + """ + ifd = os.open (fname, os.O_RDONLY) + + try: + cands = locate_tar_hdr_candidates (ifd) + return readable_tar_objects_offsets (ifd, cands) + finally: + os.close (ifd) + + def read_tarobj_at_offset (fileobj, offset, mode, secret=None): decr = None @@ -3596,6 +3620,10 @@ def gen_rescue_index (backup_tar_path, mode, password=None, key=None): offsets = crypto.reconstruct_offsets (backup_tar_path, secret) elif mode == "#gz": offsets = reconstruct_offsets_gz (backup_tar_path) + elif mode == "#": + offsets = reconstruct_offsets_tar (backup_tar_path) + else: + raise TarError ("no rescue handling for mode “%s”" % mode) fileobj = bltn_open (backup_tar_path, "rb") infos = [ (off, read_tarobj_at_offset (fileobj, off, mode, secret=secret))