def get_base_config(self, instance, vif, image_meta, inst_type, virt_type): conf = vconfig.LibvirtConfigGuestInterface() # Default to letting libvirt / the hypervisor choose the model model = None driver = None vhost_queues = None # If the user has specified a 'vif_model' against the # image then honour that model if image_meta: model = osinfo.HardwareProperties(image_meta).network_model # Else if the virt type is KVM/QEMU, use virtio according # to the global config parameter if (model is None and virt_type in ('kvm', 'qemu') and CONF.libvirt.use_virtio_for_bridges): model = network_model.VIF_MODEL_VIRTIO # Workaround libvirt bug, where it mistakenly # enables vhost mode, even for non-KVM guests if (model == network_model.VIF_MODEL_VIRTIO and virt_type == "qemu"): driver = "qemu" if not is_vif_model_valid_for_virt(virt_type, model): raise exception.UnsupportedHardware(model=model, virt=virt_type) if (virt_type == 'kvm' and model == network_model.VIF_MODEL_VIRTIO): vhost_drv, vhost_queues = self._get_virtio_mq_settings( image_meta, inst_type) driver = vhost_drv or driver designer.set_vif_guest_frontend_config(conf, vif['address'], model, driver, vhost_queues) return conf
def test_hardware_properties_from_meta(self): """Verifies that HardwareProperties attributes are being set from image properties. """ with mock.patch.object(osinfo._OsInfoDatabase, 'get_instance'): osinfo_obj = osinfo.HardwareProperties(self.img_meta) self.assertEqual('rtl8139', osinfo_obj.network_model) self.assertEqual('ide', osinfo_obj.disk_model)
def test_hardware_properties_from_osinfo(self): """Verifies that HardwareProperties attributes are being set from libosinfo. """ img_meta = {'properties': {'os_distro': 'fedora22'}} img_meta = objects.ImageMeta.from_dict(img_meta) osinfo_obj = osinfo.HardwareProperties(img_meta) self.assertEqual('virtio', osinfo_obj.network_model) self.assertEqual('virtio', osinfo_obj.disk_model)
def test_hardware_properties_from_meta_no_os_distro(self, mock_warn): """Verifies that HardwareProperties attributes are not being set from image properties if there is no os_distro provided. """ img_meta = {'properties': {'hw_watchdog_action': 'disabled'}} img_meta = objects.ImageMeta.from_dict(img_meta) with mock.patch.object(osinfo._OsInfoDatabase, 'get_instance') as get_instance: osinfo_obj = osinfo.HardwareProperties(img_meta) self.assertIsNone(osinfo_obj.network_model) self.assertIsNone(osinfo_obj.disk_model) get_instance.assert_not_called() mock_warn.assert_not_called()
def get_vif_model(self, image_meta=None, vif_model=None): model = vif_model # If the user has specified a 'vif_model' against the # image then honour that model if image_meta: model = osinfo.HardwareProperties(image_meta).network_model # If the virt type is KVM/QEMU/VZ(Parallels), then use virtio according # to the global config parameter if (model is None and CONF.libvirt.virt_type in ('kvm', 'qemu', 'parallels') and CONF.libvirt.use_virtio_for_bridges): model = network_model.VIF_MODEL_VIRTIO return model
def test_hardware_properties_from_osinfo(self): """Verifies that HardwareProperties attributes are being set from libosinfo. """ img_meta = {'properties': {'os_distro': 'fedora19'}} img_meta = objects.ImageMeta.from_dict(img_meta) with test.nested( mock.patch.object(osinfo.OsInfo, 'network_model', new_callable=mock.PropertyMock, return_value='rtl8139'), mock.patch.object(osinfo.OsInfo, 'disk_model', new_callable=mock.PropertyMock, return_value='scsi')): osinfo_obj = osinfo.HardwareProperties(img_meta) self.assertEqual('rtl8139', osinfo_obj.network_model) self.assertEqual('scsi', osinfo_obj.disk_model)
def get_base_config(self, instance, mac, image_meta, inst_type, virt_type, vnic_type, host): # TODO(sahid): We should rewrite it. This method handles too # many unrelated things. We probably need to have a specific # virtio, vhost, vhostuser functions. conf = vconfig.LibvirtConfigGuestInterface() # Default to letting libvirt / the hypervisor choose the model model = None driver = None vhost_queues = None rx_queue_size = None # NOTE(stephenfin): Skip most things here as only apply to virtio # devices if vnic_type in network_model.VNIC_TYPES_DIRECT_PASSTHROUGH: designer.set_vif_guest_frontend_config( conf, mac, model, driver, vhost_queues, rx_queue_size) return conf # If the user has specified a 'vif_model' against the # image then honour that model if image_meta: model = osinfo.HardwareProperties(image_meta).network_model # If the virt type is KVM/QEMU/VZ(Parallels), then use virtio according # to the global config parameter if (model is None and virt_type in ('kvm', 'qemu', 'parallels') and CONF.libvirt.use_virtio_for_bridges): model = network_model.VIF_MODEL_VIRTIO if not is_vif_model_valid_for_virt(virt_type, model): raise exception.UnsupportedHardware(model=model, virt=virt_type) # The rest of this only applies to virtio if model != network_model.VIF_MODEL_VIRTIO: designer.set_vif_guest_frontend_config( conf, mac, model, driver, vhost_queues, rx_queue_size) return conf # Workaround libvirt bug, where it mistakenly enables vhost mode, even # for non-KVM guests if virt_type == 'qemu': driver = 'qemu' if virt_type in ('kvm', 'parallels'): vhost_drv, vhost_queues = self._get_virtio_mq_settings(image_meta, inst_type) # TODO(sahid): It seems that we return driver 'vhost' even # for vhostuser interface where for vhostuser interface # the driver should be 'vhost-user'. That currently does # not create any issue since QEMU ignores the driver # argument for vhostuser interface but we should probably # fix that anyway. Also we should enforce that the driver # use vhost and not None. driver = vhost_drv or driver if driver == 'vhost' or driver is None: # vhost backend only supports update of RX queue size rx_queue_size, _ = self._get_virtio_queue_sizes(host) if rx_queue_size: # TODO(sahid): Specifically force driver to be vhost # that because if None we don't generate the XML # driver element needed to set the queue size # attribute. This can be removed when get_base_config # will be fixed and rewrite to set the correct # backend. driver = 'vhost' designer.set_vif_guest_frontend_config( conf, mac, model, driver, vhost_queues, rx_queue_size) return conf
def get_disk_bus_for_device_type(instance, virt_type, image_meta, device_type="disk"): """Determine the best disk bus to use for a device type. Considering the currently configured virtualization type, return the optimal disk_bus to use for a given device type. For example, for a disk on KVM it will return 'virtio', while for a CDROM it will return 'ide' on x86_64 and 'scsi' on ppc64. Returns the disk_bus, or returns None if the device type is not supported for this virtualization """ # Prefer a disk bus set against the image first of all if device_type == "disk": disk_bus = osinfo.HardwareProperties(image_meta).disk_model else: key = "hw_" + device_type + "_bus" disk_bus = image_meta.properties.get(key) if disk_bus is not None: if not is_disk_bus_valid_for_virt(virt_type, disk_bus): raise exception.UnsupportedHardware(model=disk_bus, virt=virt_type) return disk_bus # Otherwise pick a hypervisor default disk bus if virt_type == "uml": if device_type == "disk": return "uml" elif virt_type == "lxc": return "lxc" elif virt_type == "xen": guest_vm_mode = vm_mode.get_from_instance(instance) if guest_vm_mode == vm_mode.HVM: return "ide" else: return "xen" elif virt_type in ("qemu", "kvm"): if device_type == "cdrom": guestarch = libvirt_utils.get_arch(image_meta) if guestarch in (arch.PPC, arch.PPC64, arch.PPCLE, arch.PPC64LE, arch.S390, arch.S390X, arch.AARCH64): return "scsi" else: return "ide" elif device_type == "disk": return "virtio" elif device_type == "floppy": return "fdc" elif virt_type == "parallels": if device_type == "cdrom": return "ide" elif device_type == "disk": return "sata" else: # If virt-type not in list then it is unsupported raise exception.UnsupportedVirtType(virt=virt_type) return None
def get_disk_bus_for_device_type(instance, virt_type, image_meta, device_type="disk"): """Determine the best disk bus to use for a device type. Considering the currently configured virtualization type, return the optimal disk_bus to use for a given device type. For example, for a disk on KVM it will return 'virtio', while for a CDROM, it will return 'ide' for the 'pc' machine type on x86_64, 'sata' for the 'q35' machine type on x86_64 and 'scsi' on ppc64. Returns the disk_bus, or returns None if the device type is not supported for this virtualization """ # Prefer a disk bus set against the image first of all if device_type == "disk": disk_bus = osinfo.HardwareProperties(image_meta).disk_model else: key = "hw_" + device_type + "_bus" disk_bus = image_meta.properties.get(key) if disk_bus is not None: if not is_disk_bus_valid_for_virt(virt_type, disk_bus): raise exception.UnsupportedHardware(model=disk_bus, virt=virt_type) return disk_bus # Otherwise pick a hypervisor default disk bus if virt_type == "uml": if device_type == "disk": return "uml" elif virt_type == "lxc": return "lxc" elif virt_type == "xen": guest_vm_mode = obj_fields.VMMode.get_from_instance(instance) if guest_vm_mode == obj_fields.VMMode.HVM: return "ide" else: return "xen" elif virt_type in ("qemu", "kvm"): if device_type == "cdrom": guestarch = libvirt_utils.get_arch(image_meta) if guestarch in ( obj_fields.Architecture.PPC, obj_fields.Architecture.PPC64, obj_fields.Architecture.PPCLE, obj_fields.Architecture.PPC64LE, obj_fields.Architecture.S390, obj_fields.Architecture.S390X, obj_fields.Architecture.AARCH64): return "scsi" machine_type = libvirt_utils.get_machine_type(image_meta) # NOTE(lyarwood): We can't be any more explicit here as QEMU # provides a version of the Q35 machine type per release. # Additionally downstream distributions can also provide their own. if machine_type and 'q35' in machine_type: # NOTE(lyarwood): The Q35 machine type does not provide an IDE # bus and as such we must use a SATA bus for cdroms. return "sata" else: return "ide" elif device_type == "disk": return "virtio" elif device_type == "floppy": return "fdc" elif virt_type == "parallels": if device_type == "cdrom": return "ide" elif device_type == "disk": return "scsi" else: # If virt-type not in list then it is unsupported raise exception.UnsupportedVirtType(virt=virt_type) return None