Beispiel #1
0
 def get_control_rule_info(self, audit_info, name):
     try:
         msg_b = WokMessage("GINAUD0001M", None, "/plugins/ginger")
         text_b = msg_b.get_text(prepend_code=False, translate=True)
         msg_e = WokMessage("GINAUD0002M", None, "/plugins/ginger")
         text_e = msg_e.get_text(prepend_code=False, translate=True)
         msg_f = WokMessage("GINAUD0003M", None, "/plugins/ginger")
         text_f = msg_f.get_text(prepend_code=False, translate=True)
         msg_r = WokMessage("GINAUD0004M", None, "/plugins/ginger")
         text_r = msg_r.get_text(prepend_code=False, translate=True)
         msg_D = WokMessage("GINAUD0005M", None, "/plugins/ginger")
         text_D = msg_D.get_text(prepend_code=False, translate=True)
         control_rules_dict = {'-b': text_b,
                               '-e': text_e,
                               '-f': text_f,
                               '-r': text_r,
                               '-D': text_D}
         control_info = dict()
         control_info['rule_info'] = {}
         if name.split(" ")[0] != "-D":
             control_info['rule_info']['conf_value'] = name.split(" ")[1]
         control_info['rule_info']['conf_option'] = \
             name.split(" ")[0] + ": " + \
             control_rules_dict[name.split(" ")[0]]
         audit_info.update(control_info)
     except Exception, e:
         raise OperationFailed("GINAUD0007E", {"error": e.message})
Beispiel #2
0
 def get_control_rule_info(self, audit_info, name):
     try:
         msg_b = WokMessage("GINAUD0001M", None, "/plugins/ginger")
         text_b = msg_b.get_text(prepend_code=False, translate=True)
         msg_e = WokMessage("GINAUD0002M", None, "/plugins/ginger")
         text_e = msg_e.get_text(prepend_code=False, translate=True)
         msg_f = WokMessage("GINAUD0003M", None, "/plugins/ginger")
         text_f = msg_f.get_text(prepend_code=False, translate=True)
         msg_r = WokMessage("GINAUD0004M", None, "/plugins/ginger")
         text_r = msg_r.get_text(prepend_code=False, translate=True)
         msg_D = WokMessage("GINAUD0005M", None, "/plugins/ginger")
         text_D = msg_D.get_text(prepend_code=False, translate=True)
         control_rules_dict = {'-b': text_b,
                               '-e': text_e,
                               '-f': text_f,
                               '-r': text_r,
                               '-D': text_D}
         control_info = dict()
         control_info['rule_info'] = {}
         if name.split(" ")[0] != "-D":
             control_info['rule_info']['conf_value'] = name.split(" ")[1]
         control_info['rule_info']['conf_option'] = \
             name.split(" ")[0] + ": " + \
             control_rules_dict[name.split(" ")[0]]
         audit_info.update(control_info)
     except Exception as e:
         raise OperationFailed("GINAUD0007E", {"error": e.message})
Beispiel #3
0
    def getTranslatedMessage(self, message, error, app_root):
        code = message.get('code', '')
        params = message.get('params', {})
        msg = WokMessage(code, params, app_root)
        text = msg.get_text(prepend_code=False, translate=True)

        if error:
            code = error.get('code', '')
            params = error.get('params', {})
            msg = WokMessage(code, params, app_root)
            text += ' (%s)' % msg.get_text(prepend_code=True, translate=True)

        return text
Beispiel #4
0
    def getTranslatedMessage(self, message, error, app_root):
        code = message.get('code', '')
        params = message.get('params', {})
        msg = WokMessage(code, params, app_root)
        text = msg.get_text(prepend_code=False, translate=True)

        if error:
            code = error.get('code', '')
            params = error.get('params', {})
            msg = WokMessage(code, params, app_root)
            text += ' (%s)' % msg.get_text(prepend_code=True, translate=True)

        return text
Beispiel #5
0
    def _detach_device(self, cb, params):
        cb('Detaching device')
        self._cb = cb
        vmid = params['vmid']
        dev_name = params['dev_name']
        dom = params['dom']
        hostdev = params['hostdev']
        lock = params['lock']

        with lock:
            pci_devs = [(DeviceModel.deduce_dev_name(e, self.conn), e)
                        for e in hostdev if e.attrib['type'] == 'pci']

            dev_info = self.dev_model.lookup(dev_name)
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != "shutoff":
                raise InvalidOperation('KCHVMHDEV0006E',
                                       {'name': dev_info['name']})

            # check for multifunction and detach all functions together
            try:
                multi = self._unplug_multifunction_pci(dom, hostdev, dev_name)
            except libvirt.libvirtError:
                multi = False

            # successfully detached all functions: finish operation
            if multi:
                if is_3D_device:
                    devsmodel = VMHostDevsModel(conn=self.conn)
                    devsmodel.update_mmio_guest(vmid, False)

                if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
                    cb('OK', True)
                return

            # detach each function individually
            for e in hostdev:
                if DeviceModel.deduce_dev_name(e, self.conn) == dev_name:
                    xmlstr = etree.tostring(e)
                    dom.detachDeviceFlags(
                        xmlstr, get_vm_config_flag(dom, mode='all'))
                    if e.attrib['type'] == 'pci':
                        self._delete_affected_pci_devices(dom, dev_name,
                                                          pci_devs)
                    if is_3D_device:
                        devsmodel = VMHostDevsModel(conn=self.conn)
                        devsmodel.update_mmio_guest(vmid, False)
                    break
            else:
                msg = WokMessage('KCHVMHDEV0001E',
                                 {'vmid': vmid, 'dev_name': dev_name})
                cb(msg.get_text(), False)
                raise NotFoundError('KCHVMHDEV0001E',
                                    {'vmid': vmid, 'dev_name': dev_name})

        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
            cb('OK', True)
Beispiel #6
0
 def event_enospc_cb(self, conn, dom, path, dev, action, reason, args):
     if reason == "enospc":
         info = {
             "vm": dom.name(),
             "srcPath": path,
             "devAlias": dev,
         }
         add_notification("KCHEVENT0004W", info, '/plugins/kimchi')
         msg = WokMessage("KCHEVENT0004W", info, '/plugins/kimchi')
         wok_log.warning(msg.get_text())
Beispiel #7
0
    def _attach_multifunction_devices(self, dom, pci_infos, driver, vmid):
        slot = 0
        is_multifunction = len(pci_infos) > 1
        device_flags = get_vm_config_flag(dom, mode='all')
        with RollbackContext() as rollback:
            # multifuction: try to attach all functions together within one
            # xml file. It requires libvirt support.
            if is_multifunction:
                # search for the first available slot in guest xml
                slot = self._available_slot(dom)
                xmlstr = self._get_pci_devices_xml(pci_infos, slot, driver)

                try:
                    dom.attachDeviceFlags(xmlstr, device_flags)

                except libvirt.libvirtError:
                    # If operation fails, we try the other way, where each
                    # function is attached individually
                    pass
                else:
                    rollback.prependDefer(
                        dom.detachDeviceFlags, xmlstr, device_flags
                    )
                    rollback.commitAll()
                    if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
                        self._cb('OK', True)
                    return

            # attach each function individually (multi or single function)
            for pci_info in pci_infos:
                pci_info['detach_driver'] = driver
                xmlstr = self._get_pci_device_xml(
                    pci_info, slot, is_multifunction)
                try:
                    dom.attachDeviceFlags(xmlstr, device_flags)

                except libvirt.libvirtError:
                    msg = WokMessage(
                        'KCHVMHDEV0007E', {
                            'device': pci_info['name'], 'vm': vmid}
                    )
                    self._cb(msg.get_text(), False)
                    wok_log.error(
                        'Failed to attach host device %s to VM %s: \n%s',
                        pci_info['name'],
                        vmid,
                        xmlstr,
                    )
                    raise

                rollback.prependDefer(
                    dom.detachDeviceFlags, xmlstr, device_flags)

            rollback.commitAll()
Beispiel #8
0
    def _attach_multifunction_devices(self, dom, pci_infos, driver, vmid):
        slot = 0
        is_multifunction = len(pci_infos) > 1
        device_flags = get_vm_config_flag(dom, mode='all')
        with RollbackContext() as rollback:
            # multifuction: try to attach all functions together within one
            # xml file. It requires libvirt support.
            if is_multifunction:
                # search for the first available slot in guest xml
                slot = self._available_slot(dom)
                xmlstr = self._get_pci_devices_xml(pci_infos, slot, driver)

                try:
                    dom.attachDeviceFlags(xmlstr, device_flags)

                except libvirt.libvirtError:
                    # If operation fails, we try the other way, where each
                    # function is attached individually
                    pass
                else:
                    rollback.prependDefer(
                        dom.detachDeviceFlags, xmlstr, device_flags
                    )
                    rollback.commitAll()
                    if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
                        self._cb('OK', True)
                    return

            # attach each function individually (multi or single function)
            for pci_info in pci_infos:
                pci_info['detach_driver'] = driver
                xmlstr = self._get_pci_device_xml(
                    pci_info, slot, is_multifunction)
                try:
                    dom.attachDeviceFlags(xmlstr, device_flags)

                except libvirt.libvirtError:
                    msg = WokMessage(
                        'KCHVMHDEV0007E', {
                            'device': pci_info['name'], 'vm': vmid}
                    )
                    self._cb(msg.get_text(), False)
                    wok_log.error(
                        'Failed to attach host device %s to VM %s: \n%s',
                        pci_info['name'],
                        vmid,
                        xmlstr,
                    )
                    raise

                rollback.prependDefer(
                    dom.detachDeviceFlags, xmlstr, device_flags)

            rollback.commitAll()
Beispiel #9
0
    def _detach_device(self, cb, params):
        cb('Detaching device')
        self._cb = cb
        vmid = params['vmid']
        dev_name = params['dev_name']
        dom = params['dom']
        hostdev = params['hostdev']
        lock = params['lock']

        with lock:
            pci_devs = [(DeviceModel.deduce_dev_name(e, self.conn), e)
                        for e in hostdev if e.attrib['type'] == 'pci']

            dev_info = self.dev_model.lookup(dev_name)
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != "shutoff":
                raise InvalidOperation('KCHVMHDEV0006E',
                                       {'name': dev_info['name']})

            if self._hotunplug_multifunction_pci(dom, hostdev, dev_name):
                if is_3D_device:
                    devsmodel = VMHostDevsModel(conn=self.conn)
                    devsmodel.update_mmio_guest(vmid, False)

                if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
                    cb('OK', True)
                return

            for e in hostdev:
                if DeviceModel.deduce_dev_name(e, self.conn) == dev_name:
                    xmlstr = etree.tostring(e)
                    dom.detachDeviceFlags(xmlstr,
                                          get_vm_config_flag(dom, mode='all'))
                    if e.attrib['type'] == 'pci':
                        self._delete_affected_pci_devices(
                            dom, dev_name, pci_devs)
                    if is_3D_device:
                        devsmodel = VMHostDevsModel(conn=self.conn)
                        devsmodel.update_mmio_guest(vmid, False)
                    break
            else:
                msg = WokMessage('KCHVMHDEV0001E', {
                    'vmid': vmid,
                    'dev_name': dev_name
                })
                cb(msg.get_text(), False)
                raise NotFoundError('KCHVMHDEV0001E', {
                    'vmid': vmid,
                    'dev_name': dev_name
                })

        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
            cb('OK', True)
Beispiel #10
0
    def _attach_all_devices(self, pci_infos):
        with RollbackContext() as rollback:
            for pci_info in pci_infos:
                try:
                    dev = self.conn.get().nodeDeviceLookupByName(
                        pci_info['name'])
                    dev.dettach()
                except Exception:
                    msg = WokMessage('KCHVMHDEV0005E',
                                     {'name': pci_info['name']})
                    self._cb(msg.get_text(), False)
                    raise OperationFailed('KCHVMHDEV0005E',
                                          {'name': pci_info['name']})
                else:
                    rollback.prependDefer(dev.reAttach)

            rollback.commitAll()
Beispiel #11
0
    def _attach_all_devices(self, pci_infos):
        with RollbackContext() as rollback:
            for pci_info in pci_infos:
                try:
                    dev = self.conn.get().nodeDeviceLookupByName(
                        pci_info['name'])
                    dev.dettach()
                except Exception:
                    msg = WokMessage('KCHVMHDEV0005E', {
                        'name': pci_info['name']})
                    self._cb(msg.get_text(), False)
                    raise OperationFailed(
                        'KCHVMHDEV0005E', {'name': pci_info['name']}
                    )
                else:
                    rollback.prependDefer(dev.reAttach)

            rollback.commitAll()
Beispiel #12
0
    def _attach_scsi_device(self, cb, params):
        cb('Attaching SCSI device...')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])

        except InvalidParameter as e:
            cb(str(e), False)
            raise

        with lock:
            dom = VMModel.get_vm(vmid, self.conn)

            with RollbackContext() as rollback:
                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:
                    msg = WokMessage(
                        'KCHVMHDEV0007E', {
                            'device': dev_info['name'], 'vm': vmid}
                    )
                    cb(msg.get_text(), False)
                    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()

        if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
            cb('OK', True)
Beispiel #13
0
    def _attach_scsi_device(self, cb, params):
        cb('Attaching SCSI device...')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])

        except InvalidParameter as e:
            cb(str(e), False)
            raise

        with lock:
            dom = VMModel.get_vm(vmid, self.conn)

            with RollbackContext() as rollback:
                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:
                    msg = WokMessage(
                        'KCHVMHDEV0007E', {
                            'device': dev_info['name'], 'vm': vmid}
                    )
                    cb(msg.get_text(), False)
                    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()

        if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
            cb('OK', True)
Beispiel #14
0
    def _attach_pci_device(self, cb, params):
        cb('Attaching PCI device')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])

        except InvalidParameter as e:
            cb(e.message, False)
            raise

        with lock:
            try:
                self._validate_pci_passthrough_env()

            except InvalidOperation as e:
                cb(e.message, False)
                raise

            dom = VMModel.get_vm(vmid, self.conn)
            driver = 'vfio' if self.caps.kernel_vfio else 'kvm'

            # 'vfio' systems requires a usb controller in order to support pci
            # hotplug on Power.
            if driver == 'vfio' and platform.machine().startswith('ppc') and \
               DOM_STATE_MAP[dom.info()[0]] != "shutoff" and \
               not self.have_usb_controller(vmid):
                msg = WokMessage('KCHVMHDEV0008E', {'vmid': vmid})
                cb(msg.get_text(), False)
                raise InvalidOperation("KCHVMHDEV0008E", {'vmid': vmid})

            # Attach all PCI devices in the same IOMMU group
            affected_names = self.devs_model.get_list(
                _passthrough_affected_by=dev_info['name'])
            passthrough_names = self.devs_model.get_list(
                _cap='pci', _passthrough='true')
            group_names = list(set(affected_names) & set(passthrough_names))
            pci_infos = [self.dev_model.lookup(dev_name) for dev_name in
                         group_names]
            pci_infos.append(dev_info)

            is_multifunction = len(pci_infos) > 1
            pci_infos = sorted(pci_infos, key=itemgetter('name'))

            # does not allow hot-plug of 3D graphic cards
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != "shutoff":
                msg = WokMessage('KCHVMHDEV0006E', {'name': dev_info['name']})
                cb(msg.get_text(), False)
                raise InvalidOperation('KCHVMHDEV0006E',
                                       {'name': dev_info['name']})

            # all devices in the group that is going to be attached to the vm
            # must be detached from the host first
            with RollbackContext() as rollback:
                for pci_info in pci_infos:
                    try:
                        dev = self.conn.get().nodeDeviceLookupByName(
                            pci_info['name'])
                        dev.dettach()
                    except Exception:
                        msg = WokMessage('KCHVMHDEV0005E',
                                         {'name': pci_info['name']})
                        cb(msg.get_text(), False)
                        raise OperationFailed('KCHVMHDEV0005E',
                                              {'name': pci_info['name']})
                    else:
                        rollback.prependDefer(dev.reAttach)

                rollback.commitAll()

            device_flags = get_vm_config_flag(dom, mode='all')

            # when attaching a 3D graphic device it might be necessary to
            # increase the window size memory in order to be able to attach
            # more than one device to the same guest
            if is_3D_device:
                self.update_mmio_guest(vmid, True)

            slot = 0
            if is_multifunction:
                # search for the first available slot in guest xml
                slot = self._available_slot(dom)

            with RollbackContext() as rollback:
                # multifuction: try to attach all functions together within one
                # xml file. It requires libvirt support.
                if is_multifunction:
                    xmlstr = self._get_pci_devices_xml(pci_infos, slot, driver)

                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        # If operation fails, we try the other way, where each
                        # function is attached individually
                        pass
                    else:
                        rollback.prependDefer(dom.detachDeviceFlags, xmlstr,
                                              device_flags)
                        rollback.commitAll()
                        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
                            cb('OK', True)
                        return

                # attach each function individually (multi or single function)
                for pci_info in pci_infos:
                    pci_info['detach_driver'] = driver
                    xmlstr = self._get_pci_device_xml(pci_info,
                                                      slot,
                                                      is_multifunction)
                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        msg = WokMessage('KCHVMHDEV0007E',
                                         {'device': pci_info['name'],
                                          'vm': vmid})
                        cb(msg.get_text(), False)
                        wok_log.error(
                            'Failed to attach host device %s to VM %s: \n%s',
                            pci_info['name'], vmid, xmlstr)
                        raise

                    rollback.prependDefer(dom.detachDeviceFlags,
                                          xmlstr, device_flags)

                rollback.commitAll()

        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
            cb('OK', True)
Beispiel #15
0
 def event_enospc_cb(self, conn, dom, path, dev, action, reason, args):
     if reason == 'enospc':
         info = {'vm': dom.name(), 'srcPath': path, 'devAlias': dev}
         add_notification('KCHEVENT0004W', info, '/plugins/kimchi')
         msg = WokMessage('KCHEVENT0004W', info, '/plugins/kimchi')
         wok_log.warning(msg.get_text())
Beispiel #16
0
    def _attach_pci_device(self, cb, params):
        cb('Attaching PCI device')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])

        except InvalidParameter as e:
            cb(e.message, False)
            raise

        with lock:
            try:
                self._validate_pci_passthrough_env()

            except InvalidOperation as e:
                cb(e.message, False)
                raise

            dom = VMModel.get_vm(vmid, self.conn)
            # Due to libvirt limitation, we don't support live assigne device
            # to vfio driver.
            driver = ('vfio' if DOM_STATE_MAP[dom.info()[0]] == "shutoff" and
                      self.caps.kernel_vfio else 'kvm')

            # on powerkvm systems it must be vfio driver.
            distro, _, _ = platform.linux_distribution()
            if distro == 'IBM_PowerKVM':
                driver = 'vfio'

            # Attach all PCI devices in the same IOMMU group
            affected_names = self.devs_model.get_list(
                _passthrough_affected_by=dev_info['name'])
            passthrough_names = self.devs_model.get_list(
                _cap='pci', _passthrough='true')
            group_names = list(set(affected_names) & set(passthrough_names))
            pci_infos = [self.dev_model.lookup(dev_name) for dev_name in
                         group_names]
            pci_infos.append(dev_info)

            is_multifunction = len(pci_infos) > 1
            pci_infos = sorted(pci_infos, key=itemgetter('name'))

            # does not allow hot-plug of 3D graphic cards
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != "shutoff":
                msg = WokMessage('KCHVMHDEV0006E', {'name': dev_info['name']})
                cb(msg.get_text(), False)
                raise InvalidOperation('KCHVMHDEV0006E',
                                       {'name': dev_info['name']})

            # all devices in the group that is going to be attached to the vm
            # must be detached from the host first
            with RollbackContext() as rollback:
                for pci_info in pci_infos:
                    try:
                        dev = self.conn.get().nodeDeviceLookupByName(
                            pci_info['name'])
                        dev.dettach()
                    except Exception:
                        msg = WokMessage('KCHVMHDEV0005E',
                                         {'name': pci_info['name']})
                        cb(msg.get_text(), False)
                        raise OperationFailed('KCHVMHDEV0005E',
                                              {'name': pci_info['name']})
                    else:
                        rollback.prependDefer(dev.reAttach)

                rollback.commitAll()

            device_flags = get_vm_config_flag(dom, mode='all')

            # when attaching a 3D graphic device it might be necessary to
            # increase the window size memory in order to be able to attach
            # more than one device to the same guest
            if is_3D_device:
                self.update_mmio_guest(vmid, True)

            slot = 0
            if is_multifunction:
                # search for the first available slot in guest xml
                slot = self._available_slot(dom)

            with RollbackContext() as rollback:
                # multifunction hotplug is a special case where all functions
                # must be attached together within one xml file, the same does
                # not happen to multifunction coldplug - where each function
                # is attached individually
                if DOM_STATE_MAP[dom.info()[0]] != 'shutoff' and \
                   is_multifunction:
                    xmlstr = self._get_pci_devices_xml(pci_infos, slot, driver)

                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        msg = WokMessage('KCHVMHDEV0007E',
                                         {'device': pci_info['name'],
                                          'vm': vmid})
                        cb(msg.get_text(), False)
                        wok_log.error(
                            'Failed to attach mutifunction device VM %s: \n%s',
                            vmid, xmlstr)
                        raise

                    rollback.prependDefer(dom.detachDeviceFlags, xmlstr,
                                          device_flags)
                    rollback.commitAll()
                    if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
                        cb('OK', True)
                    return

                for pci_info in pci_infos:
                    pci_info['detach_driver'] = driver
                    xmlstr = self._get_pci_device_xml(pci_info,
                                                      slot,
                                                      is_multifunction)
                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        msg = WokMessage('KCHVMHDEV0007E',
                                         {'device': pci_info['name'],
                                          'vm': vmid})
                        cb(msg.get_text(), False)
                        wok_log.error(
                            'Failed to attach host device %s to VM %s: \n%s',
                            pci_info['name'], vmid, xmlstr)
                        raise

                    rollback.prependDefer(dom.detachDeviceFlags,
                                          xmlstr, device_flags)

                rollback.commitAll()

        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
            cb('OK', True)
Beispiel #17
0
                      'PUT': self.update}[method](*args, **kargs)

            status = cherrypy.response.status
        except WokException, e:
            status = e.getHttpStatusCode()
            raise cherrypy.HTTPError(status, e.message)
        except cherrypy.HTTPError, e:
            status = e.status
            raise
        finally:
            # log request
            if method not in LOG_DISABLED_METHODS:
                code = self.getRequestMessage(method)
                msg = WokMessage(code, self.log_args)
                RequestRecord(
                    msg.get_text(prepend_code=False),
                    app=get_plugin_from_request(),
                    req=method,
                    status=status,
                    user=cherrypy.session.get(USER_NAME, 'N/A'),
                    ip=cherrypy.request.remote.ip
                ).log()

        return result

    def is_authorized(self):
        user_name = cherrypy.session.get(USER_NAME, '')
        user_groups = cherrypy.session.get(USER_GROUPS, [])
        user_role = cherrypy.session.get(USER_ROLES, {}).get(self.role_key)

        users = self.data.get("users", None)
Beispiel #18
0
    def _attach_pci_device(self, cb, params):
        cb('Attaching PCI device')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])
        except InvalidParameter as e:
            cb(str(e), False)
            raise

        with lock:
            try:
                self._validate_pci_passthrough_env()

            except InvalidOperation as e:
                cb(str(e), False)
                raise

            dom = VMModel.get_vm(vmid, self.conn)
            driver = 'vfio' if self.caps.kernel_vfio else 'kvm'

            # 'vfio' systems requires a usb controller in order to support pci
            # hotplug on Power.
            if (
                driver == 'vfio' and
                platform.machine().startswith('ppc') and
                DOM_STATE_MAP[dom.info()[0]] != 'shutoff' and
                not self.have_usb_controller(vmid)
            ):
                msg = WokMessage('KCHVMHDEV0008E', {'vmid': vmid})
                cb(msg.get_text(), False)
                raise InvalidOperation('KCHVMHDEV0008E', {'vmid': vmid})

            # Attach all PCI devices in the same IOMMU group
            affected_names = self.devs_model.get_list(
                _passthrough_affected_by=dev_info['name']
            )
            passthrough_names = self.devs_model.get_list(
                _cap='pci', _passthrough='true'
            )
            group_names = list(set(affected_names) & set(passthrough_names))
            pci_infos = [self.dev_model.lookup(
                dev_name) for dev_name in group_names]
            pci_infos.append(dev_info)
            pci_infos = sorted(pci_infos, key=itemgetter('name'))

            # does not allow hot-plug of 3D graphic cards
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != 'shutoff':
                msg = WokMessage('KCHVMHDEV0006E', {'name': dev_info['name']})
                cb(msg.get_text(), False)
                raise InvalidOperation(
                    'KCHVMHDEV0006E', {'name': dev_info['name']})

            # all devices in the group that is going to be attached to the vm
            # must be detached from the host first
            self._attach_all_devices(pci_infos)

            # when attaching a 3D graphic device it might be necessary to
            # increase the window size memory in order to be able to attach
            # more than one device to the same guest
            if is_3D_device:
                self.update_mmio_guest(vmid, True)

            self._attach_multifunction_devices(dom, pci_infos, driver, vmid)

        if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
            cb('OK', True)
Beispiel #19
0
    def _attach_pci_device(self, cb, params):
        cb('Attaching PCI device')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])

        except InvalidParameter as e:
            cb(e.message, False)
            raise

        with lock:
            try:
                self._validate_pci_passthrough_env()

            except InvalidOperation as e:
                cb(e.message, False)
                raise

            dom = VMModel.get_vm(vmid, self.conn)
            driver = 'vfio' if self.caps.kernel_vfio else 'kvm'

            # 'vfio' systems requires a usb controller in order to support pci
            # hotplug on Power.
            if driver == 'vfio' and platform.machine().startswith('ppc') and \
               DOM_STATE_MAP[dom.info()[0]] != "shutoff" and \
               not self.have_usb_controller(vmid):
                msg = WokMessage('KCHVMHDEV0008E', {'vmid': vmid})
                cb(msg.get_text(), False)
                raise InvalidOperation("KCHVMHDEV0008E", {'vmid': vmid})

            # Attach all PCI devices in the same IOMMU group
            affected_names = self.devs_model.get_list(
                _passthrough_affected_by=dev_info['name'])
            passthrough_names = self.devs_model.get_list(_cap='pci',
                                                         _passthrough='true')
            group_names = list(set(affected_names) & set(passthrough_names))
            pci_infos = [
                self.dev_model.lookup(dev_name) for dev_name in group_names
            ]
            pci_infos.append(dev_info)

            is_multifunction = len(pci_infos) > 1
            pci_infos = sorted(pci_infos, key=itemgetter('name'))

            # does not allow hot-plug of 3D graphic cards
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != "shutoff":
                msg = WokMessage('KCHVMHDEV0006E', {'name': dev_info['name']})
                cb(msg.get_text(), False)
                raise InvalidOperation('KCHVMHDEV0006E',
                                       {'name': dev_info['name']})

            # all devices in the group that is going to be attached to the vm
            # must be detached from the host first
            with RollbackContext() as rollback:
                for pci_info in pci_infos:
                    try:
                        dev = self.conn.get().nodeDeviceLookupByName(
                            pci_info['name'])
                        dev.dettach()
                    except Exception:
                        msg = WokMessage('KCHVMHDEV0005E',
                                         {'name': pci_info['name']})
                        cb(msg.get_text(), False)
                        raise OperationFailed('KCHVMHDEV0005E',
                                              {'name': pci_info['name']})
                    else:
                        rollback.prependDefer(dev.reAttach)

                rollback.commitAll()

            device_flags = get_vm_config_flag(dom, mode='all')

            # when attaching a 3D graphic device it might be necessary to
            # increase the window size memory in order to be able to attach
            # more than one device to the same guest
            if is_3D_device:
                self.update_mmio_guest(vmid, True)

            slot = 0
            if is_multifunction:
                # search for the first available slot in guest xml
                slot = self._available_slot(dom)

            with RollbackContext() as rollback:
                # multifuction: try to attach all functions together within one
                # xml file. It requires libvirt support.
                if is_multifunction:
                    xmlstr = self._get_pci_devices_xml(pci_infos, slot, driver)

                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        # If operation fails, we try the other way, where each
                        # function is attached individually
                        pass
                    else:
                        rollback.prependDefer(dom.detachDeviceFlags, xmlstr,
                                              device_flags)
                        rollback.commitAll()
                        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
                            cb('OK', True)
                        return

                # attach each function individually (multi or single function)
                for pci_info in pci_infos:
                    pci_info['detach_driver'] = driver
                    xmlstr = self._get_pci_device_xml(pci_info, slot,
                                                      is_multifunction)
                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        msg = WokMessage('KCHVMHDEV0007E', {
                            'device': pci_info['name'],
                            'vm': vmid
                        })
                        cb(msg.get_text(), False)
                        wok_log.error(
                            'Failed to attach host device %s to VM %s: \n%s',
                            pci_info['name'], vmid, xmlstr)
                        raise

                    rollback.prependDefer(dom.detachDeviceFlags, xmlstr,
                                          device_flags)

                rollback.commitAll()

        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
            cb('OK', True)
Beispiel #20
0
 def event_enospc_cb(self, conn, dom, path, dev, action, reason, args):
     if reason == 'enospc':
         info = {'vm': dom.name(), 'srcPath': path, 'devAlias': dev}
         add_notification('KCHEVENT0004W', info, '/plugins/kimchi')
         msg = WokMessage('KCHEVENT0004W', info, '/plugins/kimchi')
         wok_log.warning(msg.get_text())
Beispiel #21
0
    def _attach_pci_device(self, cb, params):
        cb('Attaching PCI device')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])

        except InvalidParameter as e:
            cb(e.message, False)
            raise

        with lock:
            try:
                self._validate_pci_passthrough_env()

            except InvalidOperation as e:
                cb(e.message, False)
                raise

            dom = VMModel.get_vm(vmid, self.conn)
            # Due to libvirt limitation, we don't support live assigne device
            # to vfio driver.
            driver = ('vfio' if DOM_STATE_MAP[dom.info()[0]] == "shutoff"
                      and self.caps.kernel_vfio else 'kvm')

            # on powerkvm systems it must be vfio driver.
            distro, _, _ = platform.linux_distribution()
            if distro == 'IBM_PowerKVM':
                driver = 'vfio'

            # Attach all PCI devices in the same IOMMU group
            affected_names = self.devs_model.get_list(
                _passthrough_affected_by=dev_info['name'])
            passthrough_names = self.devs_model.get_list(_cap='pci',
                                                         _passthrough='true')
            group_names = list(set(affected_names) & set(passthrough_names))
            pci_infos = [
                self.dev_model.lookup(dev_name) for dev_name in group_names
            ]
            pci_infos.append(dev_info)

            is_multifunction = len(pci_infos) > 1
            pci_infos = sorted(pci_infos, key=itemgetter('name'))

            # does not allow hot-plug of 3D graphic cards
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != "shutoff":
                msg = WokMessage('KCHVMHDEV0006E', {'name': dev_info['name']})
                cb(msg.get_text(), False)
                raise InvalidOperation('KCHVMHDEV0006E',
                                       {'name': dev_info['name']})

            # all devices in the group that is going to be attached to the vm
            # must be detached from the host first
            with RollbackContext() as rollback:
                for pci_info in pci_infos:
                    try:
                        dev = self.conn.get().nodeDeviceLookupByName(
                            pci_info['name'])
                        dev.dettach()
                    except Exception:
                        msg = WokMessage('KCHVMHDEV0005E',
                                         {'name': pci_info['name']})
                        cb(msg.get_text(), False)
                        raise OperationFailed('KCHVMHDEV0005E',
                                              {'name': pci_info['name']})
                    else:
                        rollback.prependDefer(dev.reAttach)

                rollback.commitAll()

            device_flags = get_vm_config_flag(dom, mode='all')

            # when attaching a 3D graphic device it might be necessary to
            # increase the window size memory in order to be able to attach
            # more than one device to the same guest
            if is_3D_device:
                self.update_mmio_guest(vmid, True)

            slot = 0
            if is_multifunction:
                # search for the first available slot in guest xml
                slot = self._available_slot(dom)

            with RollbackContext() as rollback:
                # multifunction hotplug is a special case where all functions
                # must be attached together within one xml file, the same does
                # not happen to multifunction coldplug - where each function
                # is attached individually
                if DOM_STATE_MAP[dom.info()[0]] != 'shutoff' and \
                   is_multifunction:
                    xmlstr = self._get_pci_devices_xml(pci_infos, slot, driver)

                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        msg = WokMessage('KCHVMHDEV0007E', {
                            'device': pci_info['name'],
                            'vm': vmid
                        })
                        cb(msg.get_text(), False)
                        wok_log.error(
                            'Failed to attach mutifunction device VM %s: \n%s',
                            vmid, xmlstr)
                        raise

                    rollback.prependDefer(dom.detachDeviceFlags, xmlstr,
                                          device_flags)
                    rollback.commitAll()
                    if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
                        cb('OK', True)
                    return

                for pci_info in pci_infos:
                    pci_info['detach_driver'] = driver
                    xmlstr = self._get_pci_device_xml(pci_info, slot,
                                                      is_multifunction)
                    try:
                        dom.attachDeviceFlags(xmlstr, device_flags)

                    except libvirt.libvirtError:
                        msg = WokMessage('KCHVMHDEV0007E', {
                            'device': pci_info['name'],
                            'vm': vmid
                        })
                        cb(msg.get_text(), False)
                        wok_log.error(
                            'Failed to attach host device %s to VM %s: \n%s',
                            pci_info['name'], vmid, xmlstr)
                        raise

                    rollback.prependDefer(dom.detachDeviceFlags, xmlstr,
                                          device_flags)

                rollback.commitAll()

        if DOM_STATE_MAP[dom.info()[0]] == "shutoff":
            cb('OK', True)
Beispiel #22
0
    def _attach_pci_device(self, cb, params):
        cb('Attaching PCI device')
        self._cb = cb
        vmid = params['vmid']
        dev_info = params['dev_info']
        lock = params['lock']

        try:
            self._passthrough_device_validate(dev_info['name'])
        except InvalidParameter as e:
            cb(str(e), False)
            raise

        with lock:
            try:
                self._validate_pci_passthrough_env()

            except InvalidOperation as e:
                cb(str(e), False)
                raise

            dom = VMModel.get_vm(vmid, self.conn)
            driver = 'vfio' if self.caps.kernel_vfio else 'kvm'

            # 'vfio' systems requires a usb controller in order to support pci
            # hotplug on Power.
            if (
                driver == 'vfio' and
                platform.machine().startswith('ppc') and
                DOM_STATE_MAP[dom.info()[0]] != 'shutoff' and
                not self.have_usb_controller(vmid)
            ):
                msg = WokMessage('KCHVMHDEV0008E', {'vmid': vmid})
                cb(msg.get_text(), False)
                raise InvalidOperation('KCHVMHDEV0008E', {'vmid': vmid})

            # Attach all PCI devices in the same IOMMU group
            affected_names = self.devs_model.get_list(
                _passthrough_affected_by=dev_info['name']
            )
            passthrough_names = self.devs_model.get_list(
                _cap='pci', _passthrough='true'
            )
            group_names = list(set(affected_names) & set(passthrough_names))
            pci_infos = [self.dev_model.lookup(
                dev_name) for dev_name in group_names]
            pci_infos.append(dev_info)
            pci_infos = sorted(pci_infos, key=itemgetter('name'))

            # does not allow hot-plug of 3D graphic cards
            is_3D_device = self.dev_model.is_device_3D_controller(dev_info)
            if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != 'shutoff':
                msg = WokMessage('KCHVMHDEV0006E', {'name': dev_info['name']})
                cb(msg.get_text(), False)
                raise InvalidOperation(
                    'KCHVMHDEV0006E', {'name': dev_info['name']})

            # all devices in the group that is going to be attached to the vm
            # must be detached from the host first
            self._attach_all_devices(pci_infos)

            # when attaching a 3D graphic device it might be necessary to
            # increase the window size memory in order to be able to attach
            # more than one device to the same guest
            if is_3D_device:
                self.update_mmio_guest(vmid, True)

            self._attach_multifunction_devices(dom, pci_infos, driver, vmid)

        if DOM_STATE_MAP[dom.info()[0]] == 'shutoff':
            cb('OK', True)