mirror of
https://github.com/borgbackup/borg.git
synced 2026-06-11 01:41:57 -04:00
check: ask for key passphrase early, fixes #1931
This commit is contained in:
parent
2efe2bd9ee
commit
2340e60504
2 changed files with 30 additions and 17 deletions
|
|
@ -1659,6 +1659,7 @@ class RobustUnpacker:
|
|||
class ArchiveChecker:
|
||||
def __init__(self):
|
||||
self.error_found = False
|
||||
self.key = None
|
||||
|
||||
def check(
|
||||
self,
|
||||
|
|
@ -1696,7 +1697,8 @@ class ArchiveChecker:
|
|||
# Repository.check already did a full repository-level check and has built and cached a fresh chunkindex -
|
||||
# we can use that here, so we don't disable the caches (also no need to cache immediately, again):
|
||||
self.chunks = build_chunkindex_from_repo(self.repository, disable_caches=False, cache_immediately=False)
|
||||
self.key = self.make_key(repository)
|
||||
if self.key is None:
|
||||
self.key = self.make_key(repository)
|
||||
self.repo_objs = RepoObj(self.key)
|
||||
if verify_data:
|
||||
self.verify_data()
|
||||
|
|
@ -1728,11 +1730,10 @@ class ArchiveChecker:
|
|||
logger.info("Archive consistency check complete, no problems found.")
|
||||
return self.repair or not self.error_found
|
||||
|
||||
def make_key(self, repository):
|
||||
def make_key(self, repository, manifest_only=False):
|
||||
attempt = 0
|
||||
|
||||
# try the manifest first!
|
||||
attempt += 1
|
||||
try:
|
||||
cdata = repository.get_manifest()
|
||||
except NoManifestError:
|
||||
|
|
@ -1744,19 +1745,24 @@ class ArchiveChecker:
|
|||
# we get here, if the cdata we got has a corrupted key type byte
|
||||
pass # ignore it, just continue trying
|
||||
|
||||
for chunkid, _ in self.chunks.iteritems():
|
||||
attempt += 1
|
||||
if attempt > 999:
|
||||
# we did a lot of attempts, but could not create the key via key_factory, give up.
|
||||
break
|
||||
cdata = repository.get(chunkid)
|
||||
try:
|
||||
return key_factory(repository, cdata)
|
||||
except UnsupportedPayloadError:
|
||||
# we get here, if the cdata we got has a corrupted key type byte
|
||||
pass # ignore it, just try the next chunk
|
||||
if not manifest_only:
|
||||
for chunkid, _ in self.chunks.iteritems():
|
||||
attempt += 1
|
||||
if attempt > 999:
|
||||
# we did a lot of attempts, but could not create the key via key_factory, give up.
|
||||
break
|
||||
cdata = repository.get(chunkid)
|
||||
try:
|
||||
return key_factory(repository, cdata)
|
||||
except UnsupportedPayloadError:
|
||||
# we get here, if the cdata we got has a corrupted key type byte
|
||||
pass # ignore it, just try the next chunk
|
||||
|
||||
if attempt == 0:
|
||||
msg = "make_key: repository has no chunks at all!"
|
||||
if manifest_only:
|
||||
msg = "make_key: failed to create the key (tried only the manifest)"
|
||||
else:
|
||||
msg = "make_key: repository has no chunks at all!"
|
||||
else:
|
||||
msg = "make_key: failed to create the key (tried %d chunks)" % attempt
|
||||
raise IntegrityError(msg)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import argparse
|
|||
from ._common import with_repository, Highlander
|
||||
from ..archive import ArchiveChecker
|
||||
from ..constants import * # NOQA
|
||||
from ..helpers import set_ec, EXIT_WARNING, CancelledByUser, CommandError
|
||||
from ..helpers import set_ec, EXIT_WARNING, CancelledByUser, CommandError, IntegrityError
|
||||
from ..helpers import yes
|
||||
|
||||
from ..logger import create_logger
|
||||
|
|
@ -44,10 +44,17 @@ class CheckMixIn:
|
|||
# archives check requires that a full repo check was done before and has built/cached a ChunkIndex.
|
||||
# also, there is no max_duration support in the archives check code anyway.
|
||||
raise CommandError("--repository-only is required for --max-duration support.")
|
||||
if not args.repo_only:
|
||||
# if we need the key later for the archives check, ask NOW for the passphrase! #1931
|
||||
archive_checker = ArchiveChecker()
|
||||
try:
|
||||
archive_checker.key = archive_checker.make_key(repository, manifest_only=True)
|
||||
except IntegrityError:
|
||||
pass # will try to make key later again
|
||||
if not args.archives_only:
|
||||
if not repository.check(repair=args.repair, max_duration=args.max_duration):
|
||||
set_ec(EXIT_WARNING)
|
||||
if not args.repo_only and not ArchiveChecker().check(
|
||||
if not args.repo_only and not archive_checker.check(
|
||||
repository,
|
||||
verify_data=args.verify_data,
|
||||
repair=args.repair,
|
||||
|
|
|
|||
Loading…
Reference in a new issue