<s> """<STR_LIT>""" <EOL> import datetime <EOL> import thread <EOL> import traceback <EOL> from novaclient import v1_1 as novaclient <EOL> from eventlet import greenpool <EOL> from nova import db <EOL> from nova import flags <EOL> from nova import log as logging <EOL> from nova import utils <EOL> FLAGS = flags . FLAGS <EOL> flags . DEFINE_integer ( '<STR_LIT>' , <NUM_LIT> , <EOL> '<STR_LIT>' ) <EOL> flags . DEFINE_integer ( '<STR_LIT>' , <NUM_LIT:3> , <EOL> '<STR_LIT>' ) <EOL> class ZoneState ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . is_active = True <EOL> self . name = None <EOL> self . capabilities = None <EOL> self . attempt = <NUM_LIT:0> <EOL> self . last_seen = datetime . datetime . min <EOL> self . last_exception = None <EOL> self . last_exception_time = None <EOL> def update_credentials ( self , zone ) : <EOL> """<STR_LIT>""" <EOL> self . zone_id = zone . id <EOL> self . api_url = zone . api_url <EOL> self . username = zone . username <EOL> self . password = zone . password <EOL> def update_metadata ( self , zone_metadata ) : <EOL> """<STR_LIT>""" <EOL> self . last_seen = utils . utcnow ( ) <EOL> self . attempt = <NUM_LIT:0> <EOL> self . name = zone_metadata . get ( "<STR_LIT:name>" , "<STR_LIT>" ) <EOL> self . capabilities = "<STR_LIT:U+002CU+0020>" . join ( [ "<STR_LIT>" % ( k , v ) <EOL> for k , v in zone_metadata . iteritems ( ) if k != '<STR_LIT:name>' ] ) <EOL> self . is_active = True <EOL> def to_dict ( self ) : <EOL> return dict ( name = self . name , capabilities = self . capabilities , <EOL> is_active = self . is_active , api_url = self . api_url , <EOL> id = self . zone_id ) <EOL> def log_error ( self , exception ) : <EOL> """<STR_LIT>""" <EOL> self . last_exception = exception <EOL> self . last_exception_time = utils . utcnow ( ) <EOL> api_url = self . api_url <EOL> logging . warning ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) % locals ( ) ) <EOL> max_errors = FLAGS . zone_failures_to_offline <EOL> self . attempt += <NUM_LIT:1> <EOL> if self . attempt >= max_errors : <EOL> self . is_active = False <EOL> logging . error ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) % locals ( ) ) <EOL> def _call_novaclient ( zone ) : <EOL> """<STR_LIT>""" <EOL> client = novaclient . Client ( zone . username , zone . password , None , <EOL> zone . api_url ) <EOL> return client . zones . info ( ) . _info <EOL> def _poll_zone ( zone ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( _ ( "<STR_LIT>" ) % zone . api_url ) <EOL> try : <EOL> zone . update_metadata ( _call_novaclient ( zone ) ) <EOL> except Exception , e : <EOL> zone . log_error ( traceback . format_exc ( ) ) <EOL> class ZoneManager ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . last_zone_db_check = datetime . datetime . min <EOL> self . zone_states = { } <EOL> self . service_states = { } <EOL> self . green_pool = greenpool . GreenPool ( ) <EOL> def get_zone_list ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ zone . to_dict ( ) for zone in self . zone_states . values ( ) ] <EOL> def get_host_list ( self ) : <EOL> """<STR_LIT>""" <EOL> all_hosts = self . service_states . keys ( ) <EOL> ret = [ ] <EOL> for host in self . service_states : <EOL> for svc in self . service_states [ host ] : <EOL> ret . append ( { "<STR_LIT>" : svc , "<STR_LIT>" : host } ) <EOL> return ret <EOL> def get_zone_capabilities ( self , context ) : <EOL> """<STR_LIT>""" <EOL> hosts_dict = self . service_states <EOL> combined = { } <EOL> stale_host_services = { } <EOL> for host , host_dict in hosts_dict . iteritems ( ) : <EOL> for service_name , service_dict in host_dict . iteritems ( ) : <EOL> if not service_dict . get ( "<STR_LIT>" , True ) : <EOL> continue <EOL> if self . host_service_caps_stale ( host , service_name ) : <EOL> if host not in stale_host_services : <EOL> stale_host_services [ host ] = [ ] <EOL> stale_host_services [ host ] . append ( service_name ) <EOL> continue <EOL> for cap , value in service_dict . iteritems ( ) : <EOL> if cap == "<STR_LIT>" : <EOL> continue <EOL> key = "<STR_LIT>" % ( service_name , cap ) <EOL> min_value , max_value = combined . get ( key , ( value , value ) ) <EOL> min_value = min ( min_value , value ) <EOL> max_value = max ( max_value , value ) <EOL> combined [ key ] = ( min_value , max_value ) <EOL> self . delete_expired_host_services ( stale_host_services ) <EOL> return combined <EOL> def _refresh_from_db ( self , context ) : <EOL> """<STR_LIT>""" <EOL> zones = db . zone_get_all ( context ) <EOL> existing = self . zone_states . keys ( ) <EOL> db_keys = [ ] <EOL> for zone in zones : <EOL> db_keys . append ( zone . id ) <EOL> if zone . id not in existing : <EOL> self . zone_states [ zone . id ] = ZoneState ( ) <EOL> self . zone_states [ zone . id ] . update_credentials ( zone ) <EOL> keys = self . zone_states . keys ( ) <EOL> for zone_id in keys : <EOL> if zone_id not in db_keys : <EOL> del self . zone_states [ zone_id ] <EOL> def _poll_zones ( self , context ) : <EOL> """<STR_LIT>""" <EOL> self . green_pool . imap ( _poll_zone , self . zone_states . values ( ) ) <EOL> def ping ( self , context = None ) : <EOL> """<STR_LIT>""" <EOL> diff = utils . utcnow ( ) - self . last_zone_db_check <EOL> if diff . seconds >= FLAGS . zone_db_check_interval : <EOL> logging . debug ( _ ( "<STR_LIT>" ) ) <EOL> self . last_zone_db_check = utils . utcnow ( ) <EOL> self . _refresh_from_db ( context ) <EOL> self . _poll_zones ( context ) <EOL> def update_service_capabilities ( self , service_name , host , capabilities ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) % locals ( ) ) <EOL> service_caps = self . service_states . get ( host , { } ) <EOL> capabilities [ "<STR_LIT>" ] = utils . utcnow ( ) <EOL> service_caps [ service_name ] = capabilities <EOL> self . service_states [ host ] = service_caps <EOL> def host_service_caps_stale ( self , host , service ) : <EOL> """<STR_LIT>""" <EOL> allowed_time_diff = FLAGS . periodic_interval * <NUM_LIT:3> <EOL> caps = self . service_states [ host ] [ service ] <EOL> if ( utils . utcnow ( ) - caps [ "<STR_LIT>" ] ) <= datetime . timedelta ( seconds = allowed_time_diff ) : <EOL> return False <EOL> return True <EOL> def delete_expired_host_services ( self , host_services_dict ) : <EOL> """<STR_LIT>""" <EOL> for host , services in host_services_dict . iteritems ( ) : <EOL> service_caps = self . service_states [ host ] <EOL> for service in services : <EOL> del service_caps [ service ] <EOL> if len ( service_caps ) == <NUM_LIT:0> : <EOL> del self . service_states [ host ] </s>
