qubes/devices: devices class framework

This fixes loading PCI devices.
This commit is contained in:
Wojtek Porczyk 2016-03-17 13:06:13 +01:00
parent a4fa1adb82
commit 349e218638
3 changed files with 30 additions and 10 deletions

View File

@ -81,6 +81,18 @@ except ImportError:
pass pass
def get_entry_point_one(group, name):
epoints = tuple(pkg_resources.iter_entry_points(group, name))
if not epoints:
raise KeyError(name)
elif len(epoints) > 1:
raise TypeError(
'more than 1 implementation of {!r} found: {}'.format(name,
', '.join('{}.{}'.format(ep.module_name, '.'.join(ep.attrs))
for ep in epoints)))
return epoints[0].load()
class VMMConnection(object): class VMMConnection(object):
'''Connection to Virtual Machine Manager (libvirt)''' '''Connection to Virtual Machine Manager (libvirt)'''
@ -1401,18 +1413,13 @@ class Qubes(PropertyHolder):
:param str clsname: name of the class :param str clsname: name of the class
:return type: class :return type: class
''' '''
epoints = tuple(pkg_resources.iter_entry_points('qubes.vm', clsname))
if not epoints: try:
get_entry_point_one('qubes.vm', clsname)
except KeyError:
raise qubes.exc.QubesException( raise qubes.exc.QubesException(
'no such VM class: {!r}'.format(clsname)) 'no such VM class: {!r}'.format(clsname))
elif len(epoints) > 1: # don't catch TypeError
raise qubes.exc.QubesException(
'more than 1 implementation of {!r} found: {}'.format(
clsname,
', '.join(
'{}.{}'.format(ep.module_name, '.'.join(ep.attrs))
for ep in epoints)))
return epoints[0].load()
def add_new_vm(self, cls, qid=None, **kwargs): def add_new_vm(self, cls, qid=None, **kwargs):

View File

@ -24,6 +24,8 @@
import re import re
import qubes
class DeviceCollection(object): class DeviceCollection(object):
'''Bag for devices. '''Bag for devices.
@ -45,6 +47,14 @@ class DeviceCollection(object):
:param str device: device identifier (format is class-dependent) :param str device: device identifier (format is class-dependent)
''' '''
try:
devclass = qubes.get_entry_point_one('qubes.devices', self._class)
except KeyError:
devclass = str
if not isinstance(device, devclass):
device = devclass(device)
if device in self: if device in self:
raise KeyError( raise KeyError(
'device {!r} of class {} already attached to {!r}'.format( 'device {!r} of class {} already attached to {!r}'.format(

View File

@ -39,5 +39,8 @@ if __name__ == '__main__':
'qubes.ext.gui = qubes.ext.gui:GUI', 'qubes.ext.gui = qubes.ext.gui:GUI',
'qubes.ext.r3compatibility = qubes.ext.r3compatibility:R3Compatibility', 'qubes.ext.r3compatibility = qubes.ext.r3compatibility:R3Compatibility',
], ],
'qubes.devices': [
'pci = qubes.devices:PCIDevice',
],
} }
) )