files may be corrupt; skim files for header-like information and
attempt to retrieve the data.
"""
- backup_index = tarfile.gen_rescue_index(backup_tar_path,
- self.mode,
- password=self.password,
- key=self.crypto_key)
+ def gen_volume_name (nvol):
+ return os.path.join (os.path.dirname (backup_tar_path),
+ self.volume_name_func (backup_tar_path,
+ True,
+ nvol))
+
+ backup_index = tarfile.gen_rescue_index (gen_volume_name,
+ self.mode,
+ password=self.password,
+ key=self.crypto_key)
return self.restore_backup(target_path,
backup_index=backup_index,
'''
Called by the user to change this tar file to point to a new volume.
'''
+
# open the file using either fileobj or name
if not fileobj:
if self.mode == "a" and not os.path.exists(name):
fileobj=None,
bufsize=self.fileobj.bufsize,
encryption=encryption or self.fileobj.encryption,
- concat=self.fileobj.arcmode & ARCMODE_CONCAT)
+ concat=self.fileobj.arcmode & ARCMODE_CONCAT,
+ tolerance=self.fileobj.tolerance)
else:
# here, we lose information about compression/encryption!
self._dbg(3, 'open_volume: builtin open')
}
-def gen_rescue_index (backup_tar_path, mode, password=None, key=None):
+def gen_rescue_index (gen_volume_name, mode, maxvol=None, password=None, key=None):
+ infos = []
psidx = [] # pseudo index, return value
offsets = None
secret = crypto.make_secret (password=password, key=key)
- if secret is not 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)
+ nvol = 0
- fileobj = bltn_open (backup_tar_path, "rb")
- infos = [ (off, read_tarobj_at_offset (fileobj, off, mode, secret=secret))
- for off in offsets ]
- def aux (o, ti):
+ def aux (o, nvol, ti):
ie = idxent_of_tarinfo (ti)
ie ["offset"] = o
+ ie ["volume"] = nvol
return ie
- psidx = [ aux (o, ti) for o, ti in infos ]
+
+ while True:
+ vpath = gen_volume_name (nvol)
+ try:
+ if secret is not None:
+ offsets = crypto.reconstruct_offsets (vpath, secret)
+ elif mode == "#gz":
+ offsets = reconstruct_offsets_gz (vpath)
+ elif mode == "#":
+ offsets = reconstruct_offsets_tar (vpath)
+ else:
+ raise TarError ("no rescue handling for mode “%s”" % mode)
+ except FileNotFoundError as exn:
+ # volume does not exist
+ if maxvol is not None and i < maxvol:
+ continue # explicit volume number specified, ignore missing ones
+ else:
+ break
+
+ fileobj = bltn_open (vpath, "rb")
+ infos += [ (off, nvol, read_tarobj_at_offset (fileobj, off, mode,
+ secret=secret))
+ for off in offsets ]
+ nvol += 1
+
+ psidx = [ aux (o, nvol, ti) for o, nvol, ti in infos ]
return psidx
(source_path=self.src_path, backup_path=bak_path,
max_volume_size=1)
- psidx = tarfile.gen_rescue_index (backup_full, mode, password=self.PASSWORD)
+ def gen_volume_name (nvol):
+ return os.path.join (bak_path, vname (backup_full, True, nvol))
+
+ psidx = tarfile.gen_rescue_index (gen_volume_name,
+ mode,
+ password=self.PASSWORD)
assert len (psidx) == len (self.hash)