浏览代码

repository index conversion

Antoine Beaupré 9 年之前
父节点
当前提交
7c32f555ac
共有 2 个文件被更改,包括 27 次插入10 次删除
  1. 24 8
      borg/converter.py
  2. 3 2
      borg/testsuite/convert.py

+ 24 - 8
borg/converter.py

@@ -18,6 +18,8 @@ class AtticRepositoryConverter(Repository):
         caches, the latter being optional, as they will be rebuilt if
         caches, the latter being optional, as they will be rebuilt if
         missing."""
         missing."""
         print("reading segments from attic repository using borg")
         print("reading segments from attic repository using borg")
+        # we need to open it to load the configuration and other fields
+        self.open(self.path, exclusive=False)
         segments = [ filename for i, filename in self.io.segment_iterator() ]
         segments = [ filename for i, filename in self.io.segment_iterator() ]
         try:
         try:
             keyfile = self.find_attic_keyfile()
             keyfile = self.find_attic_keyfile()
@@ -31,10 +33,10 @@ class AtticRepositoryConverter(Repository):
                                    exclusive=True).acquire()
                                    exclusive=True).acquire()
         try:
         try:
             self.convert_segments(segments, dryrun)
             self.convert_segments(segments, dryrun)
+            self.convert_cache(dryrun)
         finally:
         finally:
             self.lock.release()
             self.lock.release()
             self.lock = None
             self.lock = None
-        self.convert_cache(dryrun)
 
 
     @staticmethod
     @staticmethod
     def convert_segments(segments, dryrun):
     def convert_segments(segments, dryrun):
@@ -54,14 +56,19 @@ class AtticRepositoryConverter(Repository):
             if dryrun:
             if dryrun:
                 time.sleep(0.001)
                 time.sleep(0.001)
             else:
             else:
-                with open(filename, 'r+b') as segment:
-                    segment.seek(0)
-                    # only write if necessary
-                    if (segment.read(len(ATTIC_MAGIC)) == ATTIC_MAGIC):
-                        segment.seek(0)
-                        segment.write(MAGIC)
+                AtticRepositoryConverter.header_replace(filename, ATTIC_MAGIC, MAGIC)
         print()
         print()
 
 
+    @staticmethod
+    def header_replace(filename, old_magic, new_magic):
+        print("changing header on %s" % filename)
+        with open(filename, 'r+b') as segment:
+            segment.seek(0)
+            # only write if necessary
+            if (segment.read(len(old_magic)) == old_magic):
+                segment.seek(0)
+                segment.write(new_magic)
+
     def find_attic_keyfile(self):
     def find_attic_keyfile(self):
         """find the attic keyfiles
         """find the attic keyfiles
 
 
@@ -123,7 +130,16 @@ class AtticRepositoryConverter(Repository):
           `Cache.open()`, edit in place and then `Cache.close()` to
           `Cache.open()`, edit in place and then `Cache.close()` to
           make sure we have locking right
           make sure we have locking right
         """
         """
-        raise NotImplementedError('cache conversion not implemented, next borg backup will take longer to rebuild those caches. use borg check --repair to rebuild now')
+        caches = []
+        transaction_id = self.get_index_transaction_id()
+        if transaction_id is None:
+            print('no index file found for repository %s' % self.path)
+        else:
+            caches += [os.path.join(self.path, 'index.%d' % transaction_id).encode('utf-8')]
+        for cache in caches:
+            print("converting cache %s" % cache)
+            AtticRepositoryConverter.header_replace(cache, b'ATTICIDX', b'BORG_IDX')
+
 
 
 class AtticKeyfileKey(KeyfileKey):
 class AtticKeyfileKey(KeyfileKey):
     """backwards compatible Attic key file parser"""
     """backwards compatible Attic key file parser"""

+ 3 - 2
borg/testsuite/convert.py

@@ -59,6 +59,7 @@ def attic_repo(tmpdir):
     # throw some stuff in that repo, copied from `RepositoryTestCase.test1`
     # throw some stuff in that repo, copied from `RepositoryTestCase.test1`
     for x in range(100):
     for x in range(100):
         attic_repo.put(('%-32d' % x).encode('ascii'), b'SOMEDATA')
         attic_repo.put(('%-32d' % x).encode('ascii'), b'SOMEDATA')
+    attic_repo.commit()
     attic_repo.close()
     attic_repo.close()
     return attic_repo
     return attic_repo
 
 
@@ -82,6 +83,7 @@ def test_convert_segments(tmpdir, attic_repo):
     segments = [filename for i, filename in repo.io.segment_iterator()]
     segments = [filename for i, filename in repo.io.segment_iterator()]
     repo.close()
     repo.close()
     repo.convert_segments(segments, dryrun=False)
     repo.convert_segments(segments, dryrun=False)
+    repo.convert_cache(dryrun=False)
     assert repo_valid(tmpdir)
     assert repo_valid(tmpdir)
 
 
 
 
@@ -157,7 +159,6 @@ def test_convert_all(tmpdir, attic_repo, attic_key_file):
     assert not repo_valid(tmpdir)
     assert not repo_valid(tmpdir)
     print("opening attic repository with borg and converting")
     print("opening attic repository with borg and converting")
     repo = AtticRepositoryConverter(str(tmpdir), create=False)
     repo = AtticRepositoryConverter(str(tmpdir), create=False)
-    with pytest.raises(NotImplementedError):
-        repo.convert(dryrun=False)
+    repo.convert(dryrun=False)
     assert key_valid(attic_key_file.path)
     assert key_valid(attic_key_file.path)
     assert repo_valid(tmpdir)
     assert repo_valid(tmpdir)