backup: make pylint happy, remove dead settings
After removing backup-restore code the remaining part of backup.py is not that bad - lets fix it and no longer exclude it from pylint.
This commit is contained in:
parent
61519014cb
commit
2ace5901df
@ -1,6 +1,6 @@
|
|||||||
[MASTER]
|
[MASTER]
|
||||||
persistent=no
|
persistent=no
|
||||||
ignore=tests,backup.py
|
ignore=tests
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
# abstract-class-little-used: see http://www.logilab.org/ticket/111138
|
# abstract-class-little-used: see http://www.logilab.org/ticket/111138
|
||||||
|
@ -26,7 +26,6 @@ import functools
|
|||||||
import termios
|
import termios
|
||||||
|
|
||||||
from qubes.utils import size_to_human
|
from qubes.utils import size_to_human
|
||||||
import sys
|
|
||||||
import stat
|
import stat
|
||||||
import os
|
import os
|
||||||
import fcntl
|
import fcntl
|
||||||
@ -37,7 +36,6 @@ import tempfile
|
|||||||
import time
|
import time
|
||||||
import grp
|
import grp
|
||||||
import pwd
|
import pwd
|
||||||
import errno
|
|
||||||
import datetime
|
import datetime
|
||||||
from multiprocessing import Queue, Process
|
from multiprocessing import Queue, Process
|
||||||
import qubes
|
import qubes
|
||||||
@ -173,15 +171,15 @@ class BackupHeader(object):
|
|||||||
"Unsupported backup version {}".format(self.version))
|
"Unsupported backup version {}".format(self.version))
|
||||||
|
|
||||||
def save(self, filename):
|
def save(self, filename):
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f_header:
|
||||||
# make sure 'version' is the first key
|
# make sure 'version' is the first key
|
||||||
f.write('version={}\n'.format(self.version))
|
f_header.write('version={}\n'.format(self.version))
|
||||||
for key, attr in self.header_keys.items():
|
for key, attr in self.header_keys.items():
|
||||||
if key == 'version':
|
if key == 'version':
|
||||||
continue
|
continue
|
||||||
if getattr(self, attr) is None:
|
if getattr(self, attr) is None:
|
||||||
continue
|
continue
|
||||||
f.write("{!s}={!s}\n".format(key, getattr(self, attr)))
|
f_header.write("{!s}={!s}\n".format(key, getattr(self, attr)))
|
||||||
|
|
||||||
|
|
||||||
class SendWorker(Process):
|
class SendWorker(Process):
|
||||||
@ -195,7 +193,7 @@ class SendWorker(Process):
|
|||||||
def run(self):
|
def run(self):
|
||||||
self.log.debug("Started sending thread")
|
self.log.debug("Started sending thread")
|
||||||
|
|
||||||
self.log.debug("Moving to temporary dir".format(self.base_dir))
|
self.log.debug("Moving to temporary dir %s", self.base_dir)
|
||||||
os.chdir(self.base_dir)
|
os.chdir(self.base_dir)
|
||||||
|
|
||||||
for filename in iter(self.queue.get, None):
|
for filename in iter(self.queue.get, None):
|
||||||
@ -308,26 +306,29 @@ class Backup(object):
|
|||||||
See attributes of this object for all available options.
|
See attributes of this object for all available options.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
# pylint: disable=too-many-instance-attributes
|
||||||
class FileToBackup(object):
|
class FileToBackup(object):
|
||||||
|
# pylint: disable=too-few-public-methods
|
||||||
def __init__(self, file_path, subdir=None, name=None):
|
def __init__(self, file_path, subdir=None, name=None):
|
||||||
sz = qubes.storage.file.get_disk_usage(file_path)
|
file_size = qubes.storage.file.get_disk_usage(file_path)
|
||||||
|
|
||||||
if subdir is None:
|
if subdir is None:
|
||||||
abs_file_path = os.path.abspath(file_path)
|
abs_file_path = os.path.abspath(file_path)
|
||||||
abs_base_dir = os.path.abspath(
|
abs_base_dir = os.path.abspath(
|
||||||
qubes.config.system_path["qubes_base_dir"]) + '/'
|
qubes.config.system_path["qubes_base_dir"]) + '/'
|
||||||
abs_file_dir = os.path.dirname(abs_file_path) + '/'
|
abs_file_dir = os.path.dirname(abs_file_path) + '/'
|
||||||
(nothing, directory, subdir) = abs_file_dir.partition(abs_base_dir)
|
(nothing, directory, subdir) = \
|
||||||
|
abs_file_dir.partition(abs_base_dir)
|
||||||
assert nothing == ""
|
assert nothing == ""
|
||||||
assert directory == abs_base_dir
|
assert directory == abs_base_dir
|
||||||
else:
|
else:
|
||||||
if len(subdir) > 0 and not subdir.endswith('/'):
|
if subdir and not subdir.endswith('/'):
|
||||||
subdir += '/'
|
subdir += '/'
|
||||||
|
|
||||||
#: real path to the file
|
#: real path to the file
|
||||||
self.path = file_path
|
self.path = file_path
|
||||||
#: size of the file
|
#: size of the file
|
||||||
self.size = sz
|
self.size = file_size
|
||||||
#: directory in backup archive where file should be placed
|
#: directory in backup archive where file should be placed
|
||||||
self.subdir = subdir
|
self.subdir = subdir
|
||||||
#: use this name in the archive (aka rename)
|
#: use this name in the archive (aka rename)
|
||||||
@ -336,6 +337,7 @@ class Backup(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
class VMToBackup(object):
|
class VMToBackup(object):
|
||||||
|
# pylint: disable=too-few-public-methods
|
||||||
def __init__(self, vm, files, subdir):
|
def __init__(self, vm, files, subdir):
|
||||||
self.vm = vm
|
self.vm = vm
|
||||||
self.files = files
|
self.files = files
|
||||||
@ -365,17 +367,11 @@ class Backup(object):
|
|||||||
self.tmpdir = None
|
self.tmpdir = None
|
||||||
|
|
||||||
# Backup settings - defaults
|
# Backup settings - defaults
|
||||||
#: should the backup be encrypted?
|
|
||||||
self.encrypted = True
|
|
||||||
#: should the backup be compressed?
|
#: should the backup be compressed?
|
||||||
self.compressed = True
|
self.compressed = True
|
||||||
#: what passphrase should be used to intergrity protect (and encrypt)
|
#: what passphrase should be used to intergrity protect (and encrypt)
|
||||||
#: the backup; required
|
#: the backup; required
|
||||||
self.passphrase = None
|
self.passphrase = None
|
||||||
#: custom hmac algorithm
|
|
||||||
self.hmac_algorithm = DEFAULT_HMAC_ALGORITHM
|
|
||||||
#: custom encryption algorithm
|
|
||||||
self.crypto_algorithm = DEFAULT_CRYPTO_ALGORITHM
|
|
||||||
#: custom compression filter; a program which process stdin to stdout
|
#: custom compression filter; a program which process stdin to stdout
|
||||||
self.compression_filter = DEFAULT_COMPRESSION_FILTER
|
self.compression_filter = DEFAULT_COMPRESSION_FILTER
|
||||||
#: VM to which backup should be sent (if any)
|
#: VM to which backup should be sent (if any)
|
||||||
@ -404,10 +400,6 @@ class Backup(object):
|
|||||||
|
|
||||||
self.log = logging.getLogger('qubes.backup')
|
self.log = logging.getLogger('qubes.backup')
|
||||||
|
|
||||||
if not self.encrypted:
|
|
||||||
self.log.warning('\'encrypted\' option is ignored, backup is '
|
|
||||||
'always encrypted')
|
|
||||||
|
|
||||||
if exclude_list is None:
|
if exclude_list is None:
|
||||||
exclude_list = []
|
exclude_list = []
|
||||||
|
|
||||||
@ -442,10 +434,7 @@ class Backup(object):
|
|||||||
# handle dom0 later
|
# handle dom0 later
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.encrypted:
|
|
||||||
subdir = 'vm%d/' % vm.qid
|
subdir = 'vm%d/' % vm.qid
|
||||||
else:
|
|
||||||
subdir = None
|
|
||||||
|
|
||||||
vm_files = []
|
vm_files = []
|
||||||
if vm.volumes['private'] is not None:
|
if vm.volumes['private'] is not None:
|
||||||
@ -500,48 +489,48 @@ class Backup(object):
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Display the header
|
# Display the header
|
||||||
for f in fields_to_display:
|
for field in fields_to_display:
|
||||||
fmt = "{{0:-^{0}}}-+".format(f["width"] + 1)
|
fmt = "{{0:-^{0}}}-+".format(field["width"] + 1)
|
||||||
summary += fmt.format('-')
|
summary += fmt.format('-')
|
||||||
summary += "\n"
|
summary += "\n"
|
||||||
for f in fields_to_display:
|
for field in fields_to_display:
|
||||||
fmt = "{{0:>{0}}} |".format(f["width"] + 1)
|
fmt = "{{0:>{0}}} |".format(field["width"] + 1)
|
||||||
summary += fmt.format(f["name"])
|
summary += fmt.format(field["name"])
|
||||||
summary += "\n"
|
summary += "\n"
|
||||||
for f in fields_to_display:
|
for field in fields_to_display:
|
||||||
fmt = "{{0:-^{0}}}-+".format(f["width"] + 1)
|
fmt = "{{0:-^{0}}}-+".format(field["width"] + 1)
|
||||||
summary += fmt.format('-')
|
summary += fmt.format('-')
|
||||||
summary += "\n"
|
summary += "\n"
|
||||||
|
|
||||||
files_to_backup = self._files_to_backup
|
files_to_backup = self._files_to_backup
|
||||||
|
|
||||||
for qid, vm_info in files_to_backup.items():
|
for qid, vm_info in files_to_backup.items():
|
||||||
s = ""
|
summary_line = ""
|
||||||
fmt = "{{0:>{0}}} |".format(fields_to_display[0]["width"] + 1)
|
fmt = "{{0:>{0}}} |".format(fields_to_display[0]["width"] + 1)
|
||||||
s += fmt.format(vm_info['vm'].name)
|
summary_line += fmt.format(vm_info['vm'].name)
|
||||||
|
|
||||||
fmt = "{{0:>{0}}} |".format(fields_to_display[1]["width"] + 1)
|
fmt = "{{0:>{0}}} |".format(fields_to_display[1]["width"] + 1)
|
||||||
if qid == 0:
|
if qid == 0:
|
||||||
s += fmt.format("User home")
|
summary_line += fmt.format("User home")
|
||||||
elif isinstance(vm_info['vm'], qubes.vm.templatevm.TemplateVM):
|
elif isinstance(vm_info['vm'], qubes.vm.templatevm.TemplateVM):
|
||||||
s += fmt.format("Template VM")
|
summary_line += fmt.format("Template VM")
|
||||||
else:
|
else:
|
||||||
s += fmt.format("VM" + (" + Sys" if vm_info['vm'].updateable
|
summary_line += fmt.format("VM" + (" + Sys" if
|
||||||
else ""))
|
vm_info['vm'].updateable else ""))
|
||||||
|
|
||||||
vm_size = vm_info['size']
|
vm_size = vm_info['size']
|
||||||
|
|
||||||
fmt = "{{0:>{0}}} |".format(fields_to_display[2]["width"] + 1)
|
fmt = "{{0:>{0}}} |".format(fields_to_display[2]["width"] + 1)
|
||||||
s += fmt.format(size_to_human(vm_size))
|
summary_line += fmt.format(size_to_human(vm_size))
|
||||||
|
|
||||||
if qid != 0 and vm_info['vm'].is_running():
|
if qid != 0 and vm_info['vm'].is_running():
|
||||||
s += " <-- The VM is running, please shut it down before proceeding " \
|
summary_line += " <-- The VM is running, please shut down it " \
|
||||||
"with the backup!"
|
"before proceeding with the backup!"
|
||||||
|
|
||||||
summary += s + "\n"
|
summary += summary_line + "\n"
|
||||||
|
|
||||||
for f in fields_to_display:
|
for field in fields_to_display:
|
||||||
fmt = "{{0:-^{0}}}-+".format(f["width"] + 1)
|
fmt = "{{0:-^{0}}}-+".format(field["width"] + 1)
|
||||||
summary += fmt.format('-')
|
summary += fmt.format('-')
|
||||||
summary += "\n"
|
summary += "\n"
|
||||||
|
|
||||||
@ -553,8 +542,8 @@ class Backup(object):
|
|||||||
summary += fmt.format(size_to_human(self.total_backup_bytes))
|
summary += fmt.format(size_to_human(self.total_backup_bytes))
|
||||||
summary += "\n"
|
summary += "\n"
|
||||||
|
|
||||||
for f in fields_to_display:
|
for field in fields_to_display:
|
||||||
fmt = "{{0:-^{0}}}-+".format(f["width"] + 1)
|
fmt = "{{0:-^{0}}}-+".format(field["width"] + 1)
|
||||||
summary += fmt.format('-')
|
summary += fmt.format('-')
|
||||||
summary += "\n"
|
summary += "\n"
|
||||||
|
|
||||||
@ -569,9 +558,8 @@ class Backup(object):
|
|||||||
header_file_path = os.path.join(self.tmpdir, HEADER_FILENAME)
|
header_file_path = os.path.join(self.tmpdir, HEADER_FILENAME)
|
||||||
backup_header = BackupHeader(
|
backup_header = BackupHeader(
|
||||||
version=CURRENT_BACKUP_FORMAT_VERSION,
|
version=CURRENT_BACKUP_FORMAT_VERSION,
|
||||||
hmac_algorithm=self.hmac_algorithm,
|
hmac_algorithm=DEFAULT_HMAC_ALGORITHM,
|
||||||
crypto_algorithm=self.crypto_algorithm,
|
encrypted=True,
|
||||||
encrypted=self.encrypted,
|
|
||||||
compressed=self.compressed,
|
compressed=self.compressed,
|
||||||
compression_filter=self.compression_filter,
|
compression_filter=self.compression_filter,
|
||||||
backup_id=self.backup_id,
|
backup_id=self.backup_id,
|
||||||
@ -609,6 +597,7 @@ class Backup(object):
|
|||||||
progress = (
|
progress = (
|
||||||
100 * (self._done_vms_bytes + self._current_vm_bytes) /
|
100 * (self._done_vms_bytes + self._current_vm_bytes) /
|
||||||
self.total_backup_bytes)
|
self.total_backup_bytes)
|
||||||
|
# pylint: disable=not-callable
|
||||||
self.progress_callback(progress)
|
self.progress_callback(progress)
|
||||||
|
|
||||||
def _add_vm_progress(self, bytes_done):
|
def _add_vm_progress(self, bytes_done):
|
||||||
@ -616,6 +605,7 @@ class Backup(object):
|
|||||||
self._send_progress_update()
|
self._send_progress_update()
|
||||||
|
|
||||||
def backup_do(self):
|
def backup_do(self):
|
||||||
|
# pylint: disable=too-many-statements
|
||||||
if self.passphrase is None:
|
if self.passphrase is None:
|
||||||
raise qubes.exc.QubesException("No passphrase set")
|
raise qubes.exc.QubesException("No passphrase set")
|
||||||
qubes_xml = self.app.store
|
qubes_xml = self.app.store
|
||||||
@ -685,8 +675,8 @@ class Backup(object):
|
|||||||
send_proc = SendWorker(to_send, self.tmpdir, backup_stdout)
|
send_proc = SendWorker(to_send, self.tmpdir, backup_stdout)
|
||||||
send_proc.start()
|
send_proc.start()
|
||||||
|
|
||||||
for f in header_files:
|
for file_name in header_files:
|
||||||
to_send.put(f)
|
to_send.put(file_name)
|
||||||
|
|
||||||
qubes_xml_info = self.VMToBackup(
|
qubes_xml_info = self.VMToBackup(
|
||||||
None,
|
None,
|
||||||
@ -879,7 +869,7 @@ def handle_streams(stream_in, streams_out, processes, size_limit=None,
|
|||||||
else:
|
else:
|
||||||
to_copy = buffer_size
|
to_copy = buffer_size
|
||||||
buf = stream_in.read(to_copy)
|
buf = stream_in.read(to_copy)
|
||||||
if not len(buf):
|
if not buf:
|
||||||
# done
|
# done
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user