summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/clitest.py2
-rw-r--r--virtManager/connection.py10
-rw-r--r--virtinst/connection.py25
-rw-r--r--virtinst/support.py167
4 files changed, 97 insertions, 107 deletions
diff --git a/tests/clitest.py b/tests/clitest.py
index 01f76b8a..6b3c4dc0 100644
--- a/tests/clitest.py
+++ b/tests/clitest.py
@@ -127,7 +127,7 @@ class SkipChecks:
msg = check()
skip = bool(msg)
else:
- skip = not conn._check_version(check) # pylint: disable=protected-access
+ skip = not conn.support._check_version(check) # pylint: disable=protected-access
msg = "Skipping check due to version < %s" % check
if skip:
diff --git a/virtManager/connection.py b/virtManager/connection.py
index 091679ac..dbff756f 100644
--- a/virtManager/connection.py
+++ b/virtManager/connection.py
@@ -426,11 +426,11 @@ class vmmConnection(vmmGObject):
# API support helpers #
#######################
- for _supportname in [_supportname for _supportname in
- dir(virtinst.VirtinstConnection) if
- _supportname.startswith("SUPPORT_")]:
- locals()[_supportname] = getattr(virtinst.VirtinstConnection,
- _supportname)
+ def __getattr__(self, attr):
+ if attr.startswith("SUPPORT_"):
+ return getattr(self._backend.support, attr.split("_", 1)[1].lower())
+ raise AttributeError
+
def check_support(self, *args):
# pylint: disable=no-value-for-parameter
return self._backend.check_support(*args)
diff --git a/virtinst/connection.py b/virtinst/connection.py
index 558b6142..57d74ffa 100644
--- a/virtinst/connection.py
+++ b/virtinst/connection.py
@@ -57,7 +57,6 @@ class VirtinstConnection(object):
self._uriobj = URI(self._uri)
self._caps = None
- self._support_cache = {}
self._fetch_cache = {}
# These let virt-manager register a callback which provides its
@@ -68,7 +67,7 @@ class VirtinstConnection(object):
self.cb_fetch_all_nodedevs = None
self.cb_cache_new_pool = None
- self.support = support.SupportCache()
+ self.support = support.SupportCache(weakref.proxy(self))
##############
@@ -79,6 +78,9 @@ class VirtinstConnection(object):
if attr in self.__dict__:
return self.__dict__[attr]
+ if attr.startswith("SUPPORT_"):
+ return getattr(self.support, attr.split("_", 1)[1].lower())
+
# Proxy virConnect API calls
libvirtconn = self.__dict__.get("_libvirtconn")
return getattr(libvirtconn, attr)
@@ -380,30 +382,13 @@ class VirtinstConnection(object):
# Support check helpers #
#########################
- for _supportname in [_supportname for _supportname in
- dir(support.SupportCache) if
- _supportname.startswith("SUPPORT_")]:
- locals()[_supportname] = getattr(support.SupportCache, _supportname)
-
-
def check_support(self, features, data=None):
- def _check_support(key):
- if key not in self._support_cache:
- self._support_cache[key] = self.support.check_support(
- self, key, data or self)
- return self._support_cache[key]
-
for f in util.listify(features):
# 'and' condition over the feature list
- if not _check_support(f):
+ if not f(data):
return False
return True
- def _check_version(self, version):
- # Entry point for the test suite to do simple version checks,
- # actual code should only use check_support
- return self.support.check_version(self, version)
-
def support_remote_url_install(self):
if self._magic_uri:
return False
diff --git a/virtinst/support.py b/virtinst/support.py
index 96f0dfac..48a75ac9 100644
--- a/virtinst/support.py
+++ b/virtinst/support.py
@@ -162,16 +162,31 @@ class _SupportCheck(object):
"support checks for libvirt versions less than 0.7.3, "
"since required APIs were not available. ver=%s" % vstr)
- def check_support(self, conn, data):
+ def __call__(self, virtconn, data=None):
+ """
+ Attempt to determine if a specific libvirt feature is support given
+ the passed connection.
+
+ :param virtconn: VirtinstConnection to check feature on
+ :param feature: Feature type to check support for
+ :type feature: One of the SUPPORT_* flags
+ :param data: Option libvirt object to use in feature checking
+ :type data: Could be virDomain, virNetwork, virStoragePool, hv name, etc
+
+ :returns: True if feature is supported, False otherwise
+ """
+ if "VirtinstConnection" in repr(data):
+ data = data.get_conn_for_api_arg()
+
ret = _check_function(self.function, self.flag, self.run_args, data)
if ret is not None:
return ret
# Do this after the function check, since there's an ordering issue
# with VirtinstConnection
- hv_type = conn.get_uri_driver()
- actual_libvirt_version = conn.daemon_version()
- actual_hv_version = conn.conn_version()
+ hv_type = virtconn.get_uri_driver()
+ actual_libvirt_version = virtconn.daemon_version()
+ actual_hv_version = virtconn.conn_version()
# Check that local libvirt version is sufficient
v = _version_str_to_int(self.version)
@@ -197,145 +212,135 @@ class _SupportCheck(object):
return True
-_SUPPORT_ID = 0
-_SUPPORT_OBJS = []
+def _make(*args, **kwargs):
+ """
+ Create a _SupportCheck from the passed args, then turn it into a
+ SupportCache method which captures and caches the returned support
+ value in self._cache
+ """
+ # pylint: disable=protected-access
+ support_obj = _SupportCheck(*args, **kwargs)
+ def cache_wrapper(self, data=None):
+ if support_obj not in self._cache:
+ support_ret = support_obj(self._virtconn, data or self._virtconn)
+ self._cache[support_obj] = support_ret
+ return self._cache[support_obj]
-def _make(*args, **kwargs):
- global _SUPPORT_ID
- _SUPPORT_ID += 1
- obj = _SupportCheck(*args, **kwargs)
- _SUPPORT_OBJS.append(obj)
- return _SUPPORT_ID
+ return cache_wrapper
class SupportCache:
"""
- Class containing all support checks and access APIs
+ Class containing all support checks and access APIs, and support for
+ caching returned results
"""
+ def __init__(self, virtconn):
+ self._cache = {}
+ self._virtconn = virtconn
- SUPPORT_CONN_STORAGE = _make(
+ conn_storage = _make(
function="virConnect.listStoragePools", run_args=())
- SUPPORT_CONN_NODEDEV = _make(
+ conn_nodedev = _make(
function="virConnect.listDevices", run_args=(None, 0))
- SUPPORT_CONN_NETWORK = _make(function="virConnect.listNetworks", run_args=())
- SUPPORT_CONN_INTERFACE = _make(
+ conn_network = _make(function="virConnect.listNetworks", run_args=())
+ conn_interface = _make(
function="virConnect.listInterfaces", run_args=())
- SUPPORT_CONN_STREAM = _make(function="virConnect.newStream", run_args=(0,))
- SUPPORT_CONN_LISTALLDOMAINS = _make(
+ conn_stream = _make(function="virConnect.newStream", run_args=(0,))
+ conn_listalldomains = _make(
function="virConnect.listAllDomains", run_args=())
- SUPPORT_CONN_LISTALLNETWORKS = _make(
+ conn_listallnetworks = _make(
function="virConnect.listAllNetworks", run_args=())
- SUPPORT_CONN_LISTALLSTORAGEPOOLS = _make(
+ conn_listallstoragepools = _make(
function="virConnect.listAllStoragePools", run_args=())
- SUPPORT_CONN_LISTALLINTERFACES = _make(
+ conn_listallinterfaces = _make(
function="virConnect.listAllInterfaces", run_args=())
- SUPPORT_CONN_LISTALLDEVICES = _make(
+ conn_listalldevices = _make(
function="virConnect.listAllDevices", run_args=())
- SUPPORT_CONN_WORKING_XEN_EVENTS = _make(hv_version={"xen": "4.0.0", "all": 0})
+ conn_working_xen_events = _make(hv_version={"xen": "4.0.0", "all": 0})
# This is an arbitrary check to say whether it's a good idea to
# default to qcow2. It might be fine for xen or qemu older than the versions
# here, but until someone tests things I'm going to be a bit conservative.
- SUPPORT_CONN_DEFAULT_QCOW2 = _make(hv_version={"qemu": "1.2.0", "test": 0})
- SUPPORT_CONN_AUTOSOCKET = _make(hv_libvirt_version={"qemu": "1.0.6"})
- SUPPORT_CONN_PM_DISABLE = _make(hv_version={"qemu": "1.2.0", "test": 0})
- SUPPORT_CONN_QCOW2_LAZY_REFCOUNTS = _make(
+ conn_default_qcow2 = _make(hv_version={"qemu": "1.2.0", "test": 0})
+ conn_autosocket = _make(hv_libvirt_version={"qemu": "1.0.6"})
+ conn_pm_disable = _make(hv_version={"qemu": "1.2.0", "test": 0})
+ conn_qcow2_lazy_refcounts = _make(
version="1.1.0", hv_version={"qemu": "1.2.0", "test": 0})
- SUPPORT_CONN_HYPERV_VAPIC = _make(
+ conn_hyperv_vapic = _make(
version="1.1.0", hv_version={"qemu": "1.1.0", "test": 0})
- SUPPORT_CONN_HYPERV_CLOCK = _make(
+ conn_hyperv_clock = _make(
version="1.2.2", hv_version={"qemu": "1.5.3", "test": 0})
- SUPPORT_CONN_DOMAIN_CAPABILITIES = _make(
+ conn_domain_capabilities = _make(
function="virConnect.getDomainCapabilities",
run_args=(None, None, None, None))
- SUPPORT_CONN_DOMAIN_RESET = _make(version="0.9.7", hv_version={"qemu": 0})
- SUPPORT_CONN_VMPORT = _make(
+ conn_domain_reset = _make(version="0.9.7", hv_version={"qemu": 0})
+ conn_vmport = _make(
version="1.2.16", hv_version={"qemu": "2.2.0", "test": 0})
- SUPPORT_CONN_MEM_STATS_PERIOD = _make(
+ conn_mem_stats_period = _make(
function="virDomain.setMemoryStatsPeriod",
version="1.1.1", hv_version={"qemu": 0})
# spice GL is actually enabled with libvirt 1.3.3, but 3.1.0 is the
# first version that sorts out the qemu:///system + cgroup issues
- SUPPORT_CONN_SPICE_GL = _make(version="3.1.0",
+ conn_spice_gl = _make(version="3.1.0",
hv_version={"qemu": "2.6.0", "test": 0})
- SUPPORT_CONN_SPICE_RENDERNODE = _make(version="3.1.0",
+ conn_spice_rendernode = _make(version="3.1.0",
hv_version={"qemu": "2.9.0", "test": 0})
- SUPPORT_CONN_VIDEO_VIRTIO_ACCEL3D = _make(version="1.3.0",
+ conn_video_virtio_accel3d = _make(version="1.3.0",
hv_version={"qemu": "2.5.0", "test": 0})
- SUPPORT_CONN_GRAPHICS_LISTEN_NONE = _make(version="2.0.0")
- SUPPORT_CONN_RNG_URANDOM = _make(version="1.3.4")
- SUPPORT_CONN_USB3_PORTS = _make(version="1.3.5")
- SUPPORT_CONN_MACHVIRT_PCI_DEFAULT = _make(version="3.0.0")
- SUPPORT_CONN_QEMU_XHCI = _make(version="3.3.0", hv_version={"qemu": "2.9.0"})
- SUPPORT_CONN_VNC_NONE_AUTH = _make(hv_version={"qemu": "2.9.0"})
- SUPPORT_CONN_DEVICE_BOOT_ORDER = _make(hv_version={"qemu": 0, "test": 0})
- SUPPORT_CONN_RISCV_VIRT_PCI_DEFAULT = _make(version="5.3.0", hv_version={"qemu": "4.0.0"})
+ conn_graphics_listen_none = _make(version="2.0.0")
+ conn_rng_urandom = _make(version="1.3.4")
+ conn_usb3_ports = _make(version="1.3.5")
+ conn_machvirt_pci_default = _make(version="3.0.0")
+ conn_qemu_xhci = _make(version="3.3.0", hv_version={"qemu": "2.9.0"})
+ conn_vnc_none_auth = _make(hv_version={"qemu": "2.9.0"})
+ conn_device_boot_order = _make(hv_version={"qemu": 0, "test": 0})
+ conn_riscv_virt_pci_default = _make(version="5.3.0", hv_version={"qemu": "4.0.0"})
# We choose qemu 2.11.0 as the first version to target for q35 default.
# That's not really based on anything except reasonably modern at the
# time of these patches.
- SUPPORT_QEMU_Q35_DEFAULT = _make(hv_version={"qemu": "2.11.0", "test": "0"})
+ qemu_q35_default = _make(hv_version={"qemu": "2.11.0", "test": "0"})
# This is for disk <driver name=qemu>. xen supports this, but it's
# limited to arbitrary new enough xen, since I know libxl can handle it
# but I don't think the old xend driver does.
- SUPPORT_CONN_DISK_DRIVER_NAME_QEMU = _make(
+ conn_disk_driver_name_qemu = _make(
hv_version={"qemu": 0, "xen": "4.2.0"},
hv_libvirt_version={"qemu": 0, "xen": "1.1.0"})
# Domain checks
- SUPPORT_DOMAIN_XML_INACTIVE = _make(function="virDomain.XMLDesc", run_args=(),
+ domain_xml_inactive = _make(function="virDomain.XMLDesc", run_args=(),
flag="VIR_DOMAIN_XML_INACTIVE")
- SUPPORT_DOMAIN_XML_SECURE = _make(function="virDomain.XMLDesc", run_args=(),
+ domain_xml_secure = _make(function="virDomain.XMLDesc", run_args=(),
flag="VIR_DOMAIN_XML_SECURE")
- SUPPORT_DOMAIN_MANAGED_SAVE = _make(
+ domain_managed_save = _make(
function="virDomain.hasManagedSaveImage",
run_args=(0,))
- SUPPORT_DOMAIN_JOB_INFO = _make(function="virDomain.jobInfo", run_args=())
- SUPPORT_DOMAIN_LIST_SNAPSHOTS = _make(
+ domain_job_info = _make(function="virDomain.jobInfo", run_args=())
+ domain_list_snapshots = _make(
function="virDomain.listAllSnapshots", run_args=())
- SUPPORT_DOMAIN_MEMORY_STATS = _make(
+ domain_memory_stats = _make(
function="virDomain.memoryStats", run_args=())
- SUPPORT_DOMAIN_STATE = _make(function="virDomain.state", run_args=())
- SUPPORT_DOMAIN_OPEN_GRAPHICS = _make(function="virDomain.openGraphicsFD",
+ domain_state = _make(function="virDomain.state", run_args=())
+ domain_open_graphics = _make(function="virDomain.openGraphicsFD",
version="1.2.8", hv_version={"qemu": 0})
# Pool checks
- SUPPORT_POOL_ISACTIVE = _make(function="virStoragePool.isActive", run_args=())
- SUPPORT_POOL_LISTALLVOLUMES = _make(
+ pool_isactive = _make(function="virStoragePool.isActive", run_args=())
+ pool_listallvolumes = _make(
function="virStoragePool.listAllVolumes", run_args=())
- SUPPORT_POOL_METADATA_PREALLOC = _make(
+ pool_metadata_prealloc = _make(
flag="VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA",
version="1.0.1")
# Network checks
- SUPPORT_NET_ISACTIVE = _make(function="virNetwork.isActive", run_args=())
-
-
- def check_support(self, virtconn, feature, data=None):
- """
- Attempt to determine if a specific libvirt feature is support given
- the passed connection.
-
- :param virtconn: Libvirt connection to check feature on
- :param feature: Feature type to check support for
- :type feature: One of the SUPPORT_* flags
- :param data: Option libvirt object to use in feature checking
- :type data: Could be virDomain, virNetwork, virStoragePool, hv name, etc
-
- :returns: True if feature is supported, False otherwise
- """
- if "VirtinstConnection" in repr(data):
- data = data.get_conn_for_api_arg()
-
- sobj = _SUPPORT_OBJS[feature - 1]
- return sobj.check_support(virtconn, data)
+ net_isactive = _make(function="virNetwork.isActive", run_args=())
- def check_version(self, virtconn, version):
+ def _check_version(self, version):
"""
Check libvirt version. Useful for the test suite so we don't need
to keep adding new support checks.
"""
sobj = _SupportCheck(version=version)
- return sobj.check_support(virtconn, None)
+ return sobj(self._virtconn, None)