Streamline support checks

Just use one function check_support
This commit is contained in:
Cole Robinson 2013-10-06 10:08:04 -04:00
parent d4103eac26
commit 56b9f6187b
21 changed files with 89 additions and 123 deletions

View File

@ -218,7 +218,7 @@ class Command(object):
return
if conn is None:
raise RuntimeError("support_check is not None, but conn is None")
if conn.check_conn_support(self.support_check):
if conn.check_support(self.support_check):
return
return "skipped"

View File

@ -442,7 +442,7 @@ def check_option_collisions(options, guest):
if (options.location and
guest.conn.is_remote() and not
virtinst.support.support_remote_url_install(guest.conn)):
guest.conn.support_remote_url_install()):
fail(_("Libvirt version does not support remote --location installs"))
if not options.location and options.extra:

View File

@ -377,14 +377,14 @@ class vmmAddHardware(vmmGObjectUI):
_("Connection does not support host device enumeration"),
"pci")
add_hw_option("Video", "video-display", PAGE_VIDEO,
self.conn.check_conn_support(
self.conn.check_support(
self.conn.SUPPORT_CONN_DOMAIN_VIDEO),
_("Libvirt version does not support video devices."))
add_hw_option("Watchdog", "device_pci", PAGE_WATCHDOG,
self.vm.is_hvm(),
_("Not supported for this guest type."))
add_hw_option("Filesystem", Gtk.STOCK_DIRECTORY, PAGE_FILESYSTEM,
self.conn.check_conn_support(
self.conn.check_support(
self.conn.SUPPORT_CONN_FILESYSTEM),
_("Not supported for this hypervisor/libvirt "
"combination."))
@ -1149,7 +1149,7 @@ class vmmAddHardware(vmmGObjectUI):
ischan = char_class.virtual_device_type == "channel"
iscon = char_class.virtual_device_type == "console"
show_auto = (devtype == "unix" and ischan and
self.conn.check_conn_support(self.conn.SUPPORT_CONN_AUTOSOCKET))
self.conn.check_support(self.conn.SUPPORT_CONN_AUTOSOCKET))
self._dev = char_class(conn)
self._dev.type = devtype

View File

@ -72,9 +72,8 @@ def can_we_clone(conn, vol, path):
elif vol:
# Managed storage
if not conn.check_pool_support(
vol.get_parent_pool().get_backend(),
conn.SUPPORT_POOL_CREATEVOLFROM):
if not conn.check_support(conn.SUPPORT_POOL_CREATEVOLFROM,
vol.get_parent_pool().get_backend()):
if conn.is_remote() or not os.access(path, os.R_OK):
msg = _("Connection does not support managed storage cloning.")
else:

View File

@ -255,7 +255,7 @@ class vmmConnection(vmmGObject):
##########################
def get_qualified_hostname(self):
if self.check_conn_support(self._backend.SUPPORT_CONN_GETHOSTNAME):
if self.check_support(self._backend.SUPPORT_CONN_GETHOSTNAME):
return self._backend.getHostname()
uri_hostname = self.get_uri_hostname()
@ -328,7 +328,7 @@ class vmmConnection(vmmGObject):
if fmt != "qcow2":
return
if self.check_conn_support(self._backend.SUPPORT_CONN_DEFAULT_QCOW2):
if self.check_support(self._backend.SUPPORT_CONN_DEFAULT_QCOW2):
return fmt
return None
@ -428,22 +428,12 @@ class vmmConnection(vmmGObject):
_supportname.startswith("SUPPORT_")]:
locals()[_supportname] = getattr(virtinst.VirtualConnection,
_supportname)
def check_conn_support(self, *args):
return self._backend.check_conn_support(*args)
def check_domain_support(self, *args):
return self._backend.check_domain_support(*args)
def check_pool_support(self, *args):
return self._backend.check_pool_support(*args)
def check_interface_support(self, *args):
return self._backend.check_interface_support(*args)
def check_stream_support(self, *args):
return self._backend.check_stream_support(*args)
def check_net_support(self, *args):
return self._backend.check_net_support(*args)
def check_support(self, *args):
return self._backend.check_support(*args)
def is_storage_capable(self):
if self._storage_capable is None:
self._storage_capable = self.check_conn_support(
self._storage_capable = self.check_support(
self._backend.SUPPORT_CONN_STORAGE)
if self._storage_capable is False:
logging.debug("Connection doesn't seem to support storage "
@ -459,7 +449,7 @@ class vmmConnection(vmmGObject):
def is_network_capable(self):
if self._network_capable is None:
self._network_capable = self.check_conn_support(
self._network_capable = self.check_support(
self._backend.SUPPORT_CONN_NETWORK)
if self._network_capable is False:
logging.debug("Connection doesn't seem to support network "
@ -469,7 +459,7 @@ class vmmConnection(vmmGObject):
def is_interface_capable(self):
if self._interface_capable is None:
self._interface_capable = self.check_conn_support(
self._interface_capable = self.check_support(
self._backend.SUPPORT_CONN_INTERFACE)
if self._interface_capable is False:
logging.debug("Connection doesn't seem to support interface "
@ -479,7 +469,7 @@ class vmmConnection(vmmGObject):
def is_nodedev_capable(self):
if self._nodedev_capable is None:
self._nodedev_capable = self.check_conn_support(
self._nodedev_capable = self.check_support(
self._backend.SUPPORT_CONN_NODEDEV)
return self._nodedev_capable
@ -508,21 +498,21 @@ class vmmConnection(vmmGObject):
act = 0
inact = 0
if self.check_domain_support(vm,
self._backend.SUPPORT_DOMAIN_XML_INACTIVE):
if self.check_support(
self._backend.SUPPORT_DOMAIN_XML_INACTIVE, vm):
inact = libvirt.VIR_DOMAIN_XML_INACTIVE
else:
logging.debug("Domain XML inactive flag not supported.")
if self.check_domain_support(vm,
self._backend.SUPPORT_DOMAIN_XML_SECURE):
if self.check_support(
self._backend.SUPPORT_DOMAIN_XML_SECURE, vm):
inact |= libvirt.VIR_DOMAIN_XML_SECURE
act = libvirt.VIR_DOMAIN_XML_SECURE
else:
logging.debug("Domain XML secure flag not supported.")
if self.check_domain_support(vm,
self._backend.SUPPORT_DOMAIN_CPU_HOST_MODEL):
if self.check_support(
self._backend.SUPPORT_DOMAIN_CPU_HOST_MODEL, vm):
inact |= libvirt.VIR_DOMAIN_XML_UPDATE_CPU
act |= libvirt.VIR_DOMAIN_XML_UPDATE_CPU
else:
@ -539,8 +529,8 @@ class vmmConnection(vmmGObject):
act = 0
inact = 0
if self.check_interface_support(iface,
self._backend.SUPPORT_INTERFACE_XML_INACTIVE):
if self.check_support(
self._backend.SUPPORT_INTERFACE_XML_INACTIVE, iface):
inact = libvirt.VIR_INTERFACE_XML_INACTIVE
else:
logging.debug("Interface XML inactive flag not supported.")

View File

@ -420,8 +420,7 @@ class vmmCreate(vmmGObjectUI):
can_storage = (is_local or is_storage_capable)
is_pv = (self.capsguest.os_type == "xen")
is_container = self.conn.is_container()
can_remote_url = self.conn.check_stream_support(
self.conn.SUPPORT_STREAM_UPLOAD)
can_remote_url = self.conn.get_backend().support_remote_url_install()
installable_arch = (self.capsguest.arch in
["i686", "x86_64", "ppc64", "ia64"])

View File

@ -268,15 +268,12 @@ class vmmDomain(vmmLibvirtObject):
"""
Initialization to do if backed by a libvirt virDomain
"""
self.managedsave_supported = self.conn.check_domain_support(
self._backend,
self.conn.SUPPORT_DOMAIN_MANAGED_SAVE)
self.remote_console_supported = self.conn.check_domain_support(
self._backend,
self.conn.SUPPORT_DOMAIN_CONSOLE_STREAM)
self.title_supported = self.conn.check_domain_support(
self._backend,
self.conn.SUPPORT_DOMAIN_GET_METADATA)
self.managedsave_supported = self.conn.check_support(
self.conn.SUPPORT_DOMAIN_MANAGED_SAVE, self._backend)
self.remote_console_supported = self.conn.check_support(
self.conn.SUPPORT_DOMAIN_CONSOLE_STREAM, self._backend)
self.title_supported = self.conn.check_support(
self.conn.SUPPORT_DOMAIN_GET_METADATA, self._backend)
# Determine available XML flags (older libvirt versions will error
# out if passed SECURE_XML, INACTIVE_XML, etc)
@ -394,18 +391,18 @@ class vmmDomain(vmmLibvirtObject):
##################
def _get_getvcpus_supported(self):
return self.conn.check_domain_support(self._backend,
self.conn.SUPPORT_DOMAIN_GETVCPUS)
return self.conn.check_support(
self.conn.SUPPORT_DOMAIN_GETVCPUS, self._backend)
getvcpus_supported = property(_get_getvcpus_supported)
def _get_getjobinfo_supported(self):
return self.conn.check_domain_support(self._backend,
self.conn.SUPPORT_DOMAIN_JOB_INFO)
return self.conn.check_support(
self.conn.SUPPORT_DOMAIN_JOB_INFO, self._backend)
getjobinfo_supported = property(_get_getjobinfo_supported)
def snapshots_supported(self):
if not self.conn.check_domain_support(
self._backend, self.conn.SUPPORT_DOMAIN_LIST_SNAPSHOTS):
if not self.conn.check_support(
self.conn.SUPPORT_DOMAIN_LIST_SNAPSHOTS, self._backend):
return _("Libvirt connection does not support snapshots.")
if self.list_snapshots():
@ -916,8 +913,8 @@ class vmmDomain(vmmLibvirtObject):
# libvirt since 0.9.10 provides a SetMetadata API that provides
# actual <description> 'hotplug', and using that means checkig
# for support, version, etc.
if not self.conn.check_domain_support(self._backend,
self.conn.SUPPORT_DOMAIN_SET_METADATA):
if not self.conn.check_support(
self.conn.SUPPORT_DOMAIN_SET_METADATA, self._backend):
return
flags = (libvirt.VIR_DOMAIN_AFFECT_LIVE |
@ -927,8 +924,8 @@ class vmmDomain(vmmLibvirtObject):
desc, None, None, flags)
def hotplug_title(self, title):
if not self.conn.check_domain_support(self._backend,
self.conn.SUPPORT_DOMAIN_SET_METADATA):
if not self.conn.check_support(
self.conn.SUPPORT_DOMAIN_SET_METADATA, self._backend):
return
flags = (libvirt.VIR_DOMAIN_AFFECT_LIVE |
@ -1315,8 +1312,8 @@ class vmmDomain(vmmLibvirtObject):
def support_downtime(self):
return self.conn.check_domain_support(self._backend,
self.conn.SUPPORT_DOMAIN_MIGRATE_DOWNTIME)
return self.conn.check_support(
self.conn.SUPPORT_DOMAIN_MIGRATE_DOWNTIME, self._backend)
def migrate_set_max_downtime(self, max_downtime, flag=0):
self._backend.migrateSetMaxDowntime(max_downtime, flag)

View File

@ -55,9 +55,8 @@ class vmmInterface(vmmLibvirtObject):
def _backend_get_active(self):
ret = True
if self._support_isactive is None:
self._support_isactive = self.conn.check_interface_support(
self._backend,
self.conn.SUPPORT_INTERFACE_ISACTIVE)
self._support_isactive = self.conn.check_support(
self.conn.SUPPORT_INTERFACE_ISACTIVE, self._backend)
if not self._support_isactive:
return True

View File

@ -66,9 +66,8 @@ class vmmNetwork(vmmLibvirtObject):
def _backend_get_active(self):
if self._support_isactive is None:
self._support_isactive = self.conn.check_net_support(
self._backend,
self.conn.SUPPORT_NET_ISACTIVE)
self._support_isactive = self.conn.check_support(
self.conn.SUPPORT_NET_ISACTIVE, self._backend)
if not self._support_isactive:
return True

View File

@ -114,9 +114,8 @@ class vmmStoragePool(vmmLibvirtObject):
return self._active
def _backend_get_active(self):
if self._support_isactive is None:
self._support_isactive = self.conn.check_pool_support(
self._backend,
self.conn.SUPPORT_POOL_ISACTIVE)
self._support_isactive = self.conn.check_support(
self.conn.SUPPORT_POOL_ISACTIVE, self._backend)
if not self._support_isactive:
return True

View File

@ -615,7 +615,7 @@ def populate_network_list(net_list, conn, show_direct_interfaces=True):
brlabel = _("(Empty bridge)")
else:
if (show_direct_interfaces and
conn.check_conn_support(
conn.check_support(
conn.SUPPORT_CONN_DIRECT_INTERFACE)):
sensitive = True
nettype = virtinst.VirtualNetworkInterface.TYPE_DIRECT

View File

@ -262,7 +262,7 @@ class VirtualConnection(object):
return self.local_libvirt_version()
if not self._daemon_version:
if not self.check_conn_support(support.SUPPORT_CONN_LIBVERSION):
if not self.check_support(support.SUPPORT_CONN_LIBVERSION):
self._daemon_version = 0
else:
self._daemon_version = self.libvirtconn.getLibVersion()
@ -273,7 +273,7 @@ class VirtualConnection(object):
return self._fake_conn_version
if not self._conn_version:
if not self.check_conn_support(support.SUPPORT_CONN_GETVERSION):
if not self.check_support(support.SUPPORT_CONN_GETVERSION):
self._conn_version = 0
else:
self._conn_version = self.libvirtconn.getVersion()
@ -340,28 +340,19 @@ class VirtualConnection(object):
_supportname.startswith("SUPPORT_")]:
locals()[_supportname] = getattr(support, _supportname)
def _check_support(self, feature, data):
def check_support(self, feature, data=None):
key = feature
if type(data) is str:
key = (feature, data)
data = data or self
if key not in self._support_cache:
self._support_cache[key] = support.check_support(
self, feature, data)
return self._support_cache[key]
def check_conn_support(self, feature):
return self._check_support(feature, self)
def check_domain_support(self, dom, feature):
return self._check_support(feature, dom)
def check_pool_support(self, pool, feature):
return self._check_support(feature, pool)
def check_interface_support(self, iface, feature):
return self._check_support(feature, iface)
def check_stream_support(self, feature):
return (self.check_conn_support(self.SUPPORT_CONN_STREAM) and
self._check_support(feature, self))
def check_net_support(self, net, feature):
return self._check_support(feature, net)
def support_remote_url_install(self):
if hasattr(self, "_virtinst__fake_conn"):
return False
return (self.check_support(self.SUPPORT_CONN_STREAM) and
self.check_support(self.SUPPORT_STREAM_UPLOAD))
###################

View File

@ -106,7 +106,7 @@ def _distill_storage(conn, do_create, nomanaged,
"""
pool = None
path_is_pool = False
storage_capable = conn.check_conn_support(conn.SUPPORT_CONN_STORAGE)
storage_capable = conn.check_support(conn.SUPPORT_CONN_STORAGE)
if vol_object:
pass
@ -382,7 +382,7 @@ class VirtualDisk(VirtualDevice):
"""
Return a volume instance from a pool name, vol name tuple
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_STORAGE):
if not conn.check_support(conn.SUPPORT_CONN_STORAGE):
raise ValueError(_("Connection does not support storage lookup."))
try:
@ -681,7 +681,7 @@ class VirtualDisk(VirtualDevice):
return True
storage_capable = self.conn.check_conn_support(
storage_capable = self.conn.check_support(
self.conn.SUPPORT_CONN_STORAGE)
if self.conn.is_remote():

View File

@ -109,7 +109,7 @@ class VirtualGraphics(VirtualDevice):
return None
if (not force_local and
self.conn.check_conn_support(
self.conn.check_support(
self.conn.SUPPORT_CONN_KEYMAP_AUTODETECT)):
return None

View File

@ -33,7 +33,7 @@ def _check_if_pool_source(conn, path):
If passed path is a host disk device like /dev/sda, want to let the user
use it
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_STORAGE):
if not conn.check_support(conn.SUPPORT_CONN_STORAGE):
return None
def check_pool(poolname, path):

View File

@ -25,7 +25,6 @@ import tempfile
import urlgrabber
from virtinst import support
from virtinst import StoragePool, StorageVolume
from virtinst import util
from virtinst import Installer
@ -279,7 +278,7 @@ def _upload_media(conn, scratchdir, system_scratchdir,
" nothing to upload")
return kernel, initrd, tmpvols
if not support.support_remote_url_install(conn):
if not conn.support_remote_url_install():
logging.debug("Media upload not supported")
return kernel, initrd, tmpvols

View File

@ -534,7 +534,7 @@ class Guest(XMLBuilder):
if (self.os.is_x86() and
self._lookup_osdict_key("virtioconsole", False) and
self.conn.check_conn_support(
self.conn.check_support(
self.conn.SUPPORT_CONN_VIRTIO_CONSOLE)):
dev.target_type = "virtio"
@ -556,7 +556,7 @@ class Guest(XMLBuilder):
return
if any([d.type == "usb" for d in self.get_devices("controller")]):
return
if not self.conn.check_conn_support(
if not self.conn.check_support(
self.conn.SUPPORT_CONN_DEFAULT_USB2):
return
for dev in virtinst.VirtualController.get_usb2_controllers(self.conn):
@ -570,7 +570,7 @@ class Guest(XMLBuilder):
if (self.conn.is_qemu() and
self._lookup_osdict_key("qemu_ga", False) and
self.conn.check_conn_support(self.conn.SUPPORT_CONN_AUTOSOCKET)):
self.conn.check_support(self.conn.SUPPORT_CONN_AUTOSOCKET)):
dev = virtinst.VirtualChannelDevice(self.conn)
dev.type = "unix"
dev.target_type = "virtio"
@ -645,7 +645,7 @@ class Guest(XMLBuilder):
return
if not self.os.is_x86():
return
if not self.conn.check_conn_support(
if not self.conn.check_support(
self.conn.SUPPORT_CONN_ADVANCED_CLOCK):
return
@ -699,7 +699,7 @@ class Guest(XMLBuilder):
default = True
if (self._lookup_osdict_key("xen_disable_acpi", False) and
self.conn.check_conn_support(
self.conn.check_support(
support.SUPPORT_CONN_SKIP_DEFAULT_ACPI)):
default = False
@ -755,7 +755,7 @@ class Guest(XMLBuilder):
if (self.os.is_arm_vexpress() and
self.os.dtb and
self._lookup_osdict_key("virtiommio", False) and
self.conn.check_conn_support(support.SUPPORT_CONN_VIRTIO_MMIO)):
self.conn.check_support(support.SUPPORT_CONN_VIRTIO_MMIO)):
return True
return False
@ -829,10 +829,10 @@ class Guest(XMLBuilder):
inp.bus = input_bus
def _set_sound_defaults(self):
if self.conn.check_conn_support(
if self.conn.check_support(
support.SUPPORT_CONN_SOUND_ICH6):
default = "ich6"
elif self.conn.check_conn_support(
elif self.conn.check_support(
support.SUPPORT_CONN_SOUND_AC97):
default = "ac97"
else:
@ -850,7 +850,7 @@ class Guest(XMLBuilder):
gtype = self.default_graphics_type
logging.debug("Using default_graphics=%s", gtype)
if (gtype == "spice" and not
self.conn.check_conn_support(
self.conn.check_support(
self.conn.SUPPORT_CONN_GRAPHICS_SPICE)):
logging.debug("spice requested but HV doesn't support it. "
"Using vnc.")
@ -867,7 +867,7 @@ class Guest(XMLBuilder):
return
if (not has_spice_agent() and
self.conn.check_conn_support(
self.conn.check_support(
self.conn.SUPPORT_CONN_CHAR_SPICEVMC)):
agentdev = virtinst.VirtualChannelDevice(self.conn)
agentdev.type = agentdev.TYPE_SPICEVMC

View File

@ -76,7 +76,7 @@ class NodeDevice(XMLBuilder):
@rtype: L{NodeDevice} instance
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_NODEDEV):
if not conn.check_support(conn.SUPPORT_CONN_NODEDEV):
raise ValueError(_("Connection does not support host device "
"enumeration."))

View File

@ -108,7 +108,7 @@ def _old_poll_helper(origmap, typename,
def fetch_nets(backend, origmap, build_func):
name = "network"
if backend.check_conn_support(
if backend.check_support(
backend.SUPPORT_CONN_LISTALLNETWORKS):
return _new_poll_helper(origmap, name,
backend.listAllNetworks,
@ -126,7 +126,7 @@ def fetch_nets(backend, origmap, build_func):
def fetch_pools(backend, origmap, build_func):
name = "pool"
if backend.check_conn_support(
if backend.check_support(
backend.SUPPORT_CONN_LISTALLSTORAGEPOOLS):
return _new_poll_helper(origmap, name,
backend.listAllStoragePools,
@ -144,8 +144,8 @@ def fetch_pools(backend, origmap, build_func):
def fetch_volumes(backend, pool, origmap, build_func):
name = "volume"
if backend.check_pool_support(pool,
backend.SUPPORT_POOL_LISTALLVOLUMES):
if backend.check_support(
backend.SUPPORT_POOL_LISTALLVOLUMES, pool):
return _new_poll_helper(origmap, name,
pool.listAllVolumes,
"name", build_func)
@ -161,7 +161,7 @@ def fetch_volumes(backend, pool, origmap, build_func):
def fetch_interfaces(backend, origmap, build_func):
name = "interface"
if backend.check_conn_support(
if backend.check_support(
backend.SUPPORT_CONN_LISTALLINTERFACES):
return _new_poll_helper(origmap, name,
backend.listAllInterfaces,
@ -178,7 +178,7 @@ def fetch_interfaces(backend, origmap, build_func):
def fetch_nodedevs(backend, origmap, build_func):
name = "nodedev"
if backend.check_conn_support(
if backend.check_support(
backend.SUPPORT_CONN_LISTALLDEVICES):
return _new_poll_helper(origmap, name,
backend.listAllDevices,
@ -274,7 +274,7 @@ def _old_fetch_vms(backend, origmap, build_func):
def fetch_vms(backend, origmap, build_func):
name = "domain"
if backend.check_conn_support(
if backend.check_support(
backend.SUPPORT_CONN_LISTALLDOMAINS):
return _new_poll_helper(origmap, name,
backend.listAllDomains,

View File

@ -129,7 +129,7 @@ class StoragePool(_StorageObject):
@param pool_type: Pool type string from I{Types}
@param host: Option host string to poll for sources
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_FINDPOOLSOURCES):
if not conn.check_support(conn.SUPPORT_CONN_FINDPOOLSOURCES):
return []
if host:
@ -172,7 +172,7 @@ class StoragePool(_StorageObject):
"""
Helper to build the 'default' storage pool
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_STORAGE):
if not conn.check_support(conn.SUPPORT_CONN_STORAGE):
return
pool = None
@ -213,7 +213,7 @@ class StoragePool(_StorageObject):
Favor running pools over inactive pools.
@returns: virStoragePool object if found, None otherwise
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_STORAGE):
if not conn.check_support(conn.SUPPORT_CONN_STORAGE):
return None
def check_pool(pool, path):
@ -511,8 +511,8 @@ class StorageVolume(_StorageObject):
if not isinstance(vol, libvirt.virStorageVol):
raise ValueError(_("input_vol must be a virStorageVol"))
if not self.conn.check_pool_support(self.pool,
self.conn.SUPPORT_POOL_CREATEVOLFROM):
if not self.conn.check_support(
self.conn.SUPPORT_POOL_CREATEVOLFROM, self.pool):
raise ValueError(_("Creating storage from an existing volume is"
" not supported by this libvirt version."))
@ -649,8 +649,8 @@ class StorageVolume(_StorageObject):
if (self.format == "qcow2" and
not self.backing_store and
not self.conn.is_test() and
self.conn.check_pool_support(
self.pool, self.conn.SUPPORT_POOL_METADATA_PREALLOC)):
self.conn.check_support(
self.conn.SUPPORT_POOL_METADATA_PREALLOC, self.pool)):
createflags |= libvirt.VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA

View File

@ -24,12 +24,6 @@ import libvirt
from virtinst import util
def support_remote_url_install(conn):
if hasattr(conn, "_virtinst__fake_conn"):
return False
return conn.check_stream_support(conn.SUPPORT_STREAM_UPLOAD)
# Check that command is present in the python bindings, and return the
# the requested function
def _get_command(funcname, objname=None, obj=None):