deltatar: now index file is created on create_full_backup calls
authorEduardo Robles Elvira <edulix@wadobo.com>
Fri, 26 Jul 2013 17:44:43 +0000 (19:44 +0200)
committerEduardo Robles Elvira <edulix@wadobo.com>
Fri, 26 Jul 2013 17:44:43 +0000 (19:44 +0200)
deltatar/deltatar.py
docs/design.py
testing/test_deltatar.py

index 4a7403d..4b3e667 100644 (file)
@@ -21,6 +21,8 @@
 import logging
 import datetime
 import os
+import stat
+import json
 from functools import partial
 
 from . import tarfile
@@ -255,6 +257,33 @@ class DeltaTar(object):
             if os.path.isdir(cur_path):
                 diryield_stack.append(walk_dir(cur_path))
 
+    def _stat_dict(self, path):
+        '''
+        Returns a dict with the stat data used to compare files
+        '''
+        stinfo = os.stat(path)
+        mode = stinfo.st_mode
+
+        ptype = None
+        if stat.S_ISDIR(mode):
+            ptype = 'directory'
+        elif stat.S_ISREG(mode):
+            ptype = 'file'
+        elif stat.S_ISLNK(mode):
+            ptype = 'link'
+
+        return {
+            'type': ptype,
+            'path': path,
+            'mode': mode,
+            'mtime': stinfo.st_mtime,
+            'ctime': stinfo.st_ctime,
+            'uid': stinfo.st_uid,
+            'gid': stinfo.st_gid,
+            'inode': stinfo.st_ino,
+            'size': stinfo.st_size
+        }
+
     def create_full_backup(self, source_path, backup_path,
                            max_volume_size=None):
         '''
@@ -307,6 +336,12 @@ class DeltaTar(object):
         vol_name = self.volume_name_func(backup_path, True, 0)
         tarfile_path = os.path.join(backup_path, vol_name)
 
+        # init index
+        index_name = self.index_name_func(True)
+        index_path = os.path.join(backup_path, index_name)
+        # TODO: encrypt or compress it if necessary
+        index_fd = open(index_path, 'w')
+
         def new_volume_handler(deltarobj, tarobj, base_name, volume_number):
             '''
             Handles the new volumes
@@ -315,6 +350,10 @@ class DeltaTar(object):
             tarobj.open_volume(volume_path)
         new_volume_handler = partial(new_volume_handler, self)
 
+        index_fd.write('{"type": "python-delta-tar-index", version: "1" }\n')
+        index_fd.write('{"type": "BEGIN-FILE-LIST"}\n')
+        checksum = 'TODO' # TODO: checksum
+
         # start creating the tarfile
         tarobj = tarfile.TarFile.open(tarfile_path,
                               mode=self.mode,
@@ -326,9 +365,19 @@ class DeltaTar(object):
 
         cwd = os.getcwd()
         os.chdir(source_path)
-        for i in self._recursive_walk_dir('.'):
-            tarobj.add(i)
-
+        for path in self._recursive_walk_dir('.'):
+            # TODO: reduce paths length using previous dir entries
+            stat = self._stat_dict(path)
+            stat['volume'] = vol_no
+            stat['offset'] = tarobj.fileobj.tell() # TODO: check/fix this
+            index_fd.write(json.dumps(self._stat_dict(path)) + '\n')
+
+            tarobj.add(path)
+
+        index_fd.write('{"type": "END-FILE-LIST"}\n')
+        index_fd.write('{"type": "file-list-checksum", "checksum": "%s"}\n' %\
+                        checksum)
+        index_fd.close()
         os.chdir(cwd)
         tarobj.close()
 
index 3f7027f..00b121a 100644 (file)
@@ -7,11 +7,11 @@ Backup Files Index format:
 
 {"type": "python-delta-tar-index", version: "1" }
 {"type": "BEGIN-FILE-LIST"}
-{"type": "directory", "path": value, "stat.st_mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 0, "offset": 0}
-{"type": "file", "path": value, "stat.st_mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 0, "offset": 0}
-{"type": "file", "path": value, "stat.st_mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 0, "offset": 56464}
+{"type": "directory", "path": value, "mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 0, "offset": 0}
+{"type": "file", "path": value, "mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 0, "offset": 0}
+{"type": "file", "path": value, "mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 0, "offset": 56464}
 [...]
-{"type": "file", "path": value, "stat.st_mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 1, "offset": 0}
+{"type": "file", "path": value, "mode": value, "mtime": value, "ctime": value, "uid": value, "gid": value, "inode": value, "size": value, "volume": 1, "offset": 0}
 {"type": "END-FILE-LIST"}
 {"type": "file-list-checksum", "checksum": "4327847432743278943278942" }
 (future additional fields)
index b088c93..fc1e21e 100644 (file)
@@ -75,4 +75,4 @@ class DeltaTarTest(BaseTest):
         for key, value in self.hash.iteritems():
             assert os.path.exists(key)
             if value:
-                assert value == self.md5sum(key)
\ No newline at end of file
+                assert value == self.md5sum(key)