Browse Source

Fix most errors from pylint

Wojtek Porczyk 8 years ago
parent
commit
c47e29ed50
6 changed files with 83 additions and 85 deletions
  1. 2 2
      qubes/config.py
  2. 42 51
      qubes/storage/__init__.py
  3. 4 4
      qubes/storage/xen.py
  4. 1 0
      qubes/utils.py
  5. 13 5
      qubes/vm/mix/net.py
  6. 21 23
      qubes/vm/qubesvm.py

+ 2 - 2
qubes/config.py

@@ -83,8 +83,8 @@ defaults = {
     'root_img_size': 10*1024*1024*1024,
     'root_img_size': 10*1024*1024*1024,
 
 
     'storage_class': 'qubes.storage.xen.XenStorage',
     '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,
     # how long (in sec) to wait for VMs to shutdown,
     # before killing them (when used qvm-run with --wait option),
     # before killing them (when used qvm-run with --wait option),

+ 42 - 51
qubes/storage/__init__.py

@@ -26,6 +26,7 @@
 
 
 from __future__ import absolute_import
 from __future__ import absolute_import
 
 
+import ConfigParser
 import importlib
 import importlib
 import os
 import os
 import os.path
 import os.path
@@ -41,17 +42,24 @@ import qubes.utils
 BLKSIZE = 512
 BLKSIZE = 512
 CONFIG_FILE = '/etc/qubes/storage.conf'
 CONFIG_FILE = '/etc/qubes/storage.conf'
 
 
+
+class StoragePoolException(qubes.exc.QubesException):
+    pass
+
+
 class Storage(object):
 class Storage(object):
     '''Class for handling VM virtual disks.
     '''Class for handling VM virtual disks.
 
 
     This is base class for all other implementations, mostly with Xen on Linux
     This is base class for all other implementations, mostly with Xen on Linux
     in mind.
     in mind.
-    ''' # pylint: disable=abstract-class-little-used
+    '''
 
 
     root_img = None
     root_img = None
     private_img = None
     private_img = None
     volatile_img = None
     volatile_img = None
 
 
+    modules_dev = None
+
     def __init__(self, vm, private_img_size=None, root_img_size=None):
     def __init__(self, vm, private_img_size=None, root_img_size=None):
 
 
         #: Domain for which we manage storage
         #: Domain for which we manage storage
@@ -92,10 +100,10 @@ class Storage(object):
     def volatile_dev_config(self):
     def volatile_dev_config(self):
         raise NotImplementedError()
         raise NotImplementedError()
 
 
-    def other_dev_config(self)
+    def other_dev_config(self):
         if self.modules_img is not None:
         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:
         elif self.drive is not None:
             (drive_type, drive_domain, drive_path) = self.drive.split(":")
             (drive_type, drive_domain, drive_path) = self.drive.split(":")
             if drive_type == 'hd':
             if drive_type == 'hd':
@@ -107,16 +115,15 @@ class Storage(object):
                 drive_domain = None
                 drive_domain = None
 
 
             return self.format_disk_dev(drive_path,
             return self.format_disk_dev(drive_path,
-                None,
                 self.modules_dev,
                 self.modules_dev,
                 rw=rw,
                 rw=rw,
-                type=drive_type,
+                devtype=drive_type,
                 domain=drive_domain)
                 domain=drive_domain)
 
 
         else:
         else:
             return ''
             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):
             domain=None):
         raise NotImplementedError()
         raise NotImplementedError()
 
 
@@ -167,9 +174,6 @@ class Storage(object):
             else os.path.join(rel or self.vm.dir_path, path)
             else os.path.join(rel or self.vm.dir_path, path)
 
 
 
 
-    def get_config_params(self):
-        raise NotImplementedError()
-
     @staticmethod
     @staticmethod
     def _copy_file(source, destination):
     def _copy_file(source, destination):
         '''Effective file copy, preserving sparse files etc.
         '''Effective file copy, preserving sparse files etc.
@@ -353,16 +357,28 @@ def get_disk_usage(path):
     return ret
     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):
 def dump(o):
@@ -377,30 +393,6 @@ def dump(o):
     return o.__module__ + '.' + o.__class__.__name__
     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):
 def get_pool(name, vm):
     """ Instantiates the storage for the specified vm """
     """ Instantiates the storage for the specified vm """
     config = _get_storage_config_parser()
     config = _get_storage_config_parser()
@@ -412,7 +404,7 @@ def get_pool(name, vm):
     config_kwargs = dict(zip(keys, values))
     config_kwargs = dict(zip(keys, values))
 
 
     if name == 'default':
     if name == 'default':
-        kwargs = defaults['pool_config'].copy()
+        kwargs = qubes.config.defaults['pool_config'].copy()
         kwargs.update(keys)
         kwargs.update(keys)
     else:
     else:
         kwargs = config_kwargs
         kwargs = config_kwargs
@@ -478,16 +470,12 @@ def _get_pool_klass(name, config=None):
         klass = load(config.get(name, 'class'))
         klass = load(config.get(name, 'class'))
     elif config.has_option(name, 'driver'):
     elif config.has_option(name, 'driver'):
         pool_driver = config.get(name, 'driver')
         pool_driver = config.get(name, 'driver')
-        klass = defaults['pool_drivers'][pool_driver]
+        klass = qubes.config.defaults['pool_drivers'][pool_driver]
     else:
     else:
         raise StoragePoolException('Uknown storage pool driver ' + name)
         raise StoragePoolException('Uknown storage pool driver ' + name)
     return klass
     return klass
 
 
 
 
-class StoragePoolException(QubesException):
-    pass
-
-
 class Pool(object):
 class Pool(object):
     def __init__(self, vm, dir_path):
     def __init__(self, vm, dir_path):
         assert vm is not None
         assert vm is not None
@@ -509,6 +497,8 @@ class Pool(object):
         vm_templates_path = os.path.join(self.dir_path, 'vm-templates')
         vm_templates_path = os.path.join(self.dir_path, 'vm-templates')
         self.create_dir_if_not_exists(vm_templates_path)
         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):
     def vmdir_path(self, vm, pool_dir):
         """ Returns the path to vmdir depending on the type of the VM.
         """ Returns the path to vmdir depending on the type of the VM.
 
 
@@ -537,7 +527,8 @@ class Pool(object):
             subdir = 'appvms'
             subdir = 'appvms'
             return os.path.join(pool_dir, subdir, vm.template.name + '-dvm')
             return os.path.join(pool_dir, subdir, vm.template.name + '-dvm')
         else:
         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)
         return os.path.join(pool_dir, subdir, vm.name)
 
 

+ 4 - 4
qubes/storage/xen.py

@@ -92,9 +92,7 @@ class XenStorage(qubes.storage.Storage):
         return self.abspath(qubes.config.vm_files['volatile_img'])
         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):
             domain=None):
         if path is None:
         if path is None:
             return ''
             return ''
@@ -261,8 +259,9 @@ class XenStorage(qubes.storage.Storage):
                 # FIXME stat on f_root; with open() ...
                 # FIXME stat on f_root; with open() ...
                 f_volatile = open(self.volatile_img, "w")
                 f_volatile = open(self.volatile_img, "w")
                 f_root = open(source_template.storage.root_img, "r")
                 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_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_volatile.close()
                 f_root.close()
                 f_root.close()
                 return # XXX why is that? super() does not run
                 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()
         super(XenStorage, self).prepare_for_vm_startup()
 
 
         if self.drive is not None:
         if self.drive is not None:
+            # pylint: disable=unused-variable
             (drive_type, drive_domain, drive_path) = self.drive.split(":")
             (drive_type, drive_domain, drive_path) = self.drive.split(":")
 
 
             if drive_domain.lower() != "dom0":
             if drive_domain.lower() != "dom0":

+ 1 - 0
qubes/utils.py

@@ -24,6 +24,7 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
 #
 
 
+import hashlib
 import os
 import os
 import re
 import re
 import subprocess
 import subprocess

+ 13 - 5
qubes/vm/mix/net.py

@@ -24,9 +24,16 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
 #
 
 
+import os
+import shutil
+import time
 import weakref
 import weakref
 
 
+import libvirt
+import lxml.etree
+
 import qubes
 import qubes
+import qubes.exc
 
 
 class NetVMMixin(object):
 class NetVMMixin(object):
     mac = qubes.property('mac', type=str,
     mac = qubes.property('mac', type=str,
@@ -70,10 +77,11 @@ class NetVMMixin(object):
     # those properties and methods are most likely accessed as vm.netvm.<prop>
     # those properties and methods are most likely accessed as vm.netvm.<prop>
     #
     #
 
 
-    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.
         '''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):
         if isinstance(vm, qubes.vm.dispvm.DispVM):
             return '10.138.{}.{}'.format((vm.dispid >> 8) & 7, vm.dispid & 7)
             return '10.138.{}.{}'.format((vm.dispid >> 8) & 7, vm.dispid & 7)
 
 
@@ -150,13 +158,13 @@ class NetVMMixin(object):
 
 
             try:
             try:
                 vm.attach_network(wait=False)
                 vm.attach_network(wait=False)
-            except QubesException as e:
+            except qubes.exc.QubesException:
                 vm.log.warning('Cannot attach network', exc_info=1)
                 vm.log.warning('Cannot attach network', exc_info=1)
 
 
 
 
     @qubes.events.handler('pre-domain-shutdown')
     @qubes.events.handler('pre-domain-shutdown')
     def shutdown_net(self, force=False):
     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:
         if connected_vms and not force:
             raise qubes.exc.QubesVMError(
             raise qubes.exc.QubesVMError(
                 'There are other VMs connected to this VM: {}'.format(
                 'There are other VMs connected to this VM: {}'.format(
@@ -170,7 +178,7 @@ class NetVMMixin(object):
             if vm.is_running():
             if vm.is_running():
                 try:
                 try:
                     vm.detach_network()
                     vm.detach_network()
-                except (QubesException, libvirt.libvirtError):
+                except (qubes.exc.QubesException, libvirt.libvirtError):
                     # ignore errors
                     # ignore errors
                     pass
                     pass
 
 

+ 21 - 23
qubes/vm/qubesvm.py

@@ -26,10 +26,12 @@
 
 
 from __future__ import absolute_import
 from __future__ import absolute_import
 
 
+import base64
 import datetime
 import datetime
 import itertools
 import itertools
 import os
 import os
 import os.path
 import os.path
+import pipes
 import re
 import re
 import shutil
 import shutil
 import subprocess
 import subprocess
@@ -39,7 +41,6 @@ import uuid
 import warnings
 import warnings
 
 
 import libvirt
 import libvirt
-import lxml.etree
 
 
 import qubes
 import qubes
 import qubes.config
 import qubes.config
@@ -388,9 +389,9 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
         return isinstance(self, qubes.vm.appvm.AppVM)
         return isinstance(self, qubes.vm.appvm.AppVM)
 
 
     def is_proxyvm(self):
     def is_proxyvm(self):
-        warnings.warn('vm.is_proxyvm() is deprecated, use isinstance()',
+        warnings.warn('vm.is_proxyvm() is deprecated',
             DeprecationWarning)
             DeprecationWarning)
-        return isinstance(self, qubes.vm.proxyvm.ProxyVM)
+        return self.netvm is not None and self.provides_network
 
 
     def is_disposablevm(self):
     def is_disposablevm(self):
         warnings.warn('vm.is_disposable() is deprecated, use isinstance()',
         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._qdb_connection = None
 
 
         self.storage.rename(
         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()
         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.log.warning('Activating the {} VM'.format(self.name))
             self.libvirt_domain.resume()
             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:
             if qmemman_client:
                 qmemman_client.close()
                 qmemman_client.close()
 
 
@@ -915,7 +912,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
             return
             return
 
 
         MEM_OVERHEAD_BASE = (3 + 1) * 1024 * 1024
         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:
         if mem_required is None:
             mem_required = int(self.memory) * 1024 * 1024
             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:
         if not allow_start:
             raise qubes.exc.QubesException(
             raise qubes.exc.QubesException(
                 'The qube has to be started to complete the operation, but is'
                 '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)
         self.start(start_guid=False)
 
 
@@ -1291,6 +1288,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
 
 
         try:
         try:
             if libvirt_domain.isActive():
             if libvirt_domain.isActive():
+                # pylint: disable=line-too-long
                 if libvirt_domain.state()[0] == libvirt.VIR_DOMAIN_PAUSED:
                 if libvirt_domain.state()[0] == libvirt.VIR_DOMAIN_PAUSED:
                     return "Paused"
                     return "Paused"
                 elif libvirt_domain.state()[0] == libvirt.VIR_DOMAIN_CRASHED:
                 elif libvirt_domain.state()[0] == libvirt.VIR_DOMAIN_CRASHED: