1# 2# Common code for all guests 3# 4# Copyright 2006-2009, 2013, 2014, 2015 Red Hat, Inc. 5# 6# This work is licensed under the GNU GPLv2 or later. 7# See the COPYING file in the top-level directory. 8 9import random 10 11from . import generatename 12from . import xmlutil 13from .buildconfig import BuildConfig 14from .devices import * # pylint: disable=wildcard-import 15from .domain import * # pylint: disable=wildcard-import 16from .domcapabilities import DomainCapabilities 17from .logger import log 18from .osdict import OSDB 19from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty 20 21_ignore = Device 22 23 24class _DomainDevices(XMLBuilder): 25 XML_NAME = "devices" 26 _XML_PROP_ORDER = ['disk', 'controller', 'filesystem', 'interface', 27 'smartcard', 'serial', 'parallel', 'console', 'channel', 28 'input', 'tpm', 'graphics', 'sound', 'video', 'hostdev', 29 'redirdev', 'watchdog', 'memballoon', 'rng', 'panic', 30 'memory', 'vsock', 'iommu'] 31 32 33 disk = XMLChildProperty(DeviceDisk) 34 controller = XMLChildProperty(DeviceController) 35 filesystem = XMLChildProperty(DeviceFilesystem) 36 interface = XMLChildProperty(DeviceInterface) 37 smartcard = XMLChildProperty(DeviceSmartcard) 38 serial = XMLChildProperty(DeviceSerial) 39 parallel = XMLChildProperty(DeviceParallel) 40 console = XMLChildProperty(DeviceConsole) 41 channel = XMLChildProperty(DeviceChannel) 42 input = XMLChildProperty(DeviceInput) 43 tpm = XMLChildProperty(DeviceTpm) 44 graphics = XMLChildProperty(DeviceGraphics) 45 sound = XMLChildProperty(DeviceSound) 46 video = XMLChildProperty(DeviceVideo) 47 hostdev = XMLChildProperty(DeviceHostdev) 48 redirdev = XMLChildProperty(DeviceRedirdev) 49 watchdog = XMLChildProperty(DeviceWatchdog) 50 memballoon = XMLChildProperty(DeviceMemballoon) 51 rng = XMLChildProperty(DeviceRng) 52 panic = XMLChildProperty(DevicePanic) 53 memory = XMLChildProperty(DeviceMemory) 54 vsock = XMLChildProperty(DeviceVsock) 55 iommu = XMLChildProperty(DeviceIommu) 56 57 def get_all(self): 58 retlist = [] 59 # pylint: disable=protected-access 60 devtypes = _DomainDevices._XML_PROP_ORDER 61 for devtype in devtypes: 62 retlist.extend(getattr(self, devtype)) 63 return retlist 64 65 66class _IOThreadID(XMLBuilder): 67 XML_NAME = "iothread" 68 _XML_PROP_ORDER = ["id"] 69 70 id = XMLProperty("./@id", is_int=True) 71 72 73class Guest(XMLBuilder): 74 @staticmethod 75 def validate_name(conn, name, check_collision=True, validate=True): 76 if validate: 77 XMLBuilder.validate_generic_name(_("Guest"), name) 78 if not check_collision: 79 return 80 81 try: 82 conn.lookupByName(name) 83 except Exception: 84 return 85 raise ValueError(_("Guest name '%s' is already in use.") % name) 86 87 @staticmethod 88 def generate_uuid(conn): 89 def _randomUUID(): 90 if conn.fake_conn_predictable(): 91 # Testing hack 92 return "00000000-1111-2222-3333-444444444444" 93 94 u = [random.randint(0, 255) for ignore in range(0, 16)] 95 u[6] = (u[6] & 0x0F) | (4 << 4) 96 u[8] = (u[8] & 0x3F) | (2 << 6) 97 98 return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2, 99 "%02x" * 6]) % tuple(u) 100 101 for ignore in range(256): 102 uuid = _randomUUID() 103 if not generatename.check_libvirt_collision( 104 conn.lookupByUUID, uuid): 105 return uuid 106 107 log.error( # pragma: no cover 108 "Failed to generate non-conflicting UUID") 109 110 @staticmethod 111 def generate_name(guest): 112 def _pretty_arch(_a): 113 if _a == "armv7l": 114 return "arm" 115 return _a 116 117 force_num = False 118 basename = guest.osinfo.name 119 if basename.endswith("-unknown"): 120 basename = basename.rsplit("-", 1)[0] 121 122 if guest.osinfo.name == "generic": 123 force_num = True 124 if guest.os.is_container(): 125 basename = "container" 126 else: 127 basename = "vm" 128 129 if guest.os.arch != guest.conn.caps.host.cpu.arch: 130 basename += "-%s" % _pretty_arch(guest.os.arch) 131 force_num = False 132 133 def cb(n): 134 return generatename.check_libvirt_collision( 135 guest.conn.lookupByName, n) 136 return generatename.generate_name(basename, cb, 137 start_num=force_num and 1 or 2, force_num=force_num, 138 sep=not force_num and "-" or "") 139 140 141 @staticmethod 142 def get_recommended_machine(capsinfo): 143 """ 144 Return the recommended machine type for the passed capsinfo. 145 We only return this for arch cases where there's a very clear 146 preference that's different from the default machine type 147 """ 148 def _qemu_machine(): 149 if (capsinfo.arch in ["ppc64", "ppc64le"] and 150 "pseries" in capsinfo.machines): 151 return "pseries" 152 153 if capsinfo.arch in ["armv7l", "aarch64"]: 154 if "virt" in capsinfo.machines: 155 return "virt" 156 if "vexpress-a15" in capsinfo.machines: # pragma: no cover 157 return "vexpress-a15" 158 159 if capsinfo.arch in ["s390x"]: 160 if "s390-ccw-virtio" in capsinfo.machines: 161 return "s390-ccw-virtio" 162 163 if capsinfo.arch in ["riscv64", "riscv32"]: 164 if "virt" in capsinfo.machines: 165 return "virt" 166 167 if capsinfo.conn.is_qemu() or capsinfo.conn.is_test(): 168 return _qemu_machine() 169 return None 170 171 172 ################# 173 # init handling # 174 ################# 175 176 XML_NAME = "domain" 177 _XML_PROP_ORDER = [ 178 "type", "name", "uuid", "genid", "genid_enable", 179 "title", "description", "_metadata", "iothreads", "iothreadids", 180 "maxMemory", "maxMemorySlots", "memory", "_currentMemory", 181 "blkiotune", "memtune", "memoryBacking", 182 "_vcpus", "vcpu_current", "vcpu_placement", 183 "vcpu_cpuset", "vcpulist", "numatune", "resource", "sysinfo", 184 "bootloader", "os", "idmap", "features", "cpu", "clock", 185 "on_poweroff", "on_reboot", "on_crash", 186 "pm", "emulator", "devices", "launchSecurity", "seclabels", "keywrap"] 187 188 def __init__(self, *args, **kwargs): 189 XMLBuilder.__init__(self, *args, **kwargs) 190 191 # Allow virt-manager to override the default graphics type 192 self.default_graphics_type = BuildConfig.default_graphics 193 194 self.skip_default_console = False 195 self.skip_default_channel = False 196 self.skip_default_sound = False 197 self.skip_default_usbredir = False 198 self.skip_default_graphics = False 199 self.skip_default_rng = False 200 self.x86_cpu_default = self.cpu.SPECIAL_MODE_APP_DEFAULT 201 202 self.skip_default_osinfo = False 203 self.uefi_requested = False 204 self.__osinfo = None 205 self._capsinfo = None 206 self._domcaps = None 207 self._extra_drivers = None 208 209 210 ###################### 211 # Property accessors # 212 ###################### 213 214 name = XMLProperty("./name") 215 216 iothreads = XMLProperty("./iothreads", is_int=True) 217 iothreadids = XMLChildProperty(_IOThreadID, relative_xpath="./iothreadids") 218 219 def _set_currentMemory(self, val): 220 if val is not None: 221 val = int(val) 222 if self.memory is None or self.memory < val: 223 self.memory = val 224 self._currentMemory = val 225 def _get_currentMemory(self): 226 return self._currentMemory 227 currentMemory = property(_get_currentMemory, _set_currentMemory) 228 229 _currentMemory = XMLProperty("./currentMemory", is_int=True) 230 memory = XMLProperty("./memory", is_int=True) 231 maxMemory = XMLProperty("./maxMemory", is_int=True) 232 maxMemorySlots = XMLProperty("./maxMemory/@slots", is_int=True) 233 234 def _set_vcpus(self, val): 235 if val is not None: 236 val = int(val) 237 # Don't force set curvcpus unless already specified 238 if self.vcpu_current is not None and self.vcpu_current > val: 239 self.vcpu_current = val 240 self._vcpus = val 241 def _get_vcpus(self): 242 return self._vcpus 243 _vcpus = XMLProperty("./vcpu", is_int=True) 244 vcpus = property(_get_vcpus, _set_vcpus) 245 246 vcpu_current = XMLProperty("./vcpu/@current", is_int=True) 247 vcpu_placement = XMLProperty("./vcpu/@placement") 248 vcpu_cpuset = XMLProperty("./vcpu/@cpuset") 249 250 uuid = XMLProperty("./uuid") 251 genid = XMLProperty("./genid") 252 genid_enable = XMLProperty("./genid", is_bool=True) 253 id = XMLProperty("./@id", is_int=True) 254 type = XMLProperty("./@type") 255 bootloader = XMLProperty("./bootloader") 256 description = XMLProperty("./description") 257 title = XMLProperty("./title") 258 emulator = XMLProperty("./devices/emulator") 259 260 on_poweroff = XMLProperty("./on_poweroff") 261 on_reboot = XMLProperty("./on_reboot") 262 on_crash = XMLProperty("./on_crash") 263 on_lockfailure = XMLProperty("./on_lockfailure") 264 265 vcpulist = XMLChildProperty(DomainVCPUs, is_single=True) 266 seclabels = XMLChildProperty(DomainSeclabel) 267 keywrap = XMLChildProperty(DomainKeyWrap, is_single=True) 268 os = XMLChildProperty(DomainOs, is_single=True) 269 features = XMLChildProperty(DomainFeatures, is_single=True) 270 clock = XMLChildProperty(DomainClock, is_single=True) 271 cpu = XMLChildProperty(DomainCpu, is_single=True) 272 cputune = XMLChildProperty(DomainCputune, is_single=True) 273 numatune = XMLChildProperty(DomainNumatune, is_single=True) 274 pm = XMLChildProperty(DomainPm, is_single=True) 275 blkiotune = XMLChildProperty(DomainBlkiotune, is_single=True) 276 memtune = XMLChildProperty(DomainMemtune, is_single=True) 277 memoryBacking = XMLChildProperty(DomainMemoryBacking, is_single=True) 278 idmap = XMLChildProperty(DomainIdmap, is_single=True) 279 resource = XMLChildProperty(DomainResource, is_single=True) 280 sysinfo = XMLChildProperty(DomainSysinfo) 281 launchSecurity = XMLChildProperty(DomainLaunchSecurity, is_single=True) 282 _metadata = XMLChildProperty(DomainMetadata, is_single=True) 283 284 xmlns_qemu = XMLChildProperty(DomainXMLNSQemu, is_single=True) 285 286 287 ############################## 288 # osinfo related definitions # 289 ############################## 290 291 def _get_osinfo(self): 292 if self.__osinfo: 293 return self.__osinfo 294 295 os_id = self._metadata.libosinfo.os_id 296 if os_id: 297 self.__osinfo = OSDB.lookup_os_by_full_id(os_id) 298 if not self.__osinfo: 299 log.debug("XML had libosinfo os id=%s but we didn't " 300 "find any libosinfo object matching that", os_id) 301 302 if not self.__osinfo: 303 # If you hit this error, it means some part of the cli 304 # tried to access osinfo before we can depend on it being 305 # available. Try moving whatever bits need osinfo to be 306 # triggered via set_defaults 307 if self.skip_default_osinfo: 308 raise xmlutil.DevError( 309 "osinfo is accessed before it has been set.") 310 self.set_default_os_name() 311 return self.__osinfo 312 osinfo = property(_get_osinfo) 313 314 def _set_os_obj(self, obj): 315 self.__osinfo = obj 316 self._metadata.libosinfo.os_id = obj.full_id 317 318 def set_os_name(self, name): 319 obj = OSDB.lookup_os(name, raise_error=True) 320 log.debug("Setting Guest osinfo name %s", obj) 321 self._set_os_obj(obj) 322 323 def set_default_os_name(self): 324 self.set_os_name("generic") 325 326 def _supports_virtio(self, os_support): 327 if not self.conn.is_qemu(): 328 return False 329 330 # These _only_ support virtio so don't check the OS 331 if (self.os.is_arm_machvirt() or 332 self.os.is_riscv_virt() or 333 self.os.is_s390x() or 334 self.os.is_pseries()): 335 return True 336 337 if not os_support: 338 return False 339 340 if self.os.is_x86(): 341 return True 342 343 return False # pragma: no cover 344 345 def supports_virtionet(self): 346 return self._supports_virtio(self.osinfo.supports_virtionet(self._extra_drivers)) 347 def supports_virtiodisk(self): 348 return self._supports_virtio(self.osinfo.supports_virtiodisk(self._extra_drivers)) 349 def supports_virtioscsi(self): 350 return self._supports_virtio(self.osinfo.supports_virtioscsi(self._extra_drivers)) 351 def _supports_virtioserial(self): 352 return self._supports_virtio(self.osinfo.supports_virtioserial(self._extra_drivers)) 353 354 355 ##################### 356 # Bootorder helpers # 357 ##################### 358 359 def _get_old_boot_order(self): 360 return self.os.bootorder 361 362 def _convert_old_boot_order(self): 363 """Converts the old boot order (e.g. <boot dev='hd'/>) into the 364 per-device boot order format. 365 366 """ 367 boot_order = self._get_old_boot_order() 368 ret = [] 369 disk = None 370 cdrom = None 371 floppy = None 372 net = None 373 374 for d in self.devices.disk: 375 if not cdrom and d.device == "cdrom": 376 cdrom = d 377 if not floppy and d.device == "floppy": 378 floppy = d 379 if not disk and d.device not in ["cdrom", "floppy"]: 380 disk = d 381 if cdrom and disk and floppy: 382 break 383 384 for n in self.devices.interface: 385 net = n 386 break 387 388 for b in boot_order: 389 if b == "network" and net: 390 ret.append(net.get_xml_id()) 391 elif b == "hd" and disk: 392 ret.append(disk.get_xml_id()) 393 elif b == "cdrom" and cdrom: 394 ret.append(cdrom.get_xml_id()) 395 elif b == "fd" and floppy: 396 ret.append(floppy.get_xml_id()) 397 return ret 398 399 def _get_device_boot_order(self): 400 order = [] 401 for dev in self.get_bootable_devices(): 402 if not dev.boot.order: 403 continue 404 order.append((dev.get_xml_id(), dev.boot.order)) 405 406 if not order: 407 # No devices individually marked bootable, convert traditional 408 # boot XML to fine grained 409 return self._convert_old_boot_order() 410 411 order.sort(key=lambda p: p[1]) 412 return [p[0] for p in order] 413 414 def get_boot_order(self, legacy=False): 415 if legacy: 416 return self._get_old_boot_order() 417 return self._get_device_boot_order() 418 419 def _set_device_boot_order(self, boot_order): 420 """Sets the new device boot order for the domain""" 421 # Unset the traditional boot order 422 self.os.bootorder = [] 423 424 # Unset device boot order 425 for dev in self.devices.get_all(): 426 dev.boot.order = None 427 428 dev_map = dict((dev.get_xml_id(), dev) for dev in 429 self.get_bootable_devices()) 430 for boot_idx, dev_xml_id in enumerate(boot_order, 1): 431 dev_map[dev_xml_id].boot.order = boot_idx 432 433 def set_boot_order(self, boot_order, legacy=False): 434 """Modifies the boot order""" 435 if legacy: 436 self.os.bootorder = boot_order 437 else: 438 self._set_device_boot_order(boot_order) 439 440 def reorder_boot_order(self, dev, boot_index): 441 """Sets boot order of `dev` to `boot_index` 442 443 Sets the boot order for device `dev` to value `boot_index` and 444 adjusts all other boot indices accordingly. Additionally the 445 boot order defined in the 'os' node of a domain definition is 446 disabled since they are mutually exclusive in libvirt. 447 448 """ 449 # unset legacy boot order 450 self.os.bootorder = [] 451 452 # Sort the bootable devices by boot order 453 devs_sorted = sorted([device for device in self.get_bootable_devices() 454 if device.boot.order is not None], 455 key=lambda device: device.boot.order) 456 457 # set new boot order 458 dev.boot.order = boot_index 459 460 next_boot_index = None 461 for device in devs_sorted: 462 if device is dev: 463 continue 464 465 if device.boot.order in [next_boot_index, boot_index]: 466 next_boot_index = device.boot.order + 1 467 device.boot.order = next_boot_index 468 continue 469 470 if next_boot_index is not None: 471 # we found a hole so we can stop here 472 break 473 474 475 ############################### 476 # Public XML APIs and helpers # 477 ############################### 478 479 def add_device(self, dev): 480 self.devices.add_child(dev) 481 def remove_device(self, dev): 482 self.devices.remove_child(dev) 483 devices = XMLChildProperty(_DomainDevices, is_single=True) 484 485 def find_device(self, origdev): 486 """ 487 Try to find a child device that matches the content of 488 the passed @origdev. 489 """ 490 devlist = getattr(self.devices, origdev.DEVICE_TYPE) 491 for idx, dev in enumerate(devlist): 492 if origdev.compare_device(dev, idx): 493 return dev 494 return None 495 496 def get_bootable_devices(self, exclude_redirdev=False): 497 """ 498 Returns bootable devices of the guest definition. If 499 @exclude_redirdev is `True` redirected devices will be 500 skipped in the output. 501 502 """ 503 devices = self.devices 504 devs = devices.disk + devices.interface + devices.hostdev 505 if not exclude_redirdev: 506 devs = devs + devices.redirdev 507 return devs 508 509 def prefers_uefi(self): 510 """ 511 Return True if this config prefers UEFI. For example, 512 arm+machvirt prefers UEFI since it's required for traditional 513 install methods 514 """ 515 return self.os.is_arm_machvirt() 516 517 def get_uefi_path(self): 518 """ 519 If UEFI firmware path is found, return it, otherwise raise an error 520 """ 521 domcaps = self.lookup_domcaps() 522 523 if not domcaps.supports_uefi_xml(): 524 raise RuntimeError(_("Libvirt version does not support UEFI.")) 525 526 if not domcaps.arch_can_uefi(): 527 raise RuntimeError( 528 _("Don't know how to setup UEFI for arch '%s'") % 529 self.os.arch) 530 531 path = domcaps.find_uefi_path_for_arch() 532 if not path: # pragma: no cover 533 raise RuntimeError(_("Did not find any UEFI binary path for " 534 "arch '%s'") % self.os.arch) 535 536 return path 537 538 def is_uefi(self): 539 if self.os.loader and self.os.loader_type == "pflash": 540 return True 541 return self.os.firmware == "efi" 542 543 def set_uefi_path(self, path): 544 """ 545 Configure UEFI for the VM, but only if libvirt is advertising 546 a known UEFI binary path. 547 """ 548 self.os.loader_ro = True 549 self.os.loader_type = "pflash" 550 self.os.loader = path 551 552 # If the firmware name contains "secboot" it is probably build 553 # with SMM feature required so we need to enable that feature, 554 # otherwise the firmware may fail to load. True secure boot is 555 # currently supported only on x86 architecture and with q35 with 556 # SMM feature enabled so change the machine to q35 as well. 557 # To actually enforce the secure boot for the guest if Secure Boot 558 # Mode is configured we need to enable loader secure feature. 559 if (self.os.is_x86() and 560 "secboot" in self.os.loader): 561 self.features.smm = True 562 self.os.loader_secure = True 563 if self.os.machine and "q35" not in self.os.machine: 564 log.warning("Changing machine type from '%s' to 'q35' " 565 "which is required for UEFI secure boot.", 566 self.os.machine) 567 self.os.machine = "q35" 568 569 def disable_hyperv_for_uefi(self): 570 # UEFI doesn't work with hyperv bits for some OS 571 if not self.is_uefi(): 572 return # pragma: no cover 573 if not self.osinfo.broken_uefi_with_hyperv(): 574 return # pragma: no cover 575 self.features.hyperv_relaxed = None 576 self.features.hyperv_vapic = None 577 self.features.hyperv_spinlocks = None 578 self.features.hyperv_spinlocks_retries = None 579 for i in self.clock.timers: 580 if i.name == "hypervclock": 581 self.clock.timers.remove(i) 582 583 def has_spice(self): 584 for gfx in self.devices.graphics: 585 if gfx.type == gfx.TYPE_SPICE: 586 return True 587 588 def has_gl(self): 589 for gfx in self.devices.graphics: 590 if gfx.gl: 591 return True 592 593 def has_listen_none(self): 594 for gfx in self.devices.graphics: 595 listen = gfx.get_first_listen_type() 596 if listen and listen == "none": 597 return True 598 return False 599 600 def is_full_os_container(self): 601 if not self.os.is_container(): 602 return False 603 for fs in self.devices.filesystem: 604 if fs.target == "/": 605 return True 606 return False 607 608 def can_default_virtioscsi(self): 609 """ 610 Return True if the guest supports virtio-scsi, and there's 611 no other scsi controllers attached to the guest 612 """ 613 has_any_scsi = any([d.type == "scsi" for d in self.devices.controller]) 614 return not has_any_scsi and self.supports_virtioscsi() 615 616 def hyperv_supported(self): 617 if not self.osinfo.is_windows(): 618 return False 619 if (self.is_uefi() and 620 self.osinfo.broken_uefi_with_hyperv()): 621 return False 622 return True 623 624 def lookup_domcaps(self): 625 # We need to regenerate domcaps cache if any of these values change 626 def _compare(domcaps): # pragma: no cover 627 if self.type == "test": 628 # Test driver doesn't support domcaps. We kinda fake it in 629 # some cases, but it screws up the checking here for parsed XML 630 return True 631 if self.os.machine and self.os.machine != domcaps.machine: 632 return False 633 if self.type and self.type != domcaps.domain: 634 return False 635 if self.os.arch and self.os.arch != domcaps.arch: 636 return False 637 if self.emulator and self.emulator != domcaps.path: 638 return False 639 return True 640 641 if not self._domcaps or not _compare(self._domcaps): 642 self._domcaps = DomainCapabilities.build_from_guest(self) 643 return self._domcaps 644 645 def lookup_capsinfo(self): 646 # We need to regenerate capsinfo cache if any of these values change 647 def _compare(capsinfo): # pragma: no cover 648 if self.type and self.type != capsinfo.hypervisor_type: 649 return False 650 if self.os.os_type and self.os.os_type != capsinfo.os_type: 651 return False 652 if self.os.arch and self.os.arch != capsinfo.arch: 653 return False 654 if self.os.machine and self.os.machine not in capsinfo.machines: 655 return False 656 return True 657 658 if not self._capsinfo or not _compare(self._capsinfo): 659 self._capsinfo = self.conn.caps.guest_lookup( 660 os_type=self.os.os_type, 661 arch=self.os.arch, 662 typ=self.type, 663 machine=self.os.machine) 664 return self._capsinfo 665 666 def set_capabilities_defaults(self, capsinfo=None): 667 if capsinfo: # pragma: no cover 668 self._capsinfo = capsinfo 669 else: 670 capsinfo = self.lookup_capsinfo() 671 wants_default_type = not self.type and not self.os.os_type 672 673 self.type = capsinfo.hypervisor_type 674 self.os.os_type = capsinfo.os_type 675 self.os.arch = capsinfo.arch 676 if not self.os.loader: 677 self.os.loader = capsinfo.loader 678 if (not self.emulator and 679 not self.os.is_xenpv() and 680 self.type != "vz"): 681 self.emulator = capsinfo.emulator 682 if not self.os.machine: 683 self.os.machine = Guest.get_recommended_machine(capsinfo) 684 685 if (wants_default_type and 686 self.conn.is_qemu() and 687 self.os.is_x86() and 688 self.type != "kvm"): 689 log.warning( # pragma: no cover 690 "KVM acceleration not available, using '%s'", self.type) 691 692 def sync_vcpus_topology(self): 693 """ 694 <cpu> topology count and <vcpus> always need to match. Handle 695 the syncing here since we are less constrained then doing it 696 in CPU set_defaults 697 """ 698 if not self.cpu.has_topology(): 699 return 700 if not self.vcpus: 701 self.vcpus = self.cpu.vcpus_from_topology() 702 self.cpu.set_topology_defaults(self.vcpus) 703 704 def set_defaults(self, _guest): 705 self.set_capabilities_defaults() 706 707 if not self.uuid: 708 self.uuid = Guest.generate_uuid(self.conn) 709 710 self.sync_vcpus_topology() 711 if not self.vcpus: 712 # Typically if omitted libvirt will fill this value in for us 713 # However if user specified cpuset= or placement=, libvirt 714 # will error if <vcpus>X is also unset. So keep this for safety 715 self.vcpus = 1 716 717 self._set_default_machine() 718 self._set_default_uefi() 719 720 self._add_default_graphics() 721 self._add_default_video_device() 722 self._add_default_input_device() 723 self._add_default_console_device() 724 self._add_default_usb_controller() 725 self._add_default_channels() 726 self._add_default_rng() 727 self._add_default_memballoon() 728 729 self.clock.set_defaults(self) 730 self.cpu.set_defaults(self) 731 self.features.set_defaults(self) 732 for seclabel in self.seclabels: 733 seclabel.set_defaults(self) 734 self.pm.set_defaults(self) 735 self.os.set_defaults(self) 736 self.launchSecurity.set_defaults(self) 737 738 for dev in self.devices.get_all(): 739 dev.set_defaults(self) 740 741 self._add_implied_controllers() 742 self._add_spice_devices() 743 744 def add_extra_drivers(self, extra_drivers): 745 self._extra_drivers = extra_drivers 746 747 748 ######################## 749 # Private xml routines # 750 ######################## 751 752 def _set_default_machine(self): 753 if self.os.machine: 754 return 755 756 capsinfo = self.lookup_capsinfo() 757 758 if (self.os.is_x86() and 759 self.conn.is_qemu() and 760 "q35" in capsinfo.machines and 761 self.conn.support.qemu_q35_default() and 762 self.osinfo.supports_chipset_q35()): 763 self.os.machine = "q35" 764 return 765 766 default = capsinfo.machines and capsinfo.machines[0] or None 767 self.os.machine = default 768 769 770 def _set_default_uefi(self): 771 use_default_uefi = (self.prefers_uefi() and 772 not self.os.kernel and 773 not self.os.loader and 774 self.os.loader_ro is None and 775 self.os.nvram is None and 776 self.os.firmware is None) 777 778 if use_default_uefi or self.uefi_requested: 779 try: 780 path = self.get_uefi_path() 781 log.debug("Setting UEFI path=%s", path) 782 self.set_uefi_path(path) 783 except RuntimeError as e: 784 if self.uefi_requested: 785 raise 786 log.debug("Error setting UEFI default", 787 exc_info=True) 788 log.warning("Couldn't configure UEFI: %s", e) 789 log.warning("Your VM may not boot successfully.") 790 791 def _usb_disabled(self): 792 controllers = [c for c in self.devices.controller if 793 c.type == "usb"] 794 if not controllers: 795 return False 796 return all([c.model == "none" for c in controllers]) 797 798 def _add_default_input_device(self): 799 if self.os.is_container(): 800 return 801 if self.devices.input: 802 return 803 if not self.devices.graphics: 804 return 805 if self._usb_disabled(): 806 return 807 808 usb_tablet = False 809 usb_keyboard = False 810 if self.os.is_x86() and not self.os.is_xenpv(): 811 usb_tablet = self.osinfo.supports_usbtablet() 812 if (self.os.is_arm_machvirt() or 813 self.os.is_riscv_virt() or 814 self.os.is_pseries()): 815 usb_tablet = True 816 usb_keyboard = True 817 818 if usb_tablet: 819 dev = DeviceInput(self.conn) 820 dev.type = "tablet" 821 dev.bus = "usb" 822 self.add_device(dev) 823 if usb_keyboard: 824 dev = DeviceInput(self.conn) 825 dev.type = "keyboard" 826 dev.bus = "usb" 827 self.add_device(dev) 828 829 # s390x guests need VirtIO input devices 830 if self.os.is_s390x() and self.osinfo.supports_virtioinput(self._extra_drivers): 831 dev = DeviceInput(self.conn) 832 dev.type = "tablet" 833 dev.bus = "virtio" 834 self.add_device(dev) 835 dev = DeviceInput(self.conn) 836 dev.type = "keyboard" 837 dev.bus = "virtio" 838 self.add_device(dev) 839 840 def _add_default_console_device(self): 841 if self.skip_default_console: 842 return 843 if self.devices.console or self.devices.serial: 844 return 845 846 dev = DeviceConsole(self.conn) 847 dev.type = dev.TYPE_PTY 848 if self.os.is_s390x(): 849 dev.target_type = "sclp" 850 self.add_device(dev) 851 852 def _add_default_video_device(self): 853 if self.os.is_container(): 854 return 855 if self.devices.video: 856 return 857 if not self.devices.graphics: 858 return 859 self.add_device(DeviceVideo(self.conn)) 860 861 def _add_default_usb_controller(self): 862 if any([d.type == "usb" for d in self.devices.controller]): 863 return 864 if not self.conn.is_qemu() and not self.conn.is_test(): 865 return 866 867 qemu_usb3 = self.conn.support.conn_qemu_xhci() 868 usb2 = False 869 usb3 = False 870 if self.os.is_x86(): 871 usb3 = bool(self.osinfo.supports_usb3() and qemu_usb3) 872 usb2 = not usb3 873 elif self.os.is_arm_machvirt(): 874 # For machvirt, we always assume OS supports usb3 875 if (qemu_usb3 and 876 self.conn.support.conn_machvirt_pci_default()): 877 usb3 = True 878 elif self.os.is_riscv_virt(): 879 # For RISC-V we can assume the guest OS supports USB3, but we 880 # have to make sure libvirt and QEMU are new enough to be using 881 # PCI by default 882 if (qemu_usb3 and 883 self.conn.support.conn_riscv_virt_pci_default()): 884 usb3 = True 885 elif self.os.is_pseries(): 886 # For pseries, we always assume OS supports usb3 887 if qemu_usb3: 888 usb3 = True 889 890 891 if usb2: 892 for dev in DeviceController.get_usb2_controllers(self.conn): 893 self.add_device(dev) 894 elif usb3: 895 self.add_device( 896 DeviceController.get_usb3_controller(self.conn, self)) 897 898 def _add_default_channels(self): 899 if self.skip_default_channel: 900 return 901 if self.devices.channel: 902 return 903 904 if (self.conn.is_qemu() and 905 self._supports_virtioserial() and 906 self.conn.support.conn_autosocket()): 907 dev = DeviceChannel(self.conn) 908 dev.type = "unix" 909 dev.target_type = "virtio" 910 dev.target_name = dev.CHANNEL_NAME_QEMUGA 911 self.add_device(dev) 912 913 def _add_default_graphics(self): 914 if self.skip_default_graphics: 915 return 916 if self.devices.graphics: 917 return 918 if self.os.is_container() and not self.conn.is_vz(): 919 return 920 if self.os.arch not in ["x86_64", "i686", "ppc64", "ppc64le"]: 921 return 922 self.add_device(DeviceGraphics(self.conn)) 923 924 def _add_default_rng(self): 925 if self.skip_default_rng: 926 return 927 if self.devices.rng: 928 return 929 if not (self.os.is_x86() or 930 self.os.is_arm_machvirt() or 931 self.os.is_riscv_virt() or 932 self.os.is_s390x() or 933 self.os.is_pseries()): 934 return 935 936 if (self.conn.is_qemu() and 937 self.osinfo.supports_virtiorng(self._extra_drivers) and 938 self.conn.support.conn_rng_urandom()): 939 dev = DeviceRng(self.conn) 940 dev.type = "random" 941 dev.device = "/dev/urandom" 942 self.add_device(dev) 943 944 def _add_default_memballoon(self): 945 if self.devices.memballoon: 946 return 947 if not self.conn.is_qemu(): 948 return 949 950 # We know for certain that a memballoon is good to have with these 951 # machine types; for other machine types, we leave the decision up 952 # to libvirt 953 if not (self.os.is_x86() or 954 self.os.is_arm_machvirt() or 955 self.os.is_riscv_virt() or 956 self.os.is_s390x() or 957 self.os.is_pseries()): 958 return 959 960 if self.osinfo.supports_virtioballoon(self._extra_drivers): 961 dev = DeviceMemballoon(self.conn) 962 dev.model = "virtio" 963 self.add_device(dev) 964 965 def _add_implied_controllers(self): 966 # Add virtio-scsi controller if needed 967 if self.can_default_virtioscsi(): 968 for dev in self.devices.disk: 969 if dev.bus == "scsi": 970 ctrl = DeviceController(self.conn) 971 ctrl.type = "scsi" 972 ctrl.model = "virtio-scsi" 973 ctrl.set_defaults(self) 974 self.add_device(ctrl) 975 break 976 977 def _add_spice_channels(self): 978 if self.skip_default_channel: 979 return 980 for chn in self.devices.channel: 981 if chn.type == chn.TYPE_SPICEVMC: 982 return 983 984 # We explicitly don't check for virtioserial support here. 985 # We did that for a while, which excluded windows, and 986 # we received some complaints. 987 # https://bugzilla.redhat.com/show_bug.cgi?id=1660123 988 dev = DeviceChannel(self.conn) 989 dev.type = DeviceChannel.TYPE_SPICEVMC 990 dev.set_defaults(self) 991 self.add_device(dev) 992 993 def _add_spice_sound(self): 994 if self.skip_default_sound: 995 return 996 if self.devices.sound: 997 return 998 if not self.os.is_hvm(): 999 return # pragma: no cover 1000 1001 dev = DeviceSound(self.conn) 1002 dev.set_defaults(self) 1003 self.add_device(dev) 1004 1005 def _add_spice_usbredir(self): 1006 if self.skip_default_usbredir: 1007 return 1008 if self.devices.redirdev: 1009 return 1010 if self._usb_disabled(): 1011 return 1012 if not self.os.is_x86(): 1013 return 1014 1015 # If we use 4 devices here, we fill up all the emulated USB2 slots, 1016 # and directly assigned devices are forced to fall back to USB1 1017 # https://bugzilla.redhat.com/show_bug.cgi?id=1135488 1018 for ignore in range(2): 1019 dev = DeviceRedirdev(self.conn) 1020 dev.bus = "usb" 1021 dev.type = "spicevmc" 1022 dev.set_defaults(self) 1023 self.add_device(dev) 1024 1025 def _add_spice_devices(self): 1026 if not self.has_spice(): 1027 return 1028 1029 if (self.features.vmport is None and 1030 self.os.is_x86() and 1031 self.conn.support.conn_vmport()): 1032 self.features.vmport = False 1033 1034 self._add_spice_channels() 1035 self._add_spice_sound() 1036 self._add_spice_usbredir() 1037