def get_disk_bus_for_device_type(virt_type, image_meta, device_type="disk", instance=None): """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 key = "hw_" + device_type + "_bus" disk_bus = image_meta.get('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 = None if instance: 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.S390, arch.S390X): 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 is_vif_model_valid_for_virt(virt_type, vif_model): valid_models = { 'qemu': [ network_model.VIF_MODEL_VIRTIO, network_model.VIF_MODEL_NE2K_PCI, network_model.VIF_MODEL_PCNET, network_model.VIF_MODEL_RTL8139, network_model.VIF_MODEL_E1000, network_model.VIF_MODEL_SPAPR_VLAN ], 'kvm': [ network_model.VIF_MODEL_VIRTIO, network_model.VIF_MODEL_NE2K_PCI, network_model.VIF_MODEL_PCNET, network_model.VIF_MODEL_RTL8139, network_model.VIF_MODEL_E1000, network_model.VIF_MODEL_SPAPR_VLAN ], 'xen': [ network_model.VIF_MODEL_NETFRONT, network_model.VIF_MODEL_NE2K_PCI, network_model.VIF_MODEL_PCNET, network_model.VIF_MODEL_RTL8139, network_model.VIF_MODEL_E1000 ], 'lxc': [], 'uml': [], 'parallels': [ network_model.VIF_MODEL_VIRTIO, network_model.VIF_MODEL_RTL8139, network_model.VIF_MODEL_E1000 ], } if vif_model is None: return True if virt_type not in valid_models: raise exception.UnsupportedVirtType(virt=virt_type) return vif_model in valid_models[virt_type]
def is_vif_model_valid_for_virt(virt_type, vif_model): if vif_model is None: return True if virt_type not in SUPPORTED_VIF_MODELS: raise exception.UnsupportedVirtType(virt=virt_type) return vif_model in SUPPORTED_VIF_MODELS[virt_type]
def is_disk_bus_valid_for_virt(virt_type, disk_bus): valid_bus = { 'qemu': ['virtio', 'scsi', 'ide', 'usb'], 'kvm': ['virtio', 'scsi', 'ide', 'usb'], 'xen': ['xen', 'ide'], 'uml': ['uml'], 'lxc': ['lxc'], } if virt_type not in valid_bus: raise exception.UnsupportedVirtType(virt=virt_type) return disk_bus in valid_bus[virt_type]
def is_vif_model_valid_for_virt(virt_type, vif_model): valid_models = { 'qemu': ['virtio', 'ne2k_pci', 'pcnet', 'rtl8139', 'e1000'], 'kvm': ['virtio', 'ne2k_pci', 'pcnet', 'rtl8139', 'e1000'], 'xen': ['netfront', 'ne2k_pci', 'pcnet', 'rtl8139', 'e1000'], 'lxc': [], 'uml': [], } if vif_model is None: return True if virt_type not in valid_models: raise exception.UnsupportedVirtType(virt=virt_type) return vif_model in valid_models[virt_type]
def is_disk_bus_valid_for_virt(virt_type, disk_bus): # NOTE(aspiers): If you change this, don't forget to update the # docs and metadata for hw_*_bus in glance. valid_bus = { 'qemu': ['virtio', 'scsi', 'ide', 'usb', 'fdc', 'sata'], 'kvm': ['virtio', 'scsi', 'ide', 'usb', 'fdc', 'sata'], 'xen': ['xen', 'ide'], 'uml': ['uml'], 'lxc': ['lxc'], 'parallels': ['ide', 'scsi'] } if virt_type not in valid_bus: raise exception.UnsupportedVirtType(virt=virt_type) return disk_bus in valid_bus[virt_type]
def _hard_reboot(*args, **kwargs): raise exception.UnsupportedVirtType(virt="FakeVirt")
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
def is_disk_bus_valid_for_virt(virt_type, disk_bus): if virt_type not in SUPPORTED_DEVICE_BUSES: raise exception.UnsupportedVirtType(virt=virt_type) return disk_bus in SUPPORTED_DEVICE_BUSES[virt_type]