Skip to content

Commit

Permalink
Make attach device return an AsyncTask
Browse files Browse the repository at this point in the history
Modified VMHostDevs class to be an AsyncCollection and return an AsyncTask when
creating a new resource (a.k.a. attach a device into a VM).

This patch is part of the solution for Kimchi Issue kimchi-project#817

Signed-off-by: Paulo Vital <pvital@linux.vnet.ibm.com>
  • Loading branch information
Paulo Vital authored and alinefm committed Apr 20, 2016
1 parent a1c4dd1 commit a6d74ae
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 19 deletions.
4 changes: 2 additions & 2 deletions control/vm/hostdevs.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

from wok.control.base import Collection, Resource
from wok.control.base import AsyncCollection, Resource
from wok.control.utils import UrlSubNode


Expand All @@ -33,7 +33,7 @@


@UrlSubNode("hostdevs")
class VMHostDevs(Collection):
class VMHostDevs(AsyncCollection):
def __init__(self, model, vmid):
super(VMHostDevs, self).__init__(model)
self.resource = VMHostDev
Expand Down
79 changes: 62 additions & 17 deletions model/vmhostdevs.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@

from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
from wok.exception import OperationFailed
from wok.model.tasks import TaskModel
from wok.rollbackcontext import RollbackContext
from wok.utils import run_command, wok_log
from wok.utils import add_task, run_command, wok_log

from wok.plugins.kimchi.model.config import CapabilitiesModel
from wok.plugins.kimchi.model.host import DeviceModel, DevicesModel
Expand All @@ -45,7 +46,9 @@
class VMHostDevsModel(object):
def __init__(self, **kargs):
self.conn = kargs['conn']
self.objstore = kargs['objstore']
self.caps = CapabilitiesModel(**kargs)
self.task = TaskModel(**kargs)

def get_list(self, vmid):
dom = VMModel.get_vm(vmid, self.conn)
Expand All @@ -70,7 +73,11 @@ def create(self, vmid, params):
dev_info = DeviceModel(conn=self.conn).lookup(dev_name)

if dev_info['device_type'] == 'pci':
return self._attach_pci_device(vmid, dev_info)
taskid = add_task(u'/plugins/kimchi/vms/%s/hostdevs/' %
VMModel.get_vm(vmid, self.conn).name(),
self._attach_pci_device, self.objstore,
{'vmid': vmid, 'dev_info': dev_info})
return self.task.lookup(taskid)

with RollbackContext() as rollback:
try:
Expand All @@ -81,13 +88,14 @@ def create(self, vmid, params):
else:
rollback.prependDefer(dev.reAttach)

attach_device = getattr(
self, '_attach_%s_device' % dev_info['device_type'])

info = attach_device(vmid, dev_info)
rollback.commitAll()

return info
taskid = add_task(u'/plugins/kimchi/vms/%s/hostdevs/' %
VMModel.get_vm(vmid, self.conn).name(),
'_attach_%s_device' % dev_info['device_type'],
self.objstore, {'vmid': vmid, 'dev_info': dev_info})

return self.task.lookup(taskid)

def _get_pci_device_xml(self, dev_info, slot, is_multifunction):
if 'detach_driver' not in dev_info:
Expand Down Expand Up @@ -162,7 +170,10 @@ def _available_slot(self, dom):

return free+1

def _attach_pci_device(self, vmid, dev_info):
def _attach_pci_device(self, cb, params):
cb('Attaching PCI device')
vmid = params['vmid']
dev_info = params['dev_info']
self._validate_pci_passthrough_env()

dom = VMModel.get_vm(vmid, self.conn)
Expand Down Expand Up @@ -227,10 +238,12 @@ def _attach_pci_device(self, vmid, dev_info):
with RollbackContext() as rollback:
for pci_info in pci_infos:
pci_info['detach_driver'] = driver
cb('Reading source device XML')
xmlstr = self._get_pci_device_xml(pci_info,
slot,
is_multifunction)
try:
cb('Attaching device to VM')
dom.attachDeviceFlags(xmlstr, device_flags)
except libvirt.libvirtError:
wok_log.error(
Expand All @@ -241,7 +254,7 @@ def _attach_pci_device(self, vmid, dev_info):
xmlstr, device_flags)
rollback.commitAll()

return dev_info['name']
cb('OK', True)

def _count_3D_devices_attached(self, dom):
counter = 0
Expand Down Expand Up @@ -348,11 +361,27 @@ def _get_scsi_device_xml(self, dev_info):
mode='subsystem', type='scsi', sgio='unfiltered')
return etree.tostring(host_dev)

def _attach_scsi_device(self, vmid, dev_info):
xmlstr = self._get_scsi_device_xml(dev_info)
def _attach_scsi_device(self, cb, params):
cb('Attaching SCSI device...')
vmid = params['vmid']
dev_info = params['dev_info']
dom = VMModel.get_vm(vmid, self.conn)
dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
return dev_info['name']

with RollbackContext() as rollback:
cb('Reading source device XML')
xmlstr = self._get_scsi_device_xml(dev_info)
device_flags = get_vm_config_flag(dom, mode='all')
try:
cb('Attaching device to VM')
dom.attachDeviceFlags(xmlstr, device_flags)
except libvirt.libvirtError:
wok_log.error('Failed to attach host device %s to VM %s: \n%s',
dev_info['name'], vmid, xmlstr)
raise
rollback.prependDefer(dom.detachDeviceFlags, xmlstr, device_flags)
rollback.commitAll()

cb('OK', True)

def _get_usb_device_xml(self, dev_info):
source = E.source(
Expand All @@ -365,11 +394,27 @@ def _get_usb_device_xml(self, dev_info):
ype='usb', managed='yes')
return etree.tostring(host_dev)

def _attach_usb_device(self, vmid, dev_info):
xmlstr = self._get_usb_device_xml(dev_info)
def _attach_usb_device(self, cb, params):
cb('Attaching USB device...')
vmid = params['vmid']
dev_info = params['dev_info']
dom = VMModel.get_vm(vmid, self.conn)
dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
return dev_info['name']

with RollbackContext() as rollback:
cb('Reading source device XML')
xmlstr = self._get_usb_device_xml(dev_info)
device_flags = get_vm_config_flag(dom, mode='all')
try:
cb('Attaching device to VM')
dom.attachDeviceFlags(xmlstr, device_flags)
except libvirt.libvirtError:
wok_log.error('Failed to attach host device %s to VM %s: \n%s',
dev_info['name'], vmid, xmlstr)
raise
rollback.prependDefer(dom.detachDeviceFlags, xmlstr, device_flags)
rollback.commitAll()

cb('OK', True)


class VMHostDevModel(object):
Expand Down

0 comments on commit a6d74ae

Please sign in to comment.