From: Philipp Gesang Date: Tue, 22 Aug 2017 13:30:15 +0000 (+0200) Subject: extend tarfile API for rescue mode X-Git-Tag: v2.2~7^2~58 X-Git-Url: http://developer.intra2net.com/git/?p=python-delta-tar;a=commitdiff_plain;h=04f4c7ab20063c55270323b22828b6f2ace1ce1f extend tarfile API for rescue mode --- diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 55a1905..b1b8ccc 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -1296,7 +1296,7 @@ class DeltaTar(object): def restore_backup(self, target_path, backup_indexes_paths=[], backup_tar_path=None, restore_callback=None, - disaster=False): + disaster=tarfile.TOLERANCE_STRICT): ''' Restores a backup. @@ -1386,7 +1386,8 @@ class DeltaTar(object): helper = RestoreHelper(self, cwd, backup_path=backup_tar_path, tarobj=index_it.tar_obj) elif mode == "diff": - helper = RestoreHelper(self, cwd, backup_indexes_paths, disaster=disaster) + helper = RestoreHelper(self, cwd, backup_indexes_paths, + disaster=disaster) try: # get iterator from newest index at _data[0] index1 = helper._data[0]["path"] @@ -1439,7 +1440,7 @@ class DeltaTar(object): iipath = ipath.get ("path", "") self.logger.error("FAILED to restore: {} ({})" .format(iipath, e)) - if disaster is True: + if disaster != tarfile.TOLERANCE_STRICT: failed.append ((iipath, e)) continue @@ -1459,7 +1460,7 @@ class DeltaTar(object): try: helper.restore(ipath, l_no, restore_callback) except Exception as e: - if disaster is False: + if disaster == tarfile.TOLERANCE_STRICT: raise failed.append ((ipath.get ("path", ""), e)) continue @@ -1486,7 +1487,19 @@ class DeltaTar(object): """ return self.restore_backup(target_path, backup_indexes_paths=backup_indexes_paths, - disaster=True) + disaster=tarfile.TOLERANCE_RECOVER) + + + def rescue_backup(self, target_path, backup_indexes_paths=[], + restore_callback=None): + """ + More aggressive “unfsck” mode: do not rely on the index data as the + files may be corrupt; skim files for header-like information and + attempt to retrieve the data. + """ + return self.restore_backup(target_path, + backup_indexes_paths=backup_indexes_paths, + disaster=tarfile.TOLERANCE_RESCUE) def _parse_json_line(self, f, l_no): @@ -1529,10 +1542,10 @@ class RestoreHelper(object): # tarfile.extractall for details. _directories = [] - _disaster = False + _disaster = tarfile.TOLERANCE_STRICT def __init__(self, deltatar, cwd, index_list=None, backup_path=False, - tarobj=None, disaster=False): + tarobj=None, disaster=tarfile.TOLERANCE_STRICT): ''' Constructor opens the tars and init the data structures. @@ -1878,7 +1891,7 @@ class RestoreHelper(object): encryption=index_data["decryptor"], new_volume_handler=index_data['new_volume_handler'], save_to_members=False, - tolerant=self._disaster) + tolerance=self._disaster) member = index_data['tarobj'].__iter__().__next__() diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index a57983f..cc74e92 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -126,6 +126,10 @@ GZ_MAGIC_BYTES = struct.pack (" 0: t.append (buf) @@ -1067,7 +1071,7 @@ class _Stream: else: self.remainder -= todo except DecryptionError: - if self.tolerant is False: + if self.tolerance == TOLERANCE_STRICT: raise self.encryption.drop () if good_crypto == 0: @@ -2101,7 +2105,8 @@ class TarFile(object): @classmethod def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, - encryption=None, compresslevel=9, tolerant=False, **kwargs): + encryption=None, compresslevel=9, tolerance=TOLERANCE_STRICT, + **kwargs): """Open a tar archive for reading, writing or appending. Return an appropriate TarFile class. @@ -2198,7 +2203,7 @@ class TarFile(object): stream = _Stream(name, filemode, comptype, fileobj, bufsize, concat=True, encryption=encryption, - compresslevel=compresslevel, tolerant=tolerant) + compresslevel=compresslevel, tolerance=tolerance) kwargs ["concat"] = True try: t = cls(name, filemode, stream, **kwargs)