2013-07-07 13:53:37 -04:00
#
# Copyright (C) 2013 Red Hat, Inc.
#
2018-04-04 14:35:41 +01:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 15:00:02 -04:00
# See the COPYING file in the top-level directory.
2013-07-07 13:53:37 -04:00
#
2019-06-16 21:12:39 -04:00
from . logger import log
2013-07-07 13:53:37 -04:00
2014-06-02 11:57:09 -04:00
# Debugging helper to force old style polling
2015-09-17 15:18:22 -04:00
# Can be enabled with virt-manager --test-old-poll
FORCE_OLD_POLL = False
2014-06-02 11:57:09 -04:00
2014-06-02 17:17:47 -04:00
def _new_poll_helper ( origmap , typename , listfunc , buildfunc ) :
2013-07-07 13:53:37 -04:00
"""
Helper for new style listAll * APIs
"""
current = { }
new = { }
objs = [ ]
try :
objs = listfunc ( )
2017-05-05 12:47:21 -04:00
except Exception as e :
2019-06-16 21:12:39 -04:00
log . debug ( " Unable to list all %s s: %s " , typename , e )
2013-07-07 13:53:37 -04:00
for obj in objs :
2014-06-02 17:17:47 -04:00
connkey = obj . name ( )
2013-07-07 13:53:37 -04:00
2014-06-02 17:17:47 -04:00
if connkey not in origmap :
2013-07-07 13:53:37 -04:00
# Object is brand new this period
2014-06-02 17:17:47 -04:00
current [ connkey ] = buildfunc ( obj , connkey )
new [ connkey ] = current [ connkey ]
2013-07-07 13:53:37 -04:00
else :
# Previously known object
2014-06-02 17:17:47 -04:00
current [ connkey ] = origmap [ connkey ]
del ( origmap [ connkey ] )
2013-07-07 13:53:37 -04:00
2017-10-11 12:35:46 +01:00
return ( list ( origmap . values ( ) ) , list ( new . values ( ) ) , list ( current . values ( ) ) )
2013-07-07 13:53:37 -04:00
2013-09-29 09:28:42 -04:00
def _old_poll_helper ( origmap , typename ,
2013-07-07 13:53:37 -04:00
active_list , inactive_list ,
2014-06-02 17:17:47 -04:00
lookup_func , build_func ) :
2013-07-07 13:53:37 -04:00
"""
Helper routine for old style split API libvirt polling .
2014-06-02 17:17:47 -04:00
@origmap : Pre - existing mapping of objects , with connkey - > obj mapping .
2013-07-07 13:53:37 -04:00
objects must have an is_active and set_active API
@typename : string describing type of objects we are polling for use
in debug messages .
@active_list : Function that returns the list of active objects
@inactive_list : Function that returns the list of inactive objects
@lookup_func : Function to get an object handle for the passed name
@build_func : Function that builds a new object class . It is passed
2014-06-02 17:17:47 -04:00
args of ( raw libvirt object , connkey )
2013-07-07 13:53:37 -04:00
"""
current = { }
new = { }
newActiveNames = [ ]
newInactiveNames = [ ]
try :
newActiveNames = active_list ( )
2017-05-05 12:47:21 -04:00
except Exception as e :
2019-06-16 21:12:39 -04:00
log . debug ( " Unable to list active %s s: %s " , typename , e )
2013-07-07 13:53:37 -04:00
try :
newInactiveNames = inactive_list ( )
2017-05-05 12:47:21 -04:00
except Exception as e :
2019-06-16 21:12:39 -04:00
log . debug ( " Unable to list inactive %s s: %s " , typename , e )
2013-07-07 13:53:37 -04:00
2014-06-02 12:17:21 -04:00
def check_obj ( name ) :
obj = None
2014-06-02 17:17:47 -04:00
connkey = name
2013-07-07 13:53:37 -04:00
2014-06-02 17:17:47 -04:00
if connkey not in origmap :
2015-04-10 09:15:44 -04:00
try :
obj = lookup_func ( name )
2017-05-05 12:47:21 -04:00
except Exception as e :
2019-06-16 21:12:39 -04:00
log . debug ( " Could not fetch %s ' %s ' : %s " ,
2015-04-10 09:15:44 -04:00
typename , connkey , e )
return
2014-06-02 12:17:21 -04:00
2013-07-07 13:53:37 -04:00
# Object is brand new this period
2014-06-02 17:17:47 -04:00
current [ connkey ] = build_func ( obj , connkey )
new [ connkey ] = current [ connkey ]
2013-07-07 13:53:37 -04:00
else :
# Previously known object
2014-06-02 17:17:47 -04:00
current [ connkey ] = origmap [ connkey ]
del ( origmap [ connkey ] )
2013-07-07 13:53:37 -04:00
for name in newActiveNames + newInactiveNames :
try :
check_obj ( name )
2017-07-24 09:26:48 +01:00
except Exception :
2019-06-16 21:12:39 -04:00
log . exception ( " Couldn ' t fetch %s ' %s ' " , typename , name )
2013-07-07 13:53:37 -04:00
2017-10-11 12:35:46 +01:00
return ( list ( origmap . values ( ) ) , list ( new . values ( ) ) , list ( current . values ( ) ) )
2013-07-07 13:53:37 -04:00
2013-09-29 09:28:42 -04:00
def fetch_nets ( backend , origmap , build_func ) :
2013-07-07 13:53:37 -04:00
name = " network "
2019-06-07 16:06:52 -04:00
if backend . support . conn_listallnetworks ( ) and not FORCE_OLD_POLL :
2013-09-29 09:28:42 -04:00
return _new_poll_helper ( origmap , name ,
2014-06-02 17:17:47 -04:00
backend . listAllNetworks , build_func )
2013-07-07 13:53:37 -04:00
else :
active_list = backend . listNetworks
inactive_list = backend . listDefinedNetworks
lookup_func = backend . networkLookupByName
2013-09-29 09:28:42 -04:00
return _old_poll_helper ( origmap , name ,
2013-07-07 13:53:37 -04:00
active_list , inactive_list ,
2014-06-02 17:17:47 -04:00
lookup_func , build_func )
2013-07-07 13:53:37 -04:00
2013-09-29 09:28:42 -04:00
def fetch_pools ( backend , origmap , build_func ) :
2013-07-07 13:53:37 -04:00
name = " pool "
2019-06-07 16:06:52 -04:00
if backend . support . conn_listallstoragepools ( ) and not FORCE_OLD_POLL :
2013-09-29 09:28:42 -04:00
return _new_poll_helper ( origmap , name ,
2014-06-02 17:17:47 -04:00
backend . listAllStoragePools , build_func )
2013-07-07 13:53:37 -04:00
else :
active_list = backend . listStoragePools
inactive_list = backend . listDefinedStoragePools
lookup_func = backend . storagePoolLookupByName
2013-09-29 09:28:42 -04:00
return _old_poll_helper ( origmap , name ,
2013-07-07 13:53:37 -04:00
active_list , inactive_list ,
2014-06-02 17:17:47 -04:00
lookup_func , build_func )
2013-07-07 13:53:37 -04:00
2013-09-29 09:31:39 -04:00
def fetch_volumes ( backend , pool , origmap , build_func ) :
name = " volume "
2019-06-07 16:06:52 -04:00
if backend . support . pool_listallvolumes ( pool ) and not FORCE_OLD_POLL :
2013-09-29 09:31:39 -04:00
return _new_poll_helper ( origmap , name ,
2014-06-02 17:17:47 -04:00
pool . listAllVolumes , build_func )
2013-09-29 09:31:39 -04:00
else :
active_list = pool . listVolumes
2015-07-10 14:07:03 +02:00
def inactive_list ( ) :
return [ ]
2013-09-29 09:31:39 -04:00
lookup_func = pool . storageVolLookupByName
return _old_poll_helper ( origmap , name ,
active_list , inactive_list ,
lookup_func , build_func )
2013-09-29 09:28:42 -04:00
def fetch_interfaces ( backend , origmap , build_func ) :
2013-07-07 13:53:37 -04:00
name = " interface "
2019-06-07 16:06:52 -04:00
if backend . support . conn_listallinterfaces ( ) and not FORCE_OLD_POLL :
2013-09-29 09:28:42 -04:00
return _new_poll_helper ( origmap , name ,
2014-06-02 17:17:47 -04:00
backend . listAllInterfaces , build_func )
2013-07-07 13:53:37 -04:00
else :
active_list = backend . listInterfaces
inactive_list = backend . listDefinedInterfaces
lookup_func = backend . interfaceLookupByName
2013-09-29 09:28:42 -04:00
return _old_poll_helper ( origmap , name ,
2013-07-07 13:53:37 -04:00
active_list , inactive_list ,
lookup_func , build_func )
2013-09-29 09:28:42 -04:00
def fetch_nodedevs ( backend , origmap , build_func ) :
2013-07-07 13:53:37 -04:00
name = " nodedev "
2019-06-07 16:06:52 -04:00
if backend . support . conn_listalldevices ( ) and not FORCE_OLD_POLL :
2013-09-29 09:39:55 -04:00
return _new_poll_helper ( origmap , name ,
2014-06-02 17:17:47 -04:00
backend . listAllDevices , build_func )
2013-09-29 09:39:55 -04:00
else :
2015-07-10 14:07:03 +02:00
def active_list ( ) :
return backend . listDevices ( None , 0 )
def inactive_list ( ) :
return [ ]
2013-09-29 09:39:55 -04:00
lookup_func = backend . nodeDeviceLookupByName
return _old_poll_helper ( origmap , name ,
active_list , inactive_list ,
lookup_func , build_func )
2013-07-07 13:53:37 -04:00
2013-09-29 09:28:42 -04:00
def _old_fetch_vms ( backend , origmap , build_func ) :
2013-07-07 13:53:37 -04:00
# We can't easily use _old_poll_helper here because the domain API
# doesn't always return names like other objects, it returns
# IDs for active VMs
newActiveIDs = [ ]
newInactiveNames = [ ]
oldActiveIDs = { }
oldInactiveNames = { }
current = { }
new = { }
# Build list of previous vms with proper id/name mappings
2017-10-11 12:35:46 +01:00
for vm in list ( origmap . values ( ) ) :
2013-07-07 13:53:37 -04:00
if vm . is_active ( ) :
oldActiveIDs [ vm . get_id ( ) ] = vm
else :
oldInactiveNames [ vm . get_name ( ) ] = vm
try :
newActiveIDs = backend . listDomainsID ( )
2017-05-05 12:47:21 -04:00
except Exception as e :
2019-06-16 21:12:39 -04:00
log . debug ( " Unable to list active domains: %s " , e )
2013-07-07 13:53:37 -04:00
try :
newInactiveNames = backend . listDefinedDomains ( )
2017-05-05 12:47:21 -04:00
except Exception as e :
2019-06-16 21:12:39 -04:00
log . exception ( " Unable to list inactive domains: %s " , e )
2013-07-07 13:53:37 -04:00
def add_vm ( vm ) :
2014-06-02 17:17:47 -04:00
connkey = vm . get_name ( )
2013-07-07 13:53:37 -04:00
2014-06-02 17:17:47 -04:00
current [ connkey ] = vm
del ( origmap [ connkey ] )
2013-07-07 13:53:37 -04:00
2014-06-02 17:17:47 -04:00
def check_new ( rawvm , connkey ) :
if connkey in origmap :
vm = origmap [ connkey ]
del ( origmap [ connkey ] )
2013-07-07 13:53:37 -04:00
else :
2014-06-02 17:17:47 -04:00
vm = build_func ( rawvm , connkey )
new [ connkey ] = vm
2013-07-07 13:53:37 -04:00
2014-06-02 17:17:47 -04:00
current [ connkey ] = vm
2013-07-07 13:53:37 -04:00
for _id in newActiveIDs :
if _id in oldActiveIDs :
# No change, copy across existing VM object
vm = oldActiveIDs [ _id ]
add_vm ( vm )
else :
# Check if domain is brand new, or old one that changed state
try :
vm = backend . lookupByID ( _id )
2014-06-02 17:17:47 -04:00
connkey = vm . name ( )
2013-07-07 13:53:37 -04:00
2014-06-02 17:17:47 -04:00
check_new ( vm , connkey )
2017-07-24 09:26:48 +01:00
except Exception :
2019-06-16 21:12:39 -04:00
log . exception ( " Couldn ' t fetch domain id ' %s ' " , _id )
2013-07-07 13:53:37 -04:00
for name in newInactiveNames :
if name in oldInactiveNames :
# No change, copy across existing VM object
vm = oldInactiveNames [ name ]
add_vm ( vm )
else :
# Check if domain is brand new, or old one that changed state
try :
vm = backend . lookupByName ( name )
2014-06-02 17:17:47 -04:00
connkey = name
2013-07-07 13:53:37 -04:00
2014-06-02 17:17:47 -04:00
check_new ( vm , connkey )
2017-07-24 09:26:48 +01:00
except Exception :
2019-06-16 21:12:39 -04:00
log . exception ( " Couldn ' t fetch domain ' %s ' " , name )
2013-07-07 13:53:37 -04:00
2017-10-11 12:35:46 +01:00
return ( list ( origmap . values ( ) ) , list ( new . values ( ) ) , list ( current . values ( ) ) )
2013-07-07 13:53:37 -04:00
2013-09-29 09:28:42 -04:00
def fetch_vms ( backend , origmap , build_func ) :
2013-07-07 13:53:37 -04:00
name = " domain "
2019-06-07 16:06:52 -04:00
if backend . support . conn_listalldomains ( ) :
2013-09-29 09:28:42 -04:00
return _new_poll_helper ( origmap , name ,
2014-06-02 17:17:47 -04:00
backend . listAllDomains , build_func )
2013-07-07 13:53:37 -04:00
else :
2013-09-29 09:28:42 -04:00
return _old_fetch_vms ( backend , origmap , build_func )