From 64a3fa8e737a35f3044e8bf654e932fe0bd84d96 Mon Sep 17 00:00:00 2001 From: Marian Beermann Date: Sun, 13 Nov 2016 11:40:19 +0100 Subject: [PATCH 1/2] check: bail out early if repository is *completely* empty --- borg/repository.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/borg/repository.py b/borg/repository.py index fa6458c61..690e77707 100644 --- a/borg/repository.py +++ b/borg/repository.py @@ -438,6 +438,9 @@ class Repository: transaction_id = self.get_index_transaction_id() if transaction_id is None: transaction_id = self.io.get_latest_segment() + if transaction_id is None: + report_error('This repository contains no valid data.') + return False if repair: self.io.cleanup(transaction_id) segments_transaction_id = self.io.get_segments_transaction_id() From 2261709e78b34330ed439a64001cc1bb661828cf Mon Sep 17 00:00:00 2001 From: Marian Beermann Date: Sun, 13 Nov 2016 11:45:35 +0100 Subject: [PATCH 2/2] check: handle repo w/o objects gracefully normal check would complete, --repair would crash when trying to write the rebuilt (empty) manifest out, since self.key was None --- borg/archive.py | 3 +++ borg/testsuite/archiver.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/borg/archive.py b/borg/archive.py index e725857e5..654a1da9a 100644 --- a/borg/archive.py +++ b/borg/archive.py @@ -833,6 +833,9 @@ class ArchiveChecker: self.repair = repair self.repository = repository self.init_chunks() + if not self.chunks: + logger.error('Repository contains no apparent data at all, cannot continue check/repair.') + return False self.key = self.identify_key(repository) if Manifest.MANIFEST_ID not in self.chunks: logger.error("Repository manifest not found!") diff --git a/borg/testsuite/archiver.py b/borg/testsuite/archiver.py index bc49bc66b..b50304b5a 100644 --- a/borg/testsuite/archiver.py +++ b/borg/testsuite/archiver.py @@ -1444,6 +1444,13 @@ class ArchiverCheckTestCase(ArchiverTestCaseBase): self.cmd('check', self.repository_location, exit_code=0) self.cmd('extract', '--dry-run', self.repository_location + '::archive1', exit_code=0) + def test_empty_repository(self): + with Repository(self.repository_location, exclusive=True) as repository: + for id_ in repository.list(): + repository.delete(id_) + repository.commit() + self.cmd('check', self.repository_location, exit_code=1) + @pytest.mark.skipif(sys.platform == 'cygwin', reason='remote is broken on cygwin and hangs') class RemoteArchiverTestCase(ArchiverTestCase):