2013-07-07 21:53:37 +04:00
#
# Copyright (C) 2013 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
import logging
2014-06-02 19:57:09 +04:00
# Debugging helper to force old style polling
2015-09-17 22:18:22 +03:00
# Can be enabled with virt-manager --test-old-poll
FORCE_OLD_POLL = False
2014-06-02 19:57:09 +04:00
2014-06-03 01:17:47 +04:00
def _new_poll_helper ( origmap , typename , listfunc , buildfunc ) :
2013-07-07 21:53:37 +04:00
"""
Helper for new style listAll * APIs
"""
current = { }
new = { }
objs = [ ]
try :
objs = listfunc ( )
except Exception , e :
logging . debug ( " Unable to list all %s s: %s " , typename , e )
for obj in objs :
2014-06-03 01:17:47 +04:00
connkey = obj . name ( )
2013-07-07 21:53:37 +04:00
2014-06-03 01:17:47 +04:00
if connkey not in origmap :
2013-07-07 21:53:37 +04:00
# Object is brand new this period
2014-06-03 01:17:47 +04:00
current [ connkey ] = buildfunc ( obj , connkey )
new [ connkey ] = current [ connkey ]
2013-07-07 21:53:37 +04:00
else :
# Previously known object
2014-06-03 01:17:47 +04:00
current [ connkey ] = origmap [ connkey ]
del ( origmap [ connkey ] )
2013-07-07 21:53:37 +04:00
2015-04-10 19:52:42 +03:00
return ( origmap . values ( ) , new . values ( ) , current . values ( ) )
2013-07-07 21:53:37 +04:00
2013-09-29 17:28:42 +04:00
def _old_poll_helper ( origmap , typename ,
2013-07-07 21:53:37 +04:00
active_list , inactive_list ,
2014-06-03 01:17:47 +04:00
lookup_func , build_func ) :
2013-07-07 21:53:37 +04:00
"""
Helper routine for old style split API libvirt polling .
2014-06-03 01:17:47 +04:00
@origmap : Pre - existing mapping of objects , with connkey - > obj mapping .
2013-07-07 21: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-03 01:17:47 +04:00
args of ( raw libvirt object , connkey )
2013-07-07 21:53:37 +04:00
"""
current = { }
new = { }
newActiveNames = [ ]
newInactiveNames = [ ]
try :
newActiveNames = active_list ( )
except Exception , e :
logging . debug ( " Unable to list active %s s: %s " , typename , e )
try :
newInactiveNames = inactive_list ( )
except Exception , e :
logging . debug ( " Unable to list inactive %s s: %s " , typename , e )
2014-06-02 20:17:21 +04:00
def check_obj ( name ) :
obj = None
2014-06-03 01:17:47 +04:00
connkey = name
2013-07-07 21:53:37 +04:00
2014-06-03 01:17:47 +04:00
if connkey not in origmap :
2015-04-10 16:15:44 +03:00
try :
obj = lookup_func ( name )
except Exception , e :
logging . debug ( " Could not fetch %s ' %s ' : %s " ,
typename , connkey , e )
return
2014-06-02 20:17:21 +04:00
2013-07-07 21:53:37 +04:00
# Object is brand new this period
2014-06-03 01:17:47 +04:00
current [ connkey ] = build_func ( obj , connkey )
new [ connkey ] = current [ connkey ]
2013-07-07 21:53:37 +04:00
else :
# Previously known object
2014-06-03 01:17:47 +04:00
current [ connkey ] = origmap [ connkey ]
del ( origmap [ connkey ] )
2013-07-07 21:53:37 +04:00
for name in newActiveNames + newInactiveNames :
try :
check_obj ( name )
except :
logging . exception ( " Couldn ' t fetch %s ' %s ' " , typename , name )
2015-04-10 19:52:42 +03:00
return ( origmap . values ( ) , new . values ( ) , current . values ( ) )
2013-07-07 21:53:37 +04:00
2013-09-29 17:28:42 +04:00
def fetch_nets ( backend , origmap , build_func ) :
2013-07-07 21:53:37 +04:00
name = " network "
2013-10-06 18:08:04 +04:00
if backend . check_support (
2015-09-17 22:18:22 +03:00
backend . SUPPORT_CONN_LISTALLNETWORKS ) and not FORCE_OLD_POLL :
2013-09-29 17:28:42 +04:00
return _new_poll_helper ( origmap , name ,
2014-06-03 01:17:47 +04:00
backend . listAllNetworks , build_func )
2013-07-07 21:53:37 +04:00
else :
active_list = backend . listNetworks
inactive_list = backend . listDefinedNetworks
lookup_func = backend . networkLookupByName
2013-09-29 17:28:42 +04:00
return _old_poll_helper ( origmap , name ,
2013-07-07 21:53:37 +04:00
active_list , inactive_list ,
2014-06-03 01:17:47 +04:00
lookup_func , build_func )
2013-07-07 21:53:37 +04:00
2013-09-29 17:28:42 +04:00
def fetch_pools ( backend , origmap , build_func ) :
2013-07-07 21:53:37 +04:00
name = " pool "
2013-10-06 18:08:04 +04:00
if backend . check_support (
2015-09-17 22:18:22 +03:00
backend . SUPPORT_CONN_LISTALLSTORAGEPOOLS ) and not FORCE_OLD_POLL :
2013-09-29 17:28:42 +04:00
return _new_poll_helper ( origmap , name ,
2014-06-03 01:17:47 +04:00
backend . listAllStoragePools , build_func )
2013-07-07 21:53:37 +04:00
else :
active_list = backend . listStoragePools
inactive_list = backend . listDefinedStoragePools
lookup_func = backend . storagePoolLookupByName
2013-09-29 17:28:42 +04:00
return _old_poll_helper ( origmap , name ,
2013-07-07 21:53:37 +04:00
active_list , inactive_list ,
2014-06-03 01:17:47 +04:00
lookup_func , build_func )
2013-07-07 21:53:37 +04:00
2013-09-29 17:31:39 +04:00
def fetch_volumes ( backend , pool , origmap , build_func ) :
name = " volume "
2013-10-06 18:08:04 +04:00
if backend . check_support (
2015-09-17 22:18:22 +03:00
backend . SUPPORT_POOL_LISTALLVOLUMES , pool ) and not FORCE_OLD_POLL :
2013-09-29 17:31:39 +04:00
return _new_poll_helper ( origmap , name ,
2014-06-03 01:17:47 +04:00
pool . listAllVolumes , build_func )
2013-09-29 17:31:39 +04:00
else :
active_list = pool . listVolumes
2015-07-10 15:07:03 +03:00
def inactive_list ( ) :
return [ ]
2013-09-29 17: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 17:28:42 +04:00
def fetch_interfaces ( backend , origmap , build_func ) :
2013-07-07 21:53:37 +04:00
name = " interface "
2013-10-06 18:08:04 +04:00
if backend . check_support (
2015-09-17 22:18:22 +03:00
backend . SUPPORT_CONN_LISTALLINTERFACES ) and not FORCE_OLD_POLL :
2013-09-29 17:28:42 +04:00
return _new_poll_helper ( origmap , name ,
2014-06-03 01:17:47 +04:00
backend . listAllInterfaces , build_func )
2013-07-07 21:53:37 +04:00
else :
active_list = backend . listInterfaces
inactive_list = backend . listDefinedInterfaces
lookup_func = backend . interfaceLookupByName
2013-09-29 17:28:42 +04:00
return _old_poll_helper ( origmap , name ,
2013-07-07 21:53:37 +04:00
active_list , inactive_list ,
lookup_func , build_func )
2013-09-29 17:28:42 +04:00
def fetch_nodedevs ( backend , origmap , build_func ) :
2013-07-07 21:53:37 +04:00
name = " nodedev "
2013-10-06 18:08:04 +04:00
if backend . check_support (
2015-09-17 22:18:22 +03:00
backend . SUPPORT_CONN_LISTALLDEVICES ) and not FORCE_OLD_POLL :
2013-09-29 17:39:55 +04:00
return _new_poll_helper ( origmap , name ,
2014-06-03 01:17:47 +04:00
backend . listAllDevices , build_func )
2013-09-29 17:39:55 +04:00
else :
2015-07-10 15:07:03 +03:00
def active_list ( ) :
return backend . listDevices ( None , 0 )
def inactive_list ( ) :
return [ ]
2013-09-29 17: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 21:53:37 +04:00
2013-09-29 17:28:42 +04:00
def _old_fetch_vms ( backend , origmap , build_func ) :
2013-07-07 21: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
2014-06-03 01:17:47 +04:00
for vm in origmap . values ( ) :
2013-07-07 21:53:37 +04:00
if vm . is_active ( ) :
oldActiveIDs [ vm . get_id ( ) ] = vm
else :
oldInactiveNames [ vm . get_name ( ) ] = vm
try :
newActiveIDs = backend . listDomainsID ( )
except Exception , e :
logging . debug ( " Unable to list active domains: %s " , e )
try :
newInactiveNames = backend . listDefinedDomains ( )
except Exception , e :
logging . exception ( " Unable to list inactive domains: %s " , e )
def add_vm ( vm ) :
2014-06-03 01:17:47 +04:00
connkey = vm . get_name ( )
2013-07-07 21:53:37 +04:00
2014-06-03 01:17:47 +04:00
current [ connkey ] = vm
del ( origmap [ connkey ] )
2013-07-07 21:53:37 +04:00
2014-06-03 01:17:47 +04:00
def check_new ( rawvm , connkey ) :
if connkey in origmap :
vm = origmap [ connkey ]
del ( origmap [ connkey ] )
2013-07-07 21:53:37 +04:00
else :
2014-06-03 01:17:47 +04:00
vm = build_func ( rawvm , connkey )
new [ connkey ] = vm
2013-07-07 21:53:37 +04:00
2014-06-03 01:17:47 +04:00
current [ connkey ] = vm
2013-07-07 21: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-03 01:17:47 +04:00
connkey = vm . name ( )
2013-07-07 21:53:37 +04:00
2014-06-03 01:17:47 +04:00
check_new ( vm , connkey )
2013-07-07 21:53:37 +04:00
except :
logging . exception ( " Couldn ' t fetch domain id ' %s ' " , _id )
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-03 01:17:47 +04:00
connkey = name
2013-07-07 21:53:37 +04:00
2014-06-03 01:17:47 +04:00
check_new ( vm , connkey )
2013-07-07 21:53:37 +04:00
except :
logging . exception ( " Couldn ' t fetch domain ' %s ' " , name )
2015-05-07 18:10:20 +03:00
return ( origmap . values ( ) , new . values ( ) , current . values ( ) )
2013-07-07 21:53:37 +04:00
2013-09-29 17:28:42 +04:00
def fetch_vms ( backend , origmap , build_func ) :
2013-07-07 21:53:37 +04:00
name = " domain "
2013-10-06 18:08:04 +04:00
if backend . check_support (
2014-06-03 01:17:47 +04:00
backend . SUPPORT_CONN_LISTALLDOMAINS ) :
2013-09-29 17:28:42 +04:00
return _new_poll_helper ( origmap , name ,
2014-06-03 01:17:47 +04:00
backend . listAllDomains , build_func )
2013-07-07 21:53:37 +04:00
else :
2013-09-29 17:28:42 +04:00
return _old_fetch_vms ( backend , origmap , build_func )