qubes/backup: include LVM volumes content in backup
Use just introduced tar writer to archive content of LVM volumes (or more generally: block devices). Place them as 'private.img' and 'root.img' files in the backup - just like in old format. This require support for replacing file name in tar header - another thing trivially supported with tar writer.
This commit is contained in:
parent
36eb7f923f
commit
339c47480e
@ -215,7 +215,7 @@ class SendWorker(Process):
|
|||||||
|
|
||||||
class Backup(object):
|
class Backup(object):
|
||||||
class FileToBackup(object):
|
class FileToBackup(object):
|
||||||
def __init__(self, file_path, subdir=None):
|
def __init__(self, file_path, subdir=None, name=None):
|
||||||
sz = qubes.storage.file.get_disk_usage(file_path)
|
sz = qubes.storage.file.get_disk_usage(file_path)
|
||||||
|
|
||||||
if subdir is None:
|
if subdir is None:
|
||||||
@ -230,9 +230,16 @@ class Backup(object):
|
|||||||
if len(subdir) > 0 and not subdir.endswith('/'):
|
if len(subdir) > 0 and not subdir.endswith('/'):
|
||||||
subdir += '/'
|
subdir += '/'
|
||||||
|
|
||||||
|
#: real path to the file
|
||||||
self.path = file_path
|
self.path = file_path
|
||||||
|
#: size of the file
|
||||||
self.size = sz
|
self.size = sz
|
||||||
|
#: directory in backup archive where file should be placed
|
||||||
self.subdir = subdir
|
self.subdir = subdir
|
||||||
|
#: use this name in the archive (aka rename)
|
||||||
|
self.name = os.path.basename(file_path)
|
||||||
|
if name is not None:
|
||||||
|
self.name = name
|
||||||
|
|
||||||
class VMToBackup(object):
|
class VMToBackup(object):
|
||||||
def __init__(self, vm, files, subdir):
|
def __init__(self, vm, files, subdir):
|
||||||
@ -341,11 +348,10 @@ class Backup(object):
|
|||||||
subdir = None
|
subdir = None
|
||||||
|
|
||||||
vm_files = []
|
vm_files = []
|
||||||
# TODO this is file pool specific. Change it to a more general
|
|
||||||
# solution
|
|
||||||
if vm.volumes['private'] is not None:
|
if vm.volumes['private'] is not None:
|
||||||
path_to_private_img = vm.volumes['private'].path
|
path_to_private_img = vm.storage.export('private')
|
||||||
vm_files.append(self.FileToBackup(path_to_private_img, subdir))
|
vm_files.append(self.FileToBackup(path_to_private_img, subdir,
|
||||||
|
'private.img'))
|
||||||
|
|
||||||
vm_files.append(self.FileToBackup(vm.icon_path, subdir))
|
vm_files.append(self.FileToBackup(vm.icon_path, subdir))
|
||||||
vm_files.extend(self.FileToBackup(i, subdir)
|
vm_files.extend(self.FileToBackup(i, subdir)
|
||||||
@ -357,10 +363,9 @@ class Backup(object):
|
|||||||
vm_files.append(self.FileToBackup(firewall_conf, subdir))
|
vm_files.append(self.FileToBackup(firewall_conf, subdir))
|
||||||
|
|
||||||
if vm.updateable:
|
if vm.updateable:
|
||||||
# TODO this is file pool specific. Change it to a more general
|
path_to_root_img = vm.storage.export('root')
|
||||||
# solution
|
vm_files.append(self.FileToBackup(path_to_root_img, subdir,
|
||||||
path_to_root_img = vm.volumes['root'].path
|
'root.img'))
|
||||||
vm_files.append(self.FileToBackup(path_to_root_img, subdir))
|
|
||||||
files_to_backup[vm.qid] = self.VMToBackup(vm, vm_files, subdir)
|
files_to_backup[vm.qid] = self.VMToBackup(vm, vm_files, subdir)
|
||||||
|
|
||||||
# Dom0 user home
|
# Dom0 user home
|
||||||
@ -593,7 +598,7 @@ class Backup(object):
|
|||||||
|
|
||||||
backup_tempfile = os.path.join(
|
backup_tempfile = os.path.join(
|
||||||
self.tmpdir, file_info.subdir,
|
self.tmpdir, file_info.subdir,
|
||||||
os.path.basename(file_info.path))
|
file_info.name)
|
||||||
self.log.debug("Using temporary location: {}".format(
|
self.log.debug("Using temporary location: {}".format(
|
||||||
backup_tempfile))
|
backup_tempfile))
|
||||||
|
|
||||||
@ -610,13 +615,27 @@ class Backup(object):
|
|||||||
'-C', os.path.dirname(file_info.path)] +
|
'-C', os.path.dirname(file_info.path)] +
|
||||||
(['--dereference'] if
|
(['--dereference'] if
|
||||||
file_info.subdir != "dom0-home/" else []) +
|
file_info.subdir != "dom0-home/" else []) +
|
||||||
['--xform', 's:^%s:%s\\0:' % (
|
['--xform=s:^%s:%s\\0:' % (
|
||||||
os.path.basename(file_info.path),
|
os.path.basename(file_info.path),
|
||||||
file_info.subdir),
|
file_info.subdir),
|
||||||
os.path.basename(file_info.path)
|
os.path.basename(file_info.path)
|
||||||
])
|
])
|
||||||
|
file_stat = os.stat(file_info.path)
|
||||||
|
if stat.S_ISBLK(file_stat.st_mode) or \
|
||||||
|
file_info.name != os.path.basename(file_info.path):
|
||||||
|
# tar doesn't handle content of block device, use our
|
||||||
|
# writer
|
||||||
|
# also use our tar writer when renaming file
|
||||||
|
assert not stat.S_ISDIR(file_stat.st_mode),\
|
||||||
|
"Renaming directories not supported"
|
||||||
|
tar_cmdline = ['python', '-m', 'qubes.tarwriter',
|
||||||
|
'--override-name=%s' % (
|
||||||
|
os.path.join(file_info.subdir, os.path.basename(
|
||||||
|
file_info.name))),
|
||||||
|
file_info.path,
|
||||||
|
backup_pipe]
|
||||||
if self.compressed:
|
if self.compressed:
|
||||||
tar_cmdline.insert(-1,
|
tar_cmdline.insert(-2,
|
||||||
"--use-compress-program=%s" % self.compression_filter)
|
"--use-compress-program=%s" % self.compression_filter)
|
||||||
|
|
||||||
self.log.debug(" ".join(tar_cmdline))
|
self.log.debug(" ".join(tar_cmdline))
|
||||||
|
Loading…
Reference in New Issue
Block a user