From c47e29ed5011716416d753299778b43d073bb2a6 Mon Sep 17 00:00:00 2001 From: Wojtek Porczyk Date: Fri, 29 Jan 2016 17:56:33 +0100 Subject: [PATCH] Fix most errors from pylint --- qubes/config.py | 4 +- qubes/storage/__init__.py | 93 ++++++++++++++++++--------------------- qubes/storage/xen.py | 8 ++-- qubes/utils.py | 1 + qubes/vm/mix/net.py | 18 +++++--- qubes/vm/qubesvm.py | 44 +++++++++--------- 6 files changed, 83 insertions(+), 85 deletions(-) diff --git a/qubes/config.py b/qubes/config.py index 82f2964c..467f7342 100644 --- a/qubes/config.py +++ b/qubes/config.py @@ -83,8 +83,8 @@ defaults = { 'root_img_size': 10*1024*1024*1024, 'storage_class': 'qubes.storage.xen.XenStorage', - 'pool_drivers': {'xen': 'qubes.storage.xen.XenPool'} - 'pool_config': {'dir_path': '/var/lib/qubes'} + 'pool_drivers': {'xen': 'qubes.storage.xen.XenPool'}, + 'pool_config': {'dir_path': '/var/lib/qubes'}, # how long (in sec) to wait for VMs to shutdown, # before killing them (when used qvm-run with --wait option), diff --git a/qubes/storage/__init__.py b/qubes/storage/__init__.py index 32dbef6e..3bd8f57e 100644 --- a/qubes/storage/__init__.py +++ b/qubes/storage/__init__.py @@ -26,6 +26,7 @@ from __future__ import absolute_import +import ConfigParser import importlib import os import os.path @@ -41,17 +42,24 @@ import qubes.utils BLKSIZE = 512 CONFIG_FILE = '/etc/qubes/storage.conf' + +class StoragePoolException(qubes.exc.QubesException): + pass + + class Storage(object): '''Class for handling VM virtual disks. This is base class for all other implementations, mostly with Xen on Linux in mind. - ''' # pylint: disable=abstract-class-little-used + ''' root_img = None private_img = None volatile_img = None + modules_dev = None + def __init__(self, vm, private_img_size=None, root_img_size=None): #: Domain for which we manage storage @@ -92,10 +100,10 @@ class Storage(object): def volatile_dev_config(self): raise NotImplementedError() - def other_dev_config(self) + def other_dev_config(self): if self.modules_img is not None: - return self.format_disk_dev(self.modules_img, None, - self.modules_dev, rw=self.modules_img_rw) + return self.format_disk_dev(self.modules_img, self.modules_dev, + rw=self.modules_img_rw) elif self.drive is not None: (drive_type, drive_domain, drive_path) = self.drive.split(":") if drive_type == 'hd': @@ -107,16 +115,15 @@ class Storage(object): drive_domain = None return self.format_disk_dev(drive_path, - None, self.modules_dev, rw=rw, - type=drive_type, + devtype=drive_type, domain=drive_domain) else: return '' - def format_disk_dev(self, path, script, vdev, rw=True, type='disk', + def format_disk_dev(self, path, vdev, script=None, rw=True, devtype='disk', domain=None): raise NotImplementedError() @@ -167,9 +174,6 @@ class Storage(object): else os.path.join(rel or self.vm.dir_path, path) - def get_config_params(self): - raise NotImplementedError() - @staticmethod def _copy_file(source, destination): '''Effective file copy, preserving sparse files etc. @@ -353,16 +357,28 @@ def get_disk_usage(path): return ret -#def get_storage(vm): -# '''Factory yielding storage class instances for domains. -# -# :raises ImportError: when storage class specified in config cannot be found -# :raises KeyError: when storage class specified in config cannot be found -# ''' -# pkg, cls = qubes.config.defaults['storage_class'].strip().rsplit('.', 1) -# -# # this may raise ImportError or KeyError, that's okay -# return importlib.import_module(pkg).__dict__[cls](vm) +def load(clsname): + '''Given a dotted full module string representation of a class it loads it + + Args: + string (str) i.e. 'qubes.storage.xen.QubesXenVmStorage' + + Returns: + type + + See also: + :func:`qubes.storage.dump` + + :raises ImportError: when storage class specified in config cannot be found + :raises KeyError: when storage class specified in config cannot be found + ''' + + if not isinstance(clsname, basestring): + return clsname + pkg, cls = clsname.strip().rsplit('.', 1) + + # this may raise ImportError or KeyError, that's okay + return importlib.import_module(pkg).__dict__[cls] def dump(o): @@ -377,30 +393,6 @@ def dump(o): return o.__module__ + '.' + o.__class__.__name__ -def load(string): - """ Given a dotted full module string representation of a class it loads it - - Args: - string (str) i.e. 'qubes.storage.xen.QubesXenVmStorage' - - Returns: - type - - See also: - :func:`qubes.storage.dump` - """ - if not type(string) is str: - # This is a hack which allows giving a real class to a vm instead of a - # string as string_class parameter. - return string - - components = string.split(".") - module_path = ".".join(components[:-1]) - klass = components[-1:][0] - module = __import__(module_path, fromlist=[klass]) - return getattr(module, klass) - - def get_pool(name, vm): """ Instantiates the storage for the specified vm """ config = _get_storage_config_parser() @@ -412,7 +404,7 @@ def get_pool(name, vm): config_kwargs = dict(zip(keys, values)) if name == 'default': - kwargs = defaults['pool_config'].copy() + kwargs = qubes.config.defaults['pool_config'].copy() kwargs.update(keys) else: kwargs = config_kwargs @@ -478,16 +470,12 @@ def _get_pool_klass(name, config=None): klass = load(config.get(name, 'class')) elif config.has_option(name, 'driver'): pool_driver = config.get(name, 'driver') - klass = defaults['pool_drivers'][pool_driver] + klass = qubes.config.defaults['pool_drivers'][pool_driver] else: raise StoragePoolException('Uknown storage pool driver ' + name) return klass -class StoragePoolException(QubesException): - pass - - class Pool(object): def __init__(self, vm, dir_path): assert vm is not None @@ -509,6 +497,8 @@ class Pool(object): vm_templates_path = os.path.join(self.dir_path, 'vm-templates') self.create_dir_if_not_exists(vm_templates_path) + # XXX there is also a class attribute on the domain classes which does + # exactly that -- which one should prevail? def vmdir_path(self, vm, pool_dir): """ Returns the path to vmdir depending on the type of the VM. @@ -537,7 +527,8 @@ class Pool(object): subdir = 'appvms' return os.path.join(pool_dir, subdir, vm.template.name + '-dvm') else: - raise QubesException(vm.type() + ' unknown vm type') + raise qubes.exc.QubesException( + 'unknown vm type: {!r}'.format(vm.type())) return os.path.join(pool_dir, subdir, vm.name) diff --git a/qubes/storage/xen.py b/qubes/storage/xen.py index ba8a0f73..5205f72e 100644 --- a/qubes/storage/xen.py +++ b/qubes/storage/xen.py @@ -92,9 +92,7 @@ class XenStorage(qubes.storage.Storage): return self.abspath(qubes.config.vm_files['volatile_img']) - # pylint: disable=redefined-builtin - @staticmethod - def format_disk_dev(path, vdev, script=None, rw=True, type='disk', + def format_disk_dev(self, path, vdev, script=None, rw=True, devtype='disk', domain=None): if path is None: return '' @@ -261,8 +259,9 @@ class XenStorage(qubes.storage.Storage): # FIXME stat on f_root; with open() ... f_volatile = open(self.volatile_img, "w") f_root = open(source_template.storage.root_img, "r") + # make empty sparse file of the same size as root.img f_root.seek(0, os.SEEK_END) - f_volatile.truncate(f_root.tell()) # make empty sparse file of the same size as root.img + f_volatile.truncate(f_root.tell()) f_volatile.close() f_root.close() return # XXX why is that? super() does not run @@ -275,6 +274,7 @@ class XenStorage(qubes.storage.Storage): super(XenStorage, self).prepare_for_vm_startup() if self.drive is not None: + # pylint: disable=unused-variable (drive_type, drive_domain, drive_path) = self.drive.split(":") if drive_domain.lower() != "dom0": diff --git a/qubes/utils.py b/qubes/utils.py index 8ff1d069..08646d73 100644 --- a/qubes/utils.py +++ b/qubes/utils.py @@ -24,6 +24,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +import hashlib import os import re import subprocess diff --git a/qubes/vm/mix/net.py b/qubes/vm/mix/net.py index d05c37c4..35f8f378 100644 --- a/qubes/vm/mix/net.py +++ b/qubes/vm/mix/net.py @@ -24,9 +24,16 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +import os +import shutil +import time import weakref +import libvirt +import lxml.etree + import qubes +import qubes.exc class NetVMMixin(object): mac = qubes.property('mac', type=str, @@ -70,10 +77,11 @@ class NetVMMixin(object): # those properties and methods are most likely accessed as vm.netvm. # - def get_ip_for_vm(self, vm): + @staticmethod + def get_ip_for_vm(vm): '''Get IP address for (appvm) domain connected to this (netvm) domain. ''' - import qubes.vm.dispvm + import qubes.vm.dispvm # pylint: disable=redefined-outer-name if isinstance(vm, qubes.vm.dispvm.DispVM): return '10.138.{}.{}'.format((vm.dispid >> 8) & 7, vm.dispid & 7) @@ -150,13 +158,13 @@ class NetVMMixin(object): try: vm.attach_network(wait=False) - except QubesException as e: + except qubes.exc.QubesException: vm.log.warning('Cannot attach network', exc_info=1) @qubes.events.handler('pre-domain-shutdown') def shutdown_net(self, force=False): - connected_vms = [vm for vm in self.connected_vms.values() if vm.is_running()] + connected_vms = [vm for vm in self.connected_vms if vm.is_running()] if connected_vms and not force: raise qubes.exc.QubesVMError( 'There are other VMs connected to this VM: {}'.format( @@ -170,7 +178,7 @@ class NetVMMixin(object): if vm.is_running(): try: vm.detach_network() - except (QubesException, libvirt.libvirtError): + except (qubes.exc.QubesException, libvirt.libvirtError): # ignore errors pass diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index 52ed1250..f9a5ae5c 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -26,10 +26,12 @@ from __future__ import absolute_import +import base64 import datetime import itertools import os import os.path +import pipes import re import shutil import subprocess @@ -39,7 +41,6 @@ import uuid import warnings import libvirt -import lxml.etree import qubes import qubes.config @@ -388,9 +389,9 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): return isinstance(self, qubes.vm.appvm.AppVM) def is_proxyvm(self): - warnings.warn('vm.is_proxyvm() is deprecated, use isinstance()', + warnings.warn('vm.is_proxyvm() is deprecated', DeprecationWarning) - return isinstance(self, qubes.vm.proxyvm.ProxyVM) + return self.netvm is not None and self.provides_network def is_disposablevm(self): warnings.warn('vm.is_disposable() is deprecated, use isinstance()', @@ -513,18 +514,14 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): self._qdb_connection = None self.storage.rename( - self._get_dir_path(new_name), - self._get_dir_path(old_name)) + os.path.join(qubes.config.system_path['qubes_base_dir'], + self.dir_path_prefix, new_name), + os.path.join(qubes.config.system_path['qubes_base_dir'], + self.dir_path_prefix, old_name)) - if self.property_is_default('conf_file'): - new_conf = os.path.join( - self.dir_path, _default_conf_file(self, old_name)) - old_conf = os.path.join( - self.dir_path, _default_conf_file(self, old_name)) - self.storage.rename(old_conf, new_conf) - - self.fire_event('property-set:conf_file', 'conf_file', - new_conf, old_conf) + self.storage.rename( + os.path.join(self.dir_path, new_name + '.conf'), + os.path.join(self.dir_path, old_name + '.conf')) self._update_libvirt_domain() @@ -662,11 +659,11 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): self.log.warning('Activating the {} VM'.format(self.name)) self.libvirt_domain.resume() - # close() is not really needed, because the descriptor is close-on-exec - # anyway, the reason to postpone close() is that possibly xl is not done - # constructing the domain after its main process exits - # so we close() when we know the domain is up - # the successful unpause is some indicator of it + # close() is not really needed, because the descriptor is + # close-on-exec anyway, the reason to postpone close() is that + # possibly xl is not done constructing the domain after its main + # process exits so we close() when we know the domain is up the + # successful unpause is some indicator of it if qmemman_client: qmemman_client.close() @@ -915,7 +912,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): return MEM_OVERHEAD_BASE = (3 + 1) * 1024 * 1024 - MEM_OVERHEAD_PER_CPU = 3 * 1024 * 1024 / 2 + MEM_OVERHEAD_PER_VCPU = 3 * 1024 * 1024 / 2 if mem_required is None: mem_required = int(self.memory) * 1024 * 1024 @@ -1123,9 +1120,9 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): if not allow_start: raise qubes.exc.QubesException( 'The qube has to be started to complete the operation, but is' - ' required not to start. Either run the operation again allowing' - ' starting of the qube this time, or run resize2fs in the qube' - ' manually.') + ' required not to start. Either run the operation again' + ' allowing starting of the qube this time, or run resize2fs' + ' in the qube manually.') self.start(start_guid=False) @@ -1291,6 +1288,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): try: if libvirt_domain.isActive(): + # pylint: disable=line-too-long if libvirt_domain.state()[0] == libvirt.VIR_DOMAIN_PAUSED: return "Paused" elif libvirt_domain.state()[0] == libvirt.VIR_DOMAIN_CRASHED: