diff options
-rw-r--r-- | tests/clitest.py | 1 | ||||
-rwxr-xr-x | virt-install | 100 | ||||
-rw-r--r-- | virtManager/create.py | 3 | ||||
-rw-r--r-- | virtinst/capabilities.py | 43 | ||||
-rw-r--r-- | virtinst/cli.py | 2 | ||||
-rw-r--r-- | virtinst/domain/features.py | 7 | ||||
-rw-r--r-- | virtinst/guest.py | 68 |
7 files changed, 102 insertions, 122 deletions
diff --git a/tests/clitest.py b/tests/clitest.py index 041097d4..cefc778f 100644 --- a/tests/clitest.py +++ b/tests/clitest.py @@ -632,7 +632,6 @@ c.add_valid("--hvm --cdrom %(EXISTIMG1)s") # Simple cdrom install c.add_valid("--wait 0 --os-variant winxp --cdrom %(EXISTIMG1)s") # Windows (2 stage) install c.add_valid("--pxe --virt-type test") # Explicit virt-type c.add_valid("--arch i686 --pxe") # Explicitly fullvirt + arch -c.add_valid("--arch i486 --pxe") # Convert i*86 -> i686 c.add_valid("--location %(TREEDIR)s") # Directory tree URL install c.add_valid("--location %(TREEDIR)s --initrd-inject virt-install --extra-args ks=file:/virt-install") # initrd-inject c.add_valid("--hvm --location %(TREEDIR)s --extra-args console=ttyS0") # Directory tree URL install with extra-args diff --git a/virt-install b/virt-install index 28f5987d..28cb5b77 100755 --- a/virt-install +++ b/virt-install @@ -8,7 +8,6 @@ import argparse import logging import os -import re import sys import time @@ -300,56 +299,6 @@ def convert_old_features(options): options.features = opts or None -######################## -# Virt type validation # -######################## - -def get_guest(conn, options): - # Set up all virt/hypervisor parameters - if sum([bool(f) for f in [options.fullvirt, - options.paravirt, - options.container]]) > 1: - fail(_("Can't do more than one of --hvm, --paravirt, or --container")) - - req_hv_type = options.hv_type and options.hv_type.lower() or None - if options.fullvirt: - req_virt_type = "hvm" - elif options.paravirt: - req_virt_type = "xen" - elif options.container: - req_virt_type = "exe" - else: - # This should force capabilities to give us the most sensible default - req_virt_type = None - - logging.debug("Requesting virt method '%s', hv type '%s'.", - (req_virt_type and req_virt_type or _("default")), - (req_hv_type and req_hv_type or _("default"))) - - arch = options.arch - if re.match("i.86", arch or ""): - arch = "i686" - - try: - guest = conn.caps.lookup_virtinst_guest( - os_type=req_virt_type, - arch=arch, - typ=req_hv_type, - machine=options.machine) - except Exception as e: - fail(e) - - if (not req_virt_type and - not req_hv_type and - conn.is_qemu() and - guest.os.arch in ["i686", "x86_64"] and - not guest.type == "kvm"): - logging.warning("KVM acceleration not available, using '%s'", - guest.type) - - return guest - - ################################## # Install media setup/validation # ################################## @@ -550,10 +499,7 @@ def build_installer(options, guest): def build_guest_instance(conn, options): - guest = get_guest(conn, options) - - logging.debug("Received virt method '%s'", guest.type) - logging.debug("Hypervisor name is '%s'", guest.os.os_type) + guest = virtinst.Guest(conn) if options.name: guest.name = options.name @@ -561,13 +507,24 @@ def build_guest_instance(conn, options): guest.uuid = options.uuid if options.description: guest.description = options.description + if options.os_type: + guest.os.os_type = options.os_type + if options.virt_type: + guest.type = options.virt_type + if options.arch: + guest.os.arch = options.arch + if options.machine: + guest.os.machine = options.machine cli.parse_option_strings(options, guest, None) - # Extra disk validation + # cli specific disk validation for disk in guest.devices.disk: cli.validate_disk(disk) + # Do this a bit early so we can do arch/os_type checks up ahead + guest.set_capabilities_defaults() + # Default to UEFI for aarch64 if ((guest.os.is_arm64() or guest.os.is_arm32()) and not guest.os.kernel and @@ -865,21 +822,22 @@ def parse_args(): virg = parser.add_argument_group(_("Virtualization Platform Options")) - virg.add_argument("-v", "--hvm", action="store_true", dest="fullvirt", - help=_("This guest should be a fully virtualized guest")) - virg.add_argument("-p", "--paravirt", action="store_true", - help=_("This guest should be a paravirtualized guest")) - virg.add_argument("--container", action="store_true", default=False, - help=_("This guest should be a container guest")) - virg.add_argument("--virt-type", dest="hv_type", - default="", - help=_("Hypervisor name to use (kvm, qemu, xen, ...)")) - virg.add_argument("--accelerate", action="store_true", default=False, - help=argparse.SUPPRESS) - virg.add_argument("--arch", - help=_("The CPU architecture to simulate")) - virg.add_argument("--machine", - help=_("The machine type to emulate")) + ostypeg = virg.add_mutually_exclusive_group() + ostypeg.add_argument("-v", "--hvm", + action="store_const", const="hvm", dest="os_type", + help=_("This guest should be a fully virtualized guest")) + ostypeg.add_argument("-p", "--paravirt", + action="store_const", const="xen", dest="os_type", + help=_("This guest should be a paravirtualized guest")) + ostypeg.add_argument("--container", + action="store_const", const="exe", dest="os_type", + help=_("This guest should be a container guest")) + virg.add_argument("--virt-type", + help=_("Hypervisor name to use (kvm, qemu, xen, ...)")) + virg.add_argument("--arch", help=_("The CPU architecture to simulate")) + virg.add_argument("--machine", help=_("The machine type to emulate")) + virg.add_argument("--accelerate", action="store_true", + help=argparse.SUPPRESS) virg.add_argument("--noapic", action="store_true", default=False, help=argparse.SUPPRESS) virg.add_argument("--noacpi", action="store_true", diff --git a/virtManager/create.py b/virtManager/create.py index 62648659..a23d9d60 100644 --- a/virtManager/create.py +++ b/virtManager/create.py @@ -864,7 +864,8 @@ class vmmCreate(vmmGObjectUI): defmachine = None prios = [] - recommended_machine = self._capsinfo.get_recommended_machine() + recommended_machine = virtinst.Guest.get_recommended_machine( + self._capsinfo) if recommended_machine: defmachine = recommended_machine prios = [defmachine] diff --git a/virtinst/capabilities.py b/virtinst/capabilities.py index e30328fd..d49bd9e7 100644 --- a/virtinst/capabilities.py +++ b/virtinst/capabilities.py @@ -165,11 +165,10 @@ class _CapsInfo(object): Container object to hold the results of guest_lookup, so users don't need to juggle two objects """ - def __init__(self, conn, guest, domain, requested_machine): + def __init__(self, conn, guest, domain): self.conn = conn self.guest = guest self.domain = domain - self._requested_machine = requested_machine self.hypervisor_type = self.domain.hypervisor_type self.os_type = self.guest.os_type @@ -179,42 +178,6 @@ class _CapsInfo(object): self.emulator = self.domain.emulator or self.guest.emulator self.machines = self.guest.all_machine_names(self.domain) - def get_recommended_machine(self): - """ - Return the recommended machine type. - - However, if the user already requested an explicit machine type, - via guest_lookup, return that instead. - """ - if self._requested_machine: - return self._requested_machine - - # For any other HV just let libvirt get us the default, these - # are the only ones we've tested. - if (not self.conn.is_test() and - not self.conn.is_qemu() and - not self.conn.is_xen()): - return None - - if self.conn.is_xen() and len(self.machines): - return self.machines[0] - - if (self.arch in ["ppc64", "ppc64le"] and - "pseries" in self.machines): - return "pseries" - - if self.arch in ["armv7l", "aarch64"]: - if "virt" in self.machines: - return "virt" - if "vexpress-a15" in self.machines: - return "vexpress-a15" - - if self.arch in ["s390x"]: - if "s390-ccw-virtio" in self.machines: - return "s390-ccw-virtio" - - return None - class Capabilities(XMLBuilder): def __init__(self, *args, **kwargs): @@ -366,7 +329,7 @@ class Capabilities(XMLBuilder): {'domain': typ, 'virttype': guest.os_type, 'arch': guest.arch, 'machine': machinestr}) - capsinfo = _CapsInfo(self.conn, guest, domain, machine) + capsinfo = _CapsInfo(self.conn, guest, domain) return capsinfo def build_virtinst_guest(self, capsinfo): @@ -381,7 +344,7 @@ class Capabilities(XMLBuilder): gobj.os.loader = capsinfo.loader gobj.emulator = capsinfo.emulator - gobj.os.machine = capsinfo.get_recommended_machine() + gobj.os.machine = Guest.get_recommended_machine(capsinfo) gobj.capsinfo = capsinfo diff --git a/virtinst/cli.py b/virtinst/cli.py index 8920fa17..161f84b1 100644 --- a/virtinst/cli.py +++ b/virtinst/cli.py @@ -1659,6 +1659,7 @@ ParserBoot.add_arg(None, "bootloader", cb=ParserBoot.set_bootloader_cb) ParserBoot.add_arg(None, "domain_type", cb=ParserBoot.set_domain_type_cb) ParserBoot.add_arg("os_type", "os_type") ParserBoot.add_arg(None, "emulator", cb=ParserBoot.set_emulator_cb) +ParserBoot.add_arg("machine", "machine") ParserBoot.add_arg(None, "uefi", cb=ParserBoot.set_uefi_cb, is_novalue=True) ParserBoot.add_arg("useserial", "useserial", is_onoff=True) @@ -1675,7 +1676,6 @@ ParserBoot.add_arg("nvram_template", "nvram_template") ParserBoot.add_arg("kernel_args", "kernel_args", aliases=["extra_args"], can_comma=True) ParserBoot.add_arg("init", "init") -ParserBoot.add_arg("machine", "machine") ParserBoot.add_arg("initargs", "initargs", cb=ParserBoot.set_initargs_cb) ParserBoot.add_arg("smbios_mode", "smbios_mode") diff --git a/virtinst/domain/features.py b/virtinst/domain/features.py index eefaf4df..1ea2be45 100644 --- a/virtinst/domain/features.py +++ b/virtinst/domain/features.py @@ -59,17 +59,18 @@ class DomainFeatures(XMLBuilder): if not guest.os.is_hvm(): return + capsinfo = guest.lookup_capsinfo() if self._prop_is_unset("acpi"): - self.acpi = guest.capsinfo.guest.supports_acpi() + self.acpi = capsinfo.guest.supports_acpi() if self._prop_is_unset("apic"): - self.apic = guest.capsinfo.guest.supports_apic() + self.apic = capsinfo.guest.supports_apic() if self._prop_is_unset("pae"): if (guest.os.is_hvm() and guest.type == "xen" and guest.os.arch == "x86_64"): self.pae = True else: - self.pae = guest.capsinfo.guest.supports_pae() + self.pae = capsinfo.guest.supports_pae() if (guest.hyperv_supported() and self.conn.check_support(self.conn.SUPPORT_CONN_HYPERV_VAPIC)): diff --git a/virtinst/guest.py b/virtinst/guest.py index d1be0bae..5a0c672f 100644 --- a/virtinst/guest.py +++ b/virtinst/guest.py @@ -134,9 +134,6 @@ class Guest(XMLBuilder): self.__osinfo = None - # This is set via Capabilities.build_virtinst_guest - self.capsinfo = None - ###################### # Property accessors # @@ -280,6 +277,7 @@ class Guest(XMLBuilder): Configure UEFI for the VM, but only if libvirt is advertising a known UEFI binary path. """ + self.set_capabilities_defaults() domcaps = DomainCapabilities.build_from_guest(self) if not domcaps.supports_uefi_xml(): @@ -464,13 +462,73 @@ class Guest(XMLBuilder): dev.device = "/dev/urandom" self.add_device(dev) + def lookup_capsinfo(self): + return self.conn.caps.guest_lookup( + os_type=self.os.os_type, + arch=self.os.arch, + typ=self.type, + machine=self.os.machine) + + def set_capabilities_defaults(self): + capsinfo = self.lookup_capsinfo() + wants_default_type = not self.type and not self.os.os_type + + self.type = capsinfo.hypervisor_type + self.os.os_type = capsinfo.os_type + self.os.arch = capsinfo.arch + if not self.os.loader: + self.os.loader = capsinfo.loader + if (not self.emulator and + not self.os.is_xenpv() and + not self.type == "vz"): + self.emulator = capsinfo.emulator + if not self.os.machine: + self.os.machine = Guest.get_recommended_machine(capsinfo) + + if (wants_default_type and + self.conn.is_qemu() and + self.os.is_x86() and + not self.type == "kvm"): + logging.warning("KVM acceleration not available, using '%s'", + self.type) + + @staticmethod + def get_recommended_machine(capsinfo): + """ + Return the recommended machine type for the passed capsinfo + """ + # For any other HV just let libvirt get us the default, these + # are the only ones we've tested. + if (not capsinfo.conn.is_test() and + not capsinfo.conn.is_qemu() and + not capsinfo.conn.is_xen()): + return None + + if capsinfo.conn.is_xen() and len(capsinfo.machines): + return capsinfo.machines[0] + + if (capsinfo.arch in ["ppc64", "ppc64le"] and + "pseries" in capsinfo.machines): + return "pseries" + + if capsinfo.arch in ["armv7l", "aarch64"]: + if "virt" in capsinfo.machines: + return "virt" + if "vexpress-a15" in capsinfo.machines: + return "vexpress-a15" + + if capsinfo.arch in ["s390x"]: + if "s390-ccw-virtio" in capsinfo.machines: + return "s390-ccw-virtio" + + return None + def set_defaults(self, _guest): if not self.uuid: self.uuid = util.generate_uuid(self.conn) if not self.vcpus: self.vcpus = 1 - if self.os.is_xenpv() or self.type == "vz": - self.emulator = None + self.set_capabilities_defaults() self._add_default_graphics() self._add_default_video_device() |