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

Make the manifest format more extensible

Jonas Borgström 14 жил өмнө
parent
commit
80cbdcd8f1
3 өөрчлөгдсөн 22 нэмэгдсэн , 12 устгасан
  1. 13 10
      darc/archive.py
  2. 2 1
      darc/cache.py
  3. 7 1
      darc/test.py

+ 13 - 10
darc/archive.py

@@ -37,19 +37,22 @@ class Archive(object):
         if name:
             manifest = Archive.read_manifest(self.store, self.key)
             try:
-                id, ts = manifest[name]
+                info = manifest['archives'][name]
             except KeyError:
                 raise Archive.DoesNotExist
-            self.load(id)
+            self.load(info['id'])
 
     @staticmethod
     def read_manifest(store, key):
         mid = store.meta['manifest']
         if not mid:
-            return {}
+            return {'version': 1, 'archives': {}}
         mid = mid.decode('hex')
         data = key.decrypt(mid, store.get(mid))
-        return msgpack.unpackb(data)
+        manifest = msgpack.unpackb(data)
+        if not manifest.get('version') == 1:
+            raise ValueError('Invalid manifest version')
+        return manifest
 
     def write_manifest(self, manifest):
         mid = self.store.meta['manifest']
@@ -134,8 +137,8 @@ class Archive(object):
         self.id = self.key.id_hash(data)
         cache.add_chunk(self.id, data, self.stats)
         manifest = Archive.read_manifest(self.store, self.key)
-        assert not name in manifest
-        manifest[name] = self.id, metadata['time']
+        assert not name in manifest['archives']
+        manifest['archives'][name] = {'id': self.id, 'time': metadata['time']}
         self.write_manifest(manifest)
         self.store.commit()
         cache.commit()
@@ -288,8 +291,8 @@ class Archive(object):
         self.store.flush_rpc()
         self.cache.chunk_decref(self.id)
         manifest = Archive.read_manifest(self.store, self.key)
-        assert self.name in manifest
-        del manifest[self.name]
+        assert self.name in manifest['archives']
+        del manifest['archives'][self.name]
         self.write_manifest(manifest)
         self.store.commit()
         cache.commit()
@@ -370,8 +373,8 @@ class Archive(object):
     @staticmethod
     def list_archives(store, key, cache=None):
         manifest = Archive.read_manifest(store, key)
-        for name, (id, ts) in manifest.items():
+        for name, info in manifest['archives'].items():
             archive = Archive(store, key, cache=cache)
-            archive.load(id)
+            archive.load(info['id'])
             yield archive
 

+ 2 - 1
darc/cache.py

@@ -147,7 +147,8 @@ class Cache(object):
         mdata = self.key.decrypt(mid, cdata)
         self.chunks[mid] = 1, len(mdata), len(cdata)
         unpacker = msgpack.Unpacker()
-        for name, (id, _) in Archive.read_manifest(self.store, self.key).items():
+        for name, info in Archive.read_manifest(self.store, self.key)['archives'].items():
+            id = info['id']
             cdata = self.store.get(id)
             data = self.key.decrypt(id, cdata)
             try:

+ 7 - 1
darc/test.py

@@ -96,7 +96,7 @@ class Test(unittest.TestCase):
         self.create_regual_file('dir2/file2', size=1024*80)
         x = xattr(os.path.join(self.input_path, 'file1'))
         x.set('user.foo', 'bar')
-        os.link(os.path.join(self.input_path, 'file1'), 
+        os.link(os.path.join(self.input_path, 'file1'),
                 os.path.join(self.input_path, 'hardlink'))
         os.symlink('somewhere', os.path.join(self.input_path, 'link1'))
         os.mkfifo(os.path.join(self.input_path, 'fifo1'))
@@ -105,6 +105,12 @@ class Test(unittest.TestCase):
         self.darc('create', self.store_path + '::test.2', 'input')
         self.darc('extract', self.store_path + '::test', 'output')
         self.diff_dirs('input', 'output/input')
+        info_output = self.darc('info', self.store_path + '::test')
+        shutil.rmtree(self.cache_path)
+        info_output2 = self.darc('info', self.store_path + '::test')
+        # info_output2 starts with some "initializing cache" text but should
+        # end the same way as info_output
+        assert info_output2.endswith(info_output)
 
     def test_corrupted_store(self):
         self.create_src_archive('test')