cli: --os-variant: add explicit suboptions

This adds the following --os-variant suboptions

* name=, short-id=
* id=
* detect=on|off

Functionally this does not change behavior, just adds explicit
sub options for behavior we already support

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-09-14 19:05:58 -04:00
parent 67703ec7a5
commit 17f47a44c5
8 changed files with 95 additions and 69 deletions

View File

@ -969,20 +969,33 @@ GUEST OS OPTIONS
``--os-variant``, ``--osinfo``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Syntax:** ``--os-variant`` OS_VARIANT
**Syntax:** ``--os-variant`` [OS_VARIANT|OPT1=VAL1,...]
Optimize the guest configuration for a specific operating system (ex.
'fedora29', 'rhel7', 'win10'). While not required, specifying this
options is HIGHLY RECOMMENDED, as it can greatly increase performance
by specifying virtio among other guest tweaks.
By default, virt-install will attempt to auto detect this value from
the install media (currently only supported for URL installs). Autodetection
can be disabled with the special value 'none'. Autodetection can be
forced with the special value 'auto'.
The simplest usage is ``--os-variant OS-NAME``, for example
``--os-variant fedora32``. ``--os-variant`` supports explicit suboption
syntax as well:
``name=``, ``short-id=``
The OS name/short-id from libosinfo. Examples: ``fedora32``, ``win10``
``id=``
The full URL style libosinfo ID. For example, ``name=win10`` is
the same as ``id=http://microsoft.com/win/10``
``detect=on|off``
Whether virt-install should attempt OS detection from the specified
install media. Detection is presently only attempted for URL and
CDROM installs, and is not 100% reliable.
By default, virt-install will use ``--os-variant detect=on``.
Use the command "osinfo-query os" to get the list of the accepted OS
variants.
variant names.

View File

@ -194,6 +194,8 @@ GUEST OS OPTIONS
Use the command "osinfo-query os" to get the list of the accepted OS
variants.
See virt-install(1) documentation for more details about ``--os-variant``
XML OPTIONS
===========

View File

@ -1,14 +1,9 @@
<domain type="test">
<name>rhel6.0</name>
<name>vm1</name>
<uuid>00000000-1111-2222-3333-444444444444</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://redhat.com/rhel/6.0"/>
</libosinfo:libosinfo>
</metadata>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>2</vcpu>
<vcpu>1</vcpu>
<os>
<type arch="i686">hvm</type>
<kernel>/VIRTINST-TESTSUITE/vmlinuz</kernel>
@ -44,16 +39,11 @@
</devices>
</domain>
<domain type="test">
<name>rhel6.0</name>
<name>vm1</name>
<uuid>00000000-1111-2222-3333-444444444444</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://redhat.com/rhel/6.0"/>
</libosinfo:libosinfo>
</metadata>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>2</vcpu>
<vcpu>1</vcpu>
<os>
<type arch="i686">hvm</type>
<boot dev="hd"/>

View File

@ -1,9 +1,9 @@
<domain type="kvm">
<name>fedora26</name>
<name>fedora27</name>
<uuid>00000000-1111-2222-3333-444444444444</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://fedoraproject.org/fedora/26"/>
<libosinfo:os id="http://fedoraproject.org/fedora/27"/>
</libosinfo:libosinfo>
</metadata>
<memory>65536</memory>
@ -60,11 +60,11 @@
</devices>
</domain>
<domain type="kvm">
<name>fedora26</name>
<name>fedora27</name>
<uuid>00000000-1111-2222-3333-444444444444</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://fedoraproject.org/fedora/26"/>
<libosinfo:os id="http://fedoraproject.org/fedora/27"/>
</libosinfo:libosinfo>
</metadata>
<memory>65536</memory>

View File

@ -861,15 +861,14 @@ c.add_valid("--location 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
c.add_valid("--paravirt --location %(TREEDIR)s") # Paravirt location
c.add_valid("--paravirt --location %(TREEDIR)s --os-variant none") # Paravirt location with --os-variant none
c.add_valid("--location %(TREEDIR)s --os-variant fedora12") # URL install with manual os-variant
c.add_valid("--cdrom %(EXISTIMG2)s --os-variant win2k3") # HVM windows install with disk
c.add_valid("--cdrom %(EXISTIMG2)s --os-variant win2k3 --print-step 2") # HVM windows install, print 3rd stage XML
c.add_valid("--pxe --autostart") # --autostart flag
c.add_compare("--cdrom http://example.com/path/to/some.iso", "cdrom-url")
c.add_compare("--pxe --print-step all", "simple-pxe") # Diskless PXE install
c.add_compare("--location ftp://example.com", "fake-ftp") # fake ftp:// install using urlfetcher.py mocking
c.add_compare("--location https://foobar.com", "fake-http") # fake https:// install using urlfetcher.py mocking
c.add_compare("--pxe --print-step all --os-variant none", "simple-pxe") # Diskless PXE install
c.add_compare("--location ftp://example.com --os-variant auto", "fake-ftp") # fake ftp:// install using urlfetcher.py mocking
c.add_compare("--location https://foobar.com --os-variant detect=no", "fake-http") # fake https:// install using urlfetcher.py mocking, but also hit --os-variant detect=no
c.add_compare("--connect %(URI-KVM)s --install fedora26", "osinfo-url") # getting URL from osinfo
c.add_invalid("--pxe --virt-type bogus") # Bogus virt-type
c.add_invalid("--pxe --arch bogus") # Bogus arch
@ -884,7 +883,7 @@ c.add_invalid("--arch i686 --install fedora26", grep="does not have a URL locati
c.add_invalid("-c foo --cdrom bar", grep="Cannot specify both -c") # check for ambiguous -c and --cdrom collision
c.add_invalid("-c qemu:///system", grep="looks like a libvirt URI") # error for the ambiguous -c vs --connect
c.add_invalid("--location /", grep="Error validating install location") # detect_distro failure
c.add_invalid("--os-variant foo://bar", grep="Unknown libosinfo ID") # bad full id
c.add_invalid("--os-variant id=foo://bar", grep="Unknown libosinfo ID") # bad full id
c.add_invalid("--location http://testsuitefail.com", grep="installable distribution") # will trigger a particular mock failure
@ -897,8 +896,8 @@ c.add_valid("--paravirt --import") # PV Import install
c.add_valid("--paravirt --print-xml 1") # print single XML, implied import install
c.add_valid("--hvm --import --wait 0", grep="Treating --wait 0 as --noautoconsole") # --wait 0 is the same as --noautoconsole
c.add_compare("-c %(EXISTIMG2)s --osinfo win2k3 --vcpus cores=4 --controller usb,model=none", "w2k3-cdrom") # HVM windows install with disk
c.add_compare("--connect %(URI-KVM)s --install fedora26 --disk size=20", "osinfo-url-with-disk") # filling in defaults, but with disk specified
c.add_compare("--connect %(URI-KVM)s --pxe --os-variant debianbuster --disk none", "osinfo-multiple-short-id", prerun_check=lambda: not OSDB.lookup_os("debianbuster")) # test plumbing for multiple short ids
c.add_compare("--connect %(URI-KVM)s --install fedora26 --os-variant fedora27 --disk size=20", "osinfo-url-with-disk") # filling in defaults, but with disk specified, and making sure we don't overwrite --os-variant
c.add_compare("--connect %(URI-KVM)s --pxe --os-variant short-id=debianbuster --disk none", "osinfo-multiple-short-id", prerun_check=lambda: not OSDB.lookup_os("debianbuster")) # test plumbing for multiple short ids
c.add_invalid("--hvm --import --wait 2", grep="exceeded specified time limit") # --wait positive number, but test suite hack
c.add_invalid("--hvm --import --wait -1", grep="exceeded specified time limit") # --wait -1, but test suite hack
c.add_invalid("--hvm --import --wait", grep="exceeded specified time limit") # --wait aka --wait -1, but test suite hack
@ -979,7 +978,7 @@ c.add_compare("--os-variant fedora-unknown --file %(EXISTIMG1)s --location %(TRE
c.add_compare("--test-media-detection %(TREEDIR)s --arch x86_64 --hvm", "test-url-detection") # --test-media-detection
c.add_compare("--os-variant http://fedoraproject.org/fedora/20 --disk %(EXISTIMG1)s,device=floppy --disk %(NEWIMG1)s,size=.01,format=vmdk --location %(TREEDIR)s --extra-args console=ttyS0 --quiet", "quiet-url", prerun_check=has_old_osinfo) # Quiet URL install should make no noise
c.add_compare("--cdrom %(EXISTIMG2)s --file %(EXISTIMG1)s --os-variant win2k3 --sound --controller usb", "kvm-win2k3-cdrom") # HVM windows install with disk
c.add_compare("--os-variant ubuntusaucy --nodisks --boot cdrom --virt-type qemu --cpu Penryn --input tablet --boot uefi --graphics vnc", "qemu-plain") # plain qemu
c.add_compare("--os-variant name=ubuntusaucy --nodisks --boot cdrom --virt-type qemu --cpu Penryn --input tablet --boot uefi --graphics vnc", "qemu-plain") # plain qemu
c.add_compare("--os-variant fedora20 --nodisks --boot network --graphics default --arch i686 --rng none", "qemu-32-on-64", prerun_check=has_old_osinfo) # 32 on 64
# ppc64 tests

View File

@ -480,7 +480,8 @@ def get_domain_and_guest(conn, domstr):
def _get_completer_parsers():
return VIRT_PARSERS + [ParserCheck, ParserLocation,
ParserUnattended, ParserInstall, ParserCloudInit, ParserXML]
ParserUnattended, ParserInstall, ParserCloudInit, ParserXML,
ParserOSVariant]
def _virtparser_completer(prefix, **kwargs):
@ -1790,42 +1791,66 @@ def parse_location(optstr):
########################
class OSVariantData(object):
def __init__(self, os_variant):
self._rawstr = os_variant
self._default_auto = True
def __init__(self):
self._name = None
if not self._rawstr:
self._id = None
self._detect = False
def set_compat_str(self, rawstr):
if rawstr is None or rawstr == "auto":
# The default behavior
self._detect = True
return
self._default_auto = False
if self.is_none or self.is_auto:
return
if "://" in self._rawstr:
osobj = OSDB.lookup_os_by_full_id(self._rawstr, raise_error=True)
if rawstr == "none":
self._name = "generic"
elif "://" in rawstr:
self._id = rawstr
else:
osobj = OSDB.lookup_os(self._rawstr, raise_error=True)
self._name = osobj.name
self._name = rawstr
def set_installdata_name(self, name):
# osname set via --install os=X, but if --os-variant also
# explicitly set, we don't want to overwrite it
if self._default_auto:
self._default_auto = False
self._name = name
def validate(self):
osobj = None
if self._id:
osobj = OSDB.lookup_os_by_full_id(self._id, raise_error=True)
elif self._name:
osobj = OSDB.lookup_os(self._name, raise_error=True)
if osobj:
self._name = osobj.name
@property
def is_none(self):
return self._rawstr == "none"
@property
def is_auto(self):
return self._rawstr == "auto" or self._default_auto
@property
def name(self):
def is_generic_requested(self):
return self._detect is False or self._name == "generic"
def is_detect(self):
return self._detect
def get_name(self):
return self._name
class ParserOSVariant(VirtCLIParser):
cli_arg_name = "os-variant"
supports_clearxml = False
@classmethod
def _init_class(cls, **kwargs):
VirtCLIParser._init_class(**kwargs)
cls.add_arg("name", "_name")
cls.add_arg("short-id", "_name")
cls.add_arg("id", "_id")
cls.add_arg("detect", "_detect", is_onoff=True)
def parse(self, inst):
if "=" not in str(self.optstr):
inst.set_compat_str(self.optstr)
return
return super().parse(inst)
def parse_os_variant(optstr):
return OSVariantData(optstr)
data = OSVariantData()
parser = ParserOSVariant(optstr)
parser.parse(data)
data.validate()
return data
###########################

View File

@ -361,8 +361,7 @@ def show_guest_warnings(options, guest, osdata):
# Limit it to hvm x86 guests which presently our defaults
# only really matter for
if (guest.osinfo.name == "generic" and
not osdata.is_none and
not osdata.name == "generic" and
not osdata.is_generic_requested() and
guest.os.is_x86() and guest.os.is_hvm()):
log.warning(_("No operating system detected, VM performance may "
"suffer. Specify an OS with --os-variant for optimal results."))
@ -535,12 +534,12 @@ def installer_detect_distro(guest, installer, osdata):
# OS name has to be set firstly whenever --os-variant is passed,
# otherwise it won't be respected when the installer creates the
# Distro Store.
if osdata.name:
guest.set_os_name(osdata.name)
if osdata.get_name():
guest.set_os_name(osdata.get_name())
# This also validates the install location
autodistro = installer.detect_distro(guest)
if osdata.is_auto and autodistro:
if osdata.is_detect() and autodistro:
guest.set_os_name(autodistro)
except ValueError as e:
fail(_("Error validating install location: %s") % str(e))
@ -566,9 +565,7 @@ def _build_options_guest(conn, options):
def build_guest_instance(conn, options):
installdata = cli.parse_install(options.install)
osdata = cli.parse_os_variant(options.os_variant)
if installdata.os:
osdata.set_installdata_name(installdata.os)
osdata = cli.parse_os_variant(options.os_variant or installdata.os)
if options.reinstall:
dummy1, guest, dummy2 = cli.get_domain_and_guest(conn, options.reinstall)

View File

@ -51,8 +51,8 @@ def set_os_variant(options, guest):
return
osdata = cli.parse_os_variant(options.os_variant)
if osdata.name:
guest.set_os_name(osdata.name)
if osdata.get_name():
guest.set_os_name(osdata.get_name())
def defined_xml_is_unchanged(conn, domain, original_xml):