From e82f14f53cebffd7cd7ecdc28dc758a011ed6117 Mon Sep 17 00:00:00 2001 From: Eduardo Robles Elvira Date: Fri, 26 Jul 2013 19:44:43 +0200 Subject: [PATCH] deltatar: now index file is created on create_full_backup calls --- deltatar/deltatar.py | 55 +++++++++++++++++++++++++++++++++++++++++++-- docs/design.py | 8 +++--- testing/test_deltatar.py | 2 +- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 4a7403d..4b3e667 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -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() diff --git a/docs/design.py b/docs/design.py index 3f7027f..00b121a 100644 --- a/docs/design.py +++ b/docs/design.py @@ -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) diff --git a/testing/test_deltatar.py b/testing/test_deltatar.py index b088c93..fc1e21e 100644 --- a/testing/test_deltatar.py +++ b/testing/test_deltatar.py @@ -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) -- 1.7.1