فهرست منبع

PR #231 - Merge branch 'check_last_N' of https://github.com/ThomasWaldmann/attic into merge

Thomas Waldmann 10 سال پیش
والد
کامیت
60ac104a8f
2فایلهای تغییر یافته به همراه16 افزوده شده و 7 حذف شده
  1. 12 6
      attic/archive.py
  2. 4 1
      attic/archiver.py

+ 12 - 6
attic/archive.py

@@ -549,7 +549,7 @@ class ArchiveChecker:
     def __del__(self):
         shutil.rmtree(self.tmpdir)
 
-    def check(self, repository, repair=False):
+    def check(self, repository, repair=False, last=None):
         self.report_progress('Starting archive consistency check...')
         self.repair = repair
         self.repository = repository
@@ -559,8 +559,11 @@ class ArchiveChecker:
             self.manifest = self.rebuild_manifest()
         else:
             self.manifest, _ = Manifest.load(repository, key=self.key)
-        self.rebuild_refcounts()
-        self.verify_chunks()
+        self.rebuild_refcounts(last=last)
+        if last is None:
+            self.verify_chunks()
+        else:
+            self.report_progress('Orphaned objects check skipped (needs all archives checked)')
         if not self.error_found:
             self.report_progress('Archive consistency check complete, no problems found.')
         return self.repair or not self.error_found
@@ -615,7 +618,7 @@ class ArchiveChecker:
         self.report_progress('Manifest rebuild complete', error=True)
         return manifest
 
-    def rebuild_refcounts(self):
+    def rebuild_refcounts(self, last=None):
         """Rebuild object reference counts by walking the metadata
 
         Missing and/or incorrect data is repaired when detected
@@ -692,8 +695,11 @@ class ArchiveChecker:
 
         repository = cache_if_remote(self.repository)
         num_archives = len(self.manifest.archives)
-        for i, (name, info) in enumerate(list(self.manifest.archives.items()), 1):
-            self.report_progress('Analyzing archive {} ({}/{})'.format(name, i, num_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)
+        for i, (name, info) in enumerate(archive_items[:end]):
+            self.report_progress('Analyzing archive {} ({}/{})'.format(name, num_archives - i, num_archives))
             archive_id = info[b'id']
             if not archive_id in self.chunks:
                 self.report_progress('Archive metadata block is missing', error=True)

+ 4 - 1
attic/archiver.py

@@ -81,7 +81,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                 print('Repository check complete, no problems found.')
             else:
                 return 1
-        if not args.repo_only and not ArchiveChecker().check(repository, repair=args.repair):
+        if not args.repo_only and not ArchiveChecker().check(repository, repair=args.repair, last=args.last):
                 return 1
         return 0
 
@@ -520,6 +520,9 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
         subparser.add_argument('--repair', dest='repair', action='store_true',
                                default=False,
                                help='attempt to repair any inconsistencies found')
+        subparser.add_argument('--last', dest='last',
+                               type=int, default=None, metavar='N',
+                               help='only check last N archives (Default: all)')
 
         change_passphrase_epilog = textwrap.dedent("""
         The key files used for repository encryption are optionally passphrase