Replace pool config parsing logic

- Move add_pool/remove_pool to Qubes class
- Add Qubes.get_pool
- Remove storage.conf
This commit is contained in:
Bahtiar `kalkin-` Gadimov 2016-03-21 12:20:19 +01:00
parent c791cb1935
commit 36470310a2
5 changed files with 57 additions and 113 deletions

View File

@ -60,7 +60,6 @@ endif
# $(MAKE) install -C tests
$(MAKE) install -C relaxng
mkdir -p $(DESTDIR)/etc/qubes
cp etc/storage.conf $(DESTDIR)/etc/qubes/
ifeq ($(BACKEND_VMM),xen)
# Currently supported only on xen
cp etc/qmemman.conf $(DESTDIR)/etc/qubes/

View File

@ -1,13 +0,0 @@
[default] ; poolname
driver=xen ; the default xen storage
; class = qubes.storage.xen.XenStorage ; class always overwrites the driver
;
; To use our own pool driver it needs to provide `qubes.storage` entry_point
; see also: https://pythonhosted.org/setuptools/setuptools.html#dynamic-discovery-of-services-and-plugins
; class name
; [pool-b]
; driver = foo
;
; [test-dummy]
; driver=dummy

View File

@ -48,8 +48,6 @@ import time
import __builtin__
import docutils.core
import docutils.io
import jinja2
import lxml.etree
import pkg_resources
@ -1190,8 +1188,8 @@ class Qubes(PropertyHolder):
#: collection of all available labels for VMs
self.labels = {}
#: collection of all available pool configurations
self.pool_configs = {}
#: collection of all pools
self.pools = {}
#: Connection to VMM
self.vmm = VMMConnection()
@ -1262,9 +1260,11 @@ class Qubes(PropertyHolder):
for node in self.xml.xpath('./pools/pool'):
name = node.get('name')
config_data = node.attrib
del(config_data['name'])
self.pool_configs[name] = config_data
assert name, "Pool name '%s' is invalid " % name
try:
self.pools[name] = self._get_pool(**node.attrib)
except qubes.exc.QubesException as e:
self.log.error(e.message)
# stage 2: load VMs
for node in self.xml.xpath('./domains/domain'):
@ -1400,7 +1400,9 @@ class Qubes(PropertyHolder):
7: Label(7, '0x75507b', 'purple'),
8: Label(8, '0x000000', 'black'),
}
self.pool_configs['default'] = qubes.config.defaults['pool_config']
for name, config in qubes.config.defaults['pool_configs'].items():
self.pools[name] = self._get_pool(**config)
self.domains.add(
qubes.vm.adminvm.AdminVM(self, None, qid=0, name='dom0'))
self.save()
@ -1421,12 +1423,12 @@ class Qubes(PropertyHolder):
def xml_pool_configs(self):
""" Helper for converting pools config to xml """
pools = lxml.etree.Element('pools')
for config_data in self.pool_configs.values():
p = lxml.etree.Element('pool', **config_data)
pools.append(p)
pools_xml = lxml.etree.Element('pools')
for pool in self.pools.values():
p = lxml.etree.Element('pool', **pool.config)
pools_xml.append(p)
return pools
return pools_xml
def get_vm_class(self, clsname):
'''Find the class for a domain.
@ -1487,6 +1489,48 @@ class Qubes(PropertyHolder):
raise KeyError(label)
def add_pool(self, **kwargs):
""" Add a storage pool to config."""
name = kwargs['name']
self.pools[name] = self._get_pool(**kwargs)
self.save()
def remove_pool(self, name):
""" Remove a storage pool from config file. """
try:
del self.pools[name]
except KeyError:
return
self.save()
def get_pool(self, name):
''' Returns a :py:class:`qubes.storage.Pool` instance '''
try:
return self.pools[name]
except KeyError:
raise qubes.exc.QubesException('Unknown storage pool ' + name)
def _get_pool(self, **kwargs):
try:
name = kwargs['name']
assert name, 'Name needs to be an non empty string'
except KeyError:
raise qubes.exc.QubesException('No pool name for pool')
try:
driver = kwargs['driver']
except KeyError:
raise qubes.exc.QubesException('No driver specified for pool ' +
name)
try:
klass = qubes.get_entry_point_one(
qubes.storage.STORAGE_ENTRY_POINT, driver)
del kwargs['driver']
return klass(**kwargs)
except KeyError:
raise qubes.exc.QubesException('Driver %s for pool %s' %
(driver, name))
@qubes.events.handler('domain-pre-delete')
def on_domain_pre_deleted(self, event, vm):

View File

@ -28,7 +28,6 @@
from __future__ import absolute_import
import ConfigParser
import os
import os.path
import shutil
@ -40,7 +39,6 @@ import qubes.exc
import qubes.utils
BLKSIZE = 512
CONFIG_FILE = '/etc/qubes/storage.conf'
STORAGE_ENTRY_POINT = 'qubes.storage'
@ -353,89 +351,6 @@ def get_disk_usage(path):
return ret
def get_pool(name, vm):
""" Instantiates the storage for the specified vm """
config = _get_storage_config_parser()
klass = _get_pool_klass(name, config)
keys = [k for k in config.options(name) if k != 'driver' and k != 'class']
values = [config.get(name, o) for o in keys]
config_kwargs = dict(zip(keys, values))
if name == 'default':
kwargs = qubes.config.defaults['pool_config'].copy()
kwargs.update(keys)
else:
kwargs = config_kwargs
return klass(vm, **kwargs)
def pool_exists(name):
""" Check if the specified pool exists """
try:
_get_pool_klass(name)
return True
except StoragePoolException:
return False
def add_pool(name, **kwargs):
""" Add a storage pool to config."""
config = _get_storage_config_parser()
config.add_section(name)
for key, value in kwargs.iteritems():
config.set(name, key, value)
_write_config(config)
def remove_pool(name):
""" Remove a storage pool from config file. """
config = _get_storage_config_parser()
config.remove_section(name)
_write_config(config)
def _write_config(config):
with open(CONFIG_FILE, 'w') as configfile:
config.write(configfile)
def _get_storage_config_parser():
""" Instantiates a `ConfigParaser` for specified storage config file.
Returns:
RawConfigParser
"""
config = ConfigParser.RawConfigParser()
config.read(CONFIG_FILE)
return config
def _get_pool_klass(name, config=None):
""" Returns the storage klass for the specified pool.
Args:
name: The pool name.
config: If ``config`` is not specified
`_get_storage_config_parser()` is called.
Returns:
type: A class inheriting from `QubesVmStorage`
"""
if config is None:
config = _get_storage_config_parser()
if not config.has_section(name):
raise StoragePoolException('Uknown storage pool ' + name)
elif not config.has_option(name, 'driver'):
raise StoragePoolException('No driver specified for pool ' + name)
driver = config.get(name, 'driver')
try:
return qubes.get_entry_point_one(STORAGE_ENTRY_POINT, driver)
except KeyError:
raise StoragePoolException('Driver %s for pool %s' % (driver, name))
class Pool(object):
def __init__(self, vm, dir_path):
assert vm is not None

View File

@ -197,7 +197,6 @@ fi
%files
%defattr(-,root,root,-)
%config(noreplace) %attr(0664,root,qubes) %{_sysconfdir}/qubes/qmemman.conf
%config(noreplace) %attr(0664,root,qubes) %{_sysconfdir}/qubes/storage.conf
/usr/bin/qvm-*
/usr/bin/qubes-*
/usr/bin/qmemmand