backup: formatting

This commit is contained in:
Marek Marczykowski-Górecki 2016-03-14 13:34:17 +01:00 committed by Wojtek Porczyk
parent 697a26c8da
commit 3fb0754398

View File

@ -60,6 +60,7 @@ def get_disk_usage_one(st):
except AttributeError:
return st.st_size
def get_disk_usage(path):
try:
st = os.lstat(path)
@ -75,6 +76,7 @@ def get_disk_usage(path):
return ret
class BackupCanceledError(qubes.exc.QubesException):
def __init__(self, msg, tmpdir=None):
super(BackupCanceledError, self).__init__(msg)
@ -93,7 +95,7 @@ class BackupHeader(object):
bool_options = ['encrypted', 'compressed']
int_options = ['version']
def __init__(self, header_data = None):
def __init__(self, header_data=None):
# repeat the list to help code completion...
self.version = None
self.encrypted = None
@ -173,6 +175,7 @@ class BackupHeader(object):
continue
f.write("{!s}={!s}\n".format(key, getattr(self, attr)))
class SendWorker(Process):
def __init__(self, queue, base_dir, backup_stdout):
super(SendWorker, self).__init__()
@ -298,8 +301,8 @@ class Backup(object):
self.vms_for_backup = vms_list
# Apply exclude list
if exclude_list:
self.vms_for_backup = [vm for vm in vms_list if vm.name not in
exclude_list]
self.vms_for_backup = [vm for vm in vms_list
if vm.name not in exclude_list]
def __del__(self):
if self.tmpdir and os.path.exists(self.tmpdir):
@ -321,7 +324,8 @@ class Backup(object):
if subdir is None:
abs_file_path = os.path.abspath(file_path)
abs_base_dir = os.path.abspath(qubes.config.system_path["qubes_base_dir"]) + '/'
abs_base_dir = os.path.abspath(
qubes.config.system_path["qubes_base_dir"]) + '/'
abs_file_dir = os.path.dirname(abs_file_path) + '/'
(nothing, directory, subdir) = abs_file_dir.partition(abs_base_dir)
assert nothing == ""
@ -425,9 +429,9 @@ class Backup(object):
if 0 in [vm.qid for vm in self.vms_for_backup]:
local_user = grp.getgrnam('qubes').gr_mem[0]
home_dir = pwd.getpwnam(local_user).pw_dir
# Home dir should have only user-owned files, so fix it now to prevent
# permissions problems - some root-owned files can left after
# 'sudo bash' and similar commands
# Home dir should have only user-owned files, so fix it now
# to prevent permissions problems - some root-owned files can
# left after 'sudo bash' and similar commands
subprocess.check_call(['sudo', 'chown', '-R', local_user, home_dir])
home_sz = get_disk_usage(home_dir)
@ -483,7 +487,8 @@ class Backup(object):
elif vm_info['vm'].is_template():
s += fmt.format("Template VM")
else:
s += fmt.format("VM" + (" + Sys" if vm_info['vm'].updateable else ""))
s += fmt.format("VM" + (" + Sys" if vm_info['vm'].updateable
else ""))
vm_size = vm_info['size']
@ -623,8 +628,8 @@ class Backup(object):
# If not APPVM, STDOUT is a local file
backup_stdout = open(backup_target, 'wb')
# Tar with tape length does not deals well with stdout (close stdout between
# two tapes)
# Tar with tape length does not deals well with stdout
# (close stdout between two tapes)
# For this reason, we will use named pipes instead
self.log.debug("Working in {}".format(self.tmpdir))
@ -657,9 +662,9 @@ class Backup(object):
self.log.debug("Backing up {}".format(file_info))
backup_tempfile = os.path.join(self.tmpdir,
file_info["subdir"],
os.path.basename(file_info["path"]))
backup_tempfile = os.path.join(
self.tmpdir, file_info["subdir"],
os.path.basename(file_info["path"]))
self.log.debug("Using temporary location: {}".format(
backup_tempfile))
@ -667,20 +672,20 @@ class Backup(object):
if not os.path.isdir(os.path.dirname(backup_tempfile)):
os.makedirs(os.path.dirname(backup_tempfile))
# The first tar cmd can use any complex feature as we want. Files will
# be verified before untaring this.
# The first tar cmd can use any complex feature as we want.
# Files will be verified before untaring this.
# Prefix the path in archive with filename["subdir"] to have it
# verified during untar
tar_cmdline = (["tar", "-Pc", '--sparse',
"-f", backup_pipe,
'-C', os.path.dirname(file_info["path"])] +
(['--dereference'] if file_info["subdir"] != "dom0-home/"
else []) +
(['--dereference'] if
file_info["subdir"] != "dom0-home/" else []) +
['--xform', 's:^%s:%s\\0:' % (
os.path.basename(file_info["path"]),
file_info["subdir"]),
os.path.basename(file_info["path"])
])
os.path.basename(file_info["path"])
])
if self.compressed:
tar_cmdline.insert(-1,
"--use-compress-program=%s" % self.compression_filter)
@ -695,14 +700,15 @@ class Backup(object):
tar_cmdline, stdin=subprocess.PIPE)
self.processes_to_kill_on_cancel.append(tar_sparse)
# Wait for compressor (tar) process to finish or for any error of other
# subprocesses
# Wait for compressor (tar) process to finish or for any
# error of other subprocesses
i = 0
run_error = "paused"
encryptor = None
if self.encrypted:
# Start encrypt
# If no cipher is provided, the data is forwarded unencrypted !!!
# If no cipher is provided,
# the data is forwarded unencrypted !!!
encryptor = subprocess.Popen([
"openssl", "enc",
"-e", "-" + self.crypto_algorithm,
@ -764,8 +770,9 @@ class Backup(object):
"Failed to write the backup, VM output:\n" +
vmproc.stderr.read(MAX_STDERR_BYTES))
else:
raise qubes.exc.QubesException("Failed to perform backup: error in " +
run_error)
raise qubes.exc.QubesException(
"Failed to perform backup: error in " +
run_error)
# Send the chunk to the backup target
self._queue_put_with_check(
@ -922,6 +929,7 @@ def wait_backup_feedback(progress_callback, in_stream, streamproc,
return run_error
class ExtractWorker2(Process):
def __init__(self, queue, base_dir, passphrase, encrypted,
progress_callback, vmproc=None,
@ -1301,6 +1309,7 @@ def get_supported_hmac_algo(hmac_algorithm=None):
yield algo.strip()
proc.wait()
class BackupRestoreOptions(object):
def __init__(self):
#: use default NetVM if the one referenced in backup do not exists on
@ -1440,8 +1449,9 @@ class BackupRestore(object):
env=tar1_env)
self.processes_to_kill_on_cancel.append(command)
# qfile-dom0-unpacker output filelist on stderr (and have stdout connected
# to the VM), while tar output filelist on stdout
# qfile-dom0-unpacker output filelist on stderr
# and have stdout connected to the VM), while tar output filelist
# on stdout
if self.backup_vm:
filelist_pipe = command.stderr
# let qfile-dom0-unpacker hold the only open FD to the write end of
@ -1604,7 +1614,8 @@ class BackupRestore(object):
"""
# Setup worker to extract encrypted data chunks to the restore dirs
# Create the process here to pass it options extracted from backup header
# Create the process here to pass it options extracted from
# backup header
extractor_params = {
'queue': queue,
'base_dir': self.tmpdir,
@ -1832,7 +1843,8 @@ class BackupRestore(object):
except KeyError:
netvm_on_host = None
# No netvm on the host?
if not ((netvm_on_host is not None) and netvm_on_host.is_netvm()):
if not ((netvm_on_host is not None)
and netvm_on_host.is_netvm()):
# Maybe the (custom) netvm is in the backup?
if not (netvm_name in restore_info.keys() and
@ -1995,12 +2007,14 @@ class BackupRestore(object):
"netvm": {"func": "'n/a' if vm.is_netvm() and not vm.is_proxyvm() else\
('*' if vm.property_is_default('netvm') else '') +\
vm_info['netvm'] if vm_info['netvm'] is not None else '-'"},
vm_info['netvm'] if vm_info['netvm'] is not None "
"else '-'"},
"label": {"func": "vm.label.name"},
}
fields_to_display = ["name", "type", "template", "updbl", "netvm", "label"]
fields_to_display = ["name", "type", "template", "updbl",
"netvm", "label"]
# First calculate the maximum width of each field we want to display
total_width = 0
@ -2141,8 +2155,8 @@ class BackupRestore(object):
break
for vm in vms.values():
if self.canceled:
# only break the loop to save qubes.xml with already restored
# VMs
# only break the loop to save qubes.xml
# with already restored VMs
break
if vm.is_template() != do_templates:
continue
@ -2168,7 +2182,8 @@ class BackupRestore(object):
vm_name = restore_info[vm.name]['rename-to']
try:
# first only minimal set, later clone_properties will be called
# first only minimal set, later clone_properties
# will be called
new_vm = self.app.add_new_vm(
vm.__class__,
name=vm_name,
@ -2214,7 +2229,7 @@ class BackupRestore(object):
os.listdir(qubes.config.system_path[
'qubes_kernels_base_dir']):
self.log.warning("WARNING: Kernel %s not installed, "
"using default one" % vm.kernel)
"using default one" % vm.kernel)
vm.kernel = qubes.property.DEFAULT
try:
new_vm.clone_properties(vm)
@ -2226,8 +2241,8 @@ class BackupRestore(object):
try:
new_vm.fire_event('domain-restore')
except Exception as err:
self.log.error("ERROR during appmenu restore: {"
"0}".format(err))
self.log.error("ERROR during appmenu restore: "
"{0}".format(err))
self.log.warning(
"*** VM '{0}' will not have appmenus".format(vm.name))
@ -2283,10 +2298,12 @@ class BackupRestore(object):
home_dir + '/' + restore_home_backupdir + '/' + f)
if self.header_data.version == 1:
subprocess.call(
["cp", "-nrp", "--reflink=auto", backup_dom0_home_dir + '/' + f, home_file])
["cp", "-nrp", "--reflink=auto",
backup_dom0_home_dir + '/' + f, home_file])
elif self.header_data.version >= 2:
shutil.move(backup_dom0_home_dir + '/' + f, home_file)
retcode = subprocess.call(['sudo', 'chown', '-R', local_user, home_dir])
retcode = subprocess.call(['sudo', 'chown', '-R',
local_user, home_dir])
if retcode != 0:
self.log.error("*** Error while setting home directory owner")