- source_path: source path to the directory to back up.
- backup_path: path where the back up will be stored. Backup path will
be created if not existent.
- - max_volume_size: maximum volume size. Used to split the backup in
- volumes. Optional (won't split in volumes by default).
+ - max_volume_size: maximum volume size in megabytes. Used to split the
+ backup in volumes. Optional (won't split in volumes by default).
'''
# check input
if not isinstance(source_path, basestring):
raise Exception('Source path "%s" does not exist or is not a '\
'directory' % source_path)
+ if max_volume_size != None and not isinstance(max_volume_size, int):
+ raise Exception('max_volume_size must be an integer')
+ if max_volume_size != None:
+ max_volume_size = max_volume_size*1024*1024
+
if not os.access(source_path, os.R_OK):
raise Exception('Source path "%s" is not readable' % source_path)
# TODO: encrypt or compress it if necessary
index_fd = open(index_path, 'w')
- def new_volume_handler(deltarobj, tarobj, base_name, volume_number):
+ cwd = os.getcwd()
+
+ def new_volume_handler(deltarobj, cwd, backup_path, tarobj, base_name, volume_number):
'''
Handles the new volumes
'''
- volume_path = deltarobj.volume_name_func(True, volume_number)
- tarobj.open_volume(volume_path)
- new_volume_handler = partial(new_volume_handler, self)
+ volume_name = deltarobj.volume_name_func(backup_path, True, volume_number)
+ volume_path = os.path.join(backup_path, volume_name)
+
+ # we convert relative paths into absolute because CWD is changed
+ if not os.path.isabs(volume_path):
+ volume_path = os.path.join(cwd, volume_path)
+ try:
+ tarobj.open_volume(volume_path)
+ except Exception, e:
+ import ipdb; ipdb.set_trace()
+
+ # wraps some args from context into the handler
+ new_volume_handler = partial(new_volume_handler, self, cwd, backup_path)
index_fd.write('{"type": "python-delta-tar-index", version: "1" }\n')
max_volume_size=max_volume_size,
new_volume_handler=new_volume_handler)
- cwd = os.getcwd()
+
os.chdir(source_path)
for path in self._recursive_walk_dir('.'):
# TODO: reduce paths length using previous dir entries
if not os.path.exists(target_path):
os.makedirs(target_path)
- def new_volume_handler(deltarobj, tarobj, base_name, volume_number):
+ backup_path = os.path.dirname(backup_tar_path)
+ cwd = os.getcwd()
+ def new_volume_handler(deltarobj, cwd, backup_path, tarobj, base_name, volume_number):
'''
Handles the new volumes
'''
- volume_path = deltarobj.volume_name_func(True, volume_number)
+ volume_name = deltarobj.volume_name_func(backup_path, True, volume_number)
+ volume_path = os.path.join(backup_path, volume_name)
+
+ # we convert relative paths into absolute because CWD is changed
+ if not os.path.isabs(volume_path):
+ volume_path = os.path.join(cwd, volume_path)
tarobj.open_volume(volume_path)
- new_volume_handler = partial(new_volume_handler, self)
+
+ # wraps some args from context into the handler
+ new_volume_handler = partial(new_volume_handler, self, cwd, backup_path)
tarobj = tarfile.TarFile.open(backup_tar_path,
mode='r' + self.mode,
concat_compression='#gz' in self.mode,
password=self.password,
new_volume_handler=new_volume_handler)
- cwd = os.getcwd()
os.chdir(target_path)
tarobj.extractall()
os.chdir(cwd)
'''
Create base test data
'''
+ os.system('rm -rf source_dir backup_dir')
os.makedirs('source_dir/test/test2')
self.hash = dict()
self.hash["source_dir/test/test2"] = ''
self.hash["source_dir/big"] = self.create_file("source_dir/big", 50000)
self.hash["source_dir/small"] = self.create_file("source_dir/small", 100)
self.hash["source_dir/test/huge"] = self.create_file("source_dir/test/huge", 700000)
+ self.hash["source_dir/test/huge2"] = self.create_file("source_dir/test/huge2", 800000)
self.consoleLogger = logging.StreamHandler()
self.consoleLogger.setLevel(logging.DEBUG)
elif began_list:
crc = binascii.crc32(l, crc) & 0xffffffff
+ def test_create_multivol(self):
+ '''
+ Creates a full backup without any filtering with multiple volumes.
+ '''
+ deltatar = DeltaTar(mode=self.MODE, password=self.PASSWORD,
+ logger=self.consoleLogger)
+
+ # create first backup
+ deltatar.create_full_backup(
+ source_path="source_dir",
+ backup_path="backup_dir",
+ max_volume_size=1)
+
+ assert os.path.exists("backup_dir")
+ assert os.path.exists(os.path.join("backup_dir",
+ deltatar.volume_name_func("backup_dir", True, 0)))
+ assert os.path.exists(os.path.join("backup_dir",
+ deltatar.volume_name_func("backup_dir", True, 1)))
+ assert os.path.exists(os.path.join("backup_dir",
+ deltatar.volume_name_func("backup_dir", True, 2)))
+
+ shutil.rmtree("source_dir")
+
+ tar_filename = deltatar.volume_name_func('backup_dir', True, 0)
+ tar_path = os.path.join("backup_dir", tar_filename)
+
+ # this should automatically restore all volumes
+ deltatar.restore_backup(target_path="source_dir",
+ backup_tar_path=tar_path)
+
+ for key, value in self.hash.iteritems():
+ assert os.path.exists(key)
+ if value:
+ assert value == self.md5sum(key)
+