2
0
Эх сурвалжийг харах

borg check: give a named single archive to it, fixes #139

Thomas Waldmann 9 жил өмнө
parent
commit
03f39c2663
2 өөрчлөгдсөн 23 нэмэгдсэн , 13 устгасан
  1. 15 8
      borg/archive.py
  2. 8 5
      borg/archiver.py

+ 15 - 8
borg/archive.py

@@ -609,7 +609,7 @@ class ArchiveChecker:
         self.error_found = False
         self.error_found = False
         self.possibly_superseded = set()
         self.possibly_superseded = set()
 
 
-    def check(self, repository, repair=False, last=None):
+    def check(self, repository, repair=False, archive=None, last=None):
         self.report_progress('Starting archive consistency check...')
         self.report_progress('Starting archive consistency check...')
         self.repair = repair
         self.repair = repair
         self.repository = repository
         self.repository = repository
@@ -619,8 +619,8 @@ class ArchiveChecker:
             self.manifest = self.rebuild_manifest()
             self.manifest = self.rebuild_manifest()
         else:
         else:
             self.manifest, _ = Manifest.load(repository, key=self.key)
             self.manifest, _ = Manifest.load(repository, key=self.key)
-        self.rebuild_refcounts(last=last)
-        if last is None:
+        self.rebuild_refcounts(archive=archive, last=last)
+        if last is None and archive is None:
             self.verify_chunks()
             self.verify_chunks()
         else:
         else:
             self.report_progress('Orphaned objects check skipped (needs all archives checked)')
             self.report_progress('Orphaned objects check skipped (needs all archives checked)')
@@ -680,7 +680,7 @@ class ArchiveChecker:
         self.report_progress('Manifest rebuild complete', error=True)
         self.report_progress('Manifest rebuild complete', error=True)
         return manifest
         return manifest
 
 
-    def rebuild_refcounts(self, last=None):
+    def rebuild_refcounts(self, archive=None, last=None):
         """Rebuild object reference counts by walking the metadata
         """Rebuild object reference counts by walking the metadata
 
 
         Missing and/or incorrect data is repaired when detected
         Missing and/or incorrect data is repaired when detected
@@ -762,10 +762,17 @@ class ArchiveChecker:
                         yield item
                         yield item
 
 
         repository = cache_if_remote(self.repository)
         repository = cache_if_remote(self.repository)
-        num_archives = len(self.manifest.archives)
-        archive_items = sorted(self.manifest.archives.items(), reverse=True,
-                               key=lambda name_info: name_info[1][b'time'])
-        end = None if last is None else min(num_archives, last)
+        if archive is None:
+            # we need last N or all archives
+            archive_items = sorted(self.manifest.archives.items(), reverse=True,
+                                   key=lambda name_info: name_info[1][b'time'])
+            num_archives = len(self.manifest.archives)
+            end = None if last is None else min(num_archives, last)
+        else:
+            # we only want one specific archive
+            archive_items = [item for item in self.manifest.archives.items() if item[0] == archive]
+            num_archives = 1
+            end = 1
         for i, (name, info) in enumerate(archive_items[:end]):
         for i, (name, info) in enumerate(archive_items[:end]):
             self.report_progress('Analyzing archive {} ({}/{})'.format(name, num_archives - i, num_archives))
             self.report_progress('Analyzing archive {} ({}/{})'.format(name, num_archives - i, num_archives))
             archive_id = info[b'id']
             archive_id = info[b'id']

+ 8 - 5
borg/archiver.py

@@ -85,8 +85,9 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                 print('Repository check complete, no problems found.')
                 print('Repository check complete, no problems found.')
             else:
             else:
                 return 1
                 return 1
-        if not args.repo_only and not ArchiveChecker().check(repository, repair=args.repair, last=args.last):
-                return 1
+        if not args.repo_only and not ArchiveChecker().check(
+                repository, repair=args.repair, archive=args.repository.archive, last=args.last):
+            return 1
         return 0
         return 0
 
 
     def do_change_passphrase(self, args):
     def do_change_passphrase(self, args):
@@ -554,6 +555,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
         and other types of damage. After that the consistency and correctness of the archive
         and other types of damage. After that the consistency and correctness of the archive
         metadata is verified.
         metadata is verified.
 
 
+        By giving an archive name, you can specifically check that archive.
+
         The archive metadata checks can be time consuming and requires access to the key
         The archive metadata checks can be time consuming and requires access to the key
         file and/or passphrase if encryption is enabled. These checks can be skipped using
         file and/or passphrase if encryption is enabled. These checks can be skipped using
         the --repository-only option.
         the --repository-only option.
@@ -563,9 +566,9 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                                           epilog=check_epilog,
                                           epilog=check_epilog,
                                           formatter_class=argparse.RawDescriptionHelpFormatter)
                                           formatter_class=argparse.RawDescriptionHelpFormatter)
         subparser.set_defaults(func=self.do_check)
         subparser.set_defaults(func=self.do_check)
-        subparser.add_argument('repository', metavar='REPOSITORY',
-                               type=location_validator(archive=False),
-                               help='repository to check consistency of')
+        subparser.add_argument('repository', metavar='REPOSITORY_OR_ARCHIVE',
+                               type=location_validator(),
+                               help='repository or archive to check consistency of')
         subparser.add_argument('--repository-only', dest='repo_only', action='store_true',
         subparser.add_argument('--repository-only', dest='repo_only', action='store_true',
                                default=False,
                                default=False,
                                help='only perform repository checks')
                                help='only perform repository checks')