From 7986ffa80b01b699d75bd9d1724e9abe6f80de12 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Fri, 21 Jan 2022 12:51:57 -0500 Subject: [PATCH] nodedev: Move the CLI string format lookup to cli.py This address string decomposing is strictly and virt-* cli feature. Move it to cli.py to make that explicit Signed-off-by: Cole Robinson --- virtinst/cli.py | 99 ++++++++++++++++++++++++++++++++++++++++++++- virtinst/nodedev.py | 97 -------------------------------------------- 2 files changed, 97 insertions(+), 99 deletions(-) diff --git a/virtinst/cli.py b/virtinst/cli.py index ecac12b9..752f9df4 100644 --- a/virtinst/cli.py +++ b/virtinst/cli.py @@ -4558,6 +4558,101 @@ class ParserSound(VirtCLIParser): # --hostdev parsing # ##################### +def _AddressStringToHostdev(conn, addrstr): + from .devices import DeviceHostdev + hostdev = DeviceHostdev(conn) + + try: + # Determine addrstr type + if addrstr.count(":") in [1, 2] and "." in addrstr: + addrstr, func = addrstr.split(".", 1) + addrstr, slot = addrstr.rsplit(":", 1) + domain = "0" + if ":" in addrstr: + domain, bus = addrstr.split(":", 1) + else: + bus = addrstr + + hostdev.type = "pci" + hostdev.domain = "0x%.4X" % int(domain, 16) + hostdev.function = "0x%.2X" % int(func, 16) + hostdev.slot = "0x%.2X" % int(slot, 16) + hostdev.bus = "0x%.2X" % int(bus, 16) + + elif ":" in addrstr: + vendor, product = addrstr.split(":") + + hostdev.type = "usb" + hostdev.vendor = "0x%.4X" % int(vendor, 16) + hostdev.product = "0x%.4X" % int(product, 16) + + elif "." in addrstr: + bus, device = addrstr.split(".", 1) + + hostdev.type = "usb" + hostdev.bus = bus + hostdev.device = device + else: + raise RuntimeError( + "Unknown hostdev address string format '%s'" % addrstr) + except Exception: + log.debug("Error parsing node device string.", exc_info=True) + raise + + return hostdev + + +def _AddressStringToNodedev(conn, addrstr): + hostdev = _AddressStringToHostdev(conn, addrstr) + + # Iterate over node devices and compare + count = 0 + nodedev = None + + for xmlobj in conn.fetch_all_nodedevs(): + if xmlobj.compare_to_hostdev(hostdev): + nodedev = xmlobj + count += 1 + + if count == 1: + return nodedev + elif count > 1: + raise ValueError(_("%s corresponds to multiple node devices") % + addrstr) + elif count < 1: + raise ValueError(_("Did not find a matching node device for '%s'") % + addrstr) + + +def _lookupNodedevFromString(conn, idstring): + """ + Convert the passed libvirt node device name to a NodeDevice + instance, with proper error reporting. If the name is name is not + found, we will attempt to parse the name as would be passed to + devAddressToNodeDev + + :param conn: libvirt.virConnect instance to perform the lookup on + :param idstring: libvirt node device name to lookup, or address + of the form: + - bus.addr (ex. 001.003 for a usb device) + - vendor:product (ex. 0x1234:0x5678 for a usb device + - (domain:)bus:slot.func (ex. 00:10.0 for a pci device) + + :returns: NodeDevice instance + """ + # First try and see if this is a libvirt nodedev name + nodedev = NodeDevice.lookupNodedevByName(conn, idstring) + if nodedev: + return nodedev + + try: + return _AddressStringToNodedev(conn, idstring) + except Exception: + log.debug("Error looking up nodedev from idstring=%s", + idstring, exc_info=True) + raise + + class ParserHostdev(VirtCLIParser): cli_arg_name = "hostdev" guest_propname = "devices.hostdev" @@ -4578,11 +4673,11 @@ class ParserHostdev(VirtCLIParser): inst.mode = "capabilities" inst.storage_block = val else: - val = NodeDevice.lookupNodedevFromString(inst.conn, val) + val = _lookupNodedevFromString(inst.conn, val) inst.set_from_nodedev(val) def name_lookup_cb(self, inst, val, virtarg): - nodedev = NodeDevice.lookupNodedevFromString(inst.conn, val) + nodedev = _lookupNodedevFromString(inst.conn, val) return nodedev.compare_to_hostdev(inst) @classmethod diff --git a/virtinst/nodedev.py b/virtinst/nodedev.py index 6d89adc7..c90b058e 100644 --- a/virtinst/nodedev.py +++ b/virtinst/nodedev.py @@ -7,7 +7,6 @@ import os import uuid -from .logger import log from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty @@ -68,36 +67,6 @@ class NodeDevice(XMLBuilder): return nodedev - @staticmethod - def lookupNodedevFromString(conn, idstring): - """ - Convert the passed libvirt node device name to a NodeDevice - instance, with proper error reporting. If the name is name is not - found, we will attempt to parse the name as would be passed to - devAddressToNodeDev - - :param conn: libvirt.virConnect instance to perform the lookup on - :param idstring: libvirt node device name to lookup, or address - of the form: - - bus.addr (ex. 001.003 for a usb device) - - vendor:product (ex. 0x1234:0x5678 for a usb device - - (domain:)bus:slot.func (ex. 00:10.0 for a pci device) - - :returns: NodeDevice instance - """ - # First try and see if this is a libvirt nodedev name - nodedev = NodeDevice.lookupNodedevByName(conn, idstring) - if nodedev: - return nodedev - - try: - return _AddressStringToNodedev(conn, idstring) - except Exception: - log.debug("Error looking up nodedev from idstring=%s", - idstring, exc_info=True) - raise - - XML_NAME = "device" # Libvirt can generate bogus 'system' XML: @@ -213,69 +182,3 @@ class NodeDevice(XMLBuilder): # type='mdev' options type_id = XMLProperty("./capability/type/@id") uuid = XMLProperty("./capability/uuid") - - -def _AddressStringToHostdev(conn, addrstr): - from .devices import DeviceHostdev - hostdev = DeviceHostdev(conn) - - try: - # Determine addrstr type - if addrstr.count(":") in [1, 2] and "." in addrstr: - addrstr, func = addrstr.split(".", 1) - addrstr, slot = addrstr.rsplit(":", 1) - domain = "0" - if ":" in addrstr: - domain, bus = addrstr.split(":", 1) - else: - bus = addrstr - - hostdev.type = "pci" - hostdev.domain = "0x%.4X" % int(domain, 16) - hostdev.function = "0x%.2X" % int(func, 16) - hostdev.slot = "0x%.2X" % int(slot, 16) - hostdev.bus = "0x%.2X" % int(bus, 16) - - elif ":" in addrstr: - vendor, product = addrstr.split(":") - - hostdev.type = "usb" - hostdev.vendor = "0x%.4X" % int(vendor, 16) - hostdev.product = "0x%.4X" % int(product, 16) - - elif "." in addrstr: - bus, device = addrstr.split(".", 1) - - hostdev.type = "usb" - hostdev.bus = bus - hostdev.device = device - else: - raise RuntimeError( - "Unknown hostdev address string format '%s'" % addrstr) - except Exception: - log.debug("Error parsing node device string.", exc_info=True) - raise - - return hostdev - - -def _AddressStringToNodedev(conn, addrstr): - hostdev = _AddressStringToHostdev(conn, addrstr) - - # Iterate over node devices and compare - count = 0 - nodedev = None - - for xmlobj in conn.fetch_all_nodedevs(): - if xmlobj.compare_to_hostdev(hostdev): - nodedev = xmlobj - count += 1 - - if count == 1: - return nodedev - elif count > 1: - raise ValueError(_("%s corresponds to multiple node devices") % - addrstr) - elif count < 1: - raise ValueError(_("Did not find a matching node device for '%s'") % - addrstr)