<s> """<STR_LIT>""" <EOL> from oslo_config import cfg <EOL> from oslo_log import log as logging <EOL> from oslo_serialization import jsonutils <EOL> import six <EOL> import six . moves . urllib . parse as urlparse <EOL> from nova . compute import rpcapi as compute_rpcapi <EOL> from nova import exception <EOL> from nova . i18n import _ , _LE <EOL> from nova . virt . xenapi import pool_states <EOL> from nova . virt . xenapi import vm_utils <EOL> LOG = logging . getLogger ( __name__ ) <EOL> xenapi_pool_opts = [ <EOL> cfg . BoolOpt ( '<STR_LIT>' , <EOL> default = True , <EOL> help = '<STR_LIT>' ) , <EOL> ] <EOL> CONF = cfg . CONF <EOL> CONF . register_opts ( xenapi_pool_opts , '<STR_LIT>' ) <EOL> CONF . import_opt ( '<STR_LIT:host>' , '<STR_LIT>' ) <EOL> class ResourcePool ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , session , virtapi ) : <EOL> host_rec = session . host . get_record ( session . host_ref ) <EOL> self . _host_name = host_rec [ '<STR_LIT>' ] <EOL> self . _host_addr = host_rec [ '<STR_LIT:address>' ] <EOL> self . _host_uuid = host_rec [ '<STR_LIT>' ] <EOL> self . _session = session <EOL> self . _virtapi = virtapi <EOL> self . compute_rpcapi = compute_rpcapi . ComputeAPI ( ) <EOL> def undo_aggregate_operation ( self , context , op , aggregate , <EOL> host , set_error ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> if set_error : <EOL> metadata = { pool_states . KEY : pool_states . ERROR } <EOL> aggregate . update_metadata ( metadata ) <EOL> op ( host ) <EOL> except Exception : <EOL> LOG . exception ( _LE ( '<STR_LIT>' <EOL> '<STR_LIT>' ) , <EOL> { '<STR_LIT>' : aggregate . id , '<STR_LIT:host>' : host } ) <EOL> def add_to_aggregate ( self , context , aggregate , host , slave_info = None ) : <EOL> """<STR_LIT>""" <EOL> if not pool_states . is_hv_pool ( aggregate . metadata ) : <EOL> return <EOL> invalid = { pool_states . CHANGING : _ ( '<STR_LIT>' ) , <EOL> pool_states . DISMISSED : _ ( '<STR_LIT>' ) , <EOL> pool_states . ERROR : _ ( '<STR_LIT>' ) } <EOL> if ( aggregate . metadata [ pool_states . KEY ] in invalid . keys ( ) ) : <EOL> raise exception . InvalidAggregateActionAdd ( <EOL> aggregate_id = aggregate . id , <EOL> reason = invalid [ aggregate . metadata [ pool_states . KEY ] ] ) <EOL> if ( aggregate . metadata [ pool_states . KEY ] == pool_states . CREATED ) : <EOL> aggregate . update_metadata ( { pool_states . KEY : pool_states . CHANGING } ) <EOL> if len ( aggregate . hosts ) == <NUM_LIT:1> : <EOL> self . _init_pool ( aggregate . id , aggregate . name ) <EOL> metadata = { '<STR_LIT>' : host , <EOL> host : self . _host_uuid , <EOL> pool_states . KEY : pool_states . ACTIVE } <EOL> aggregate . update_metadata ( metadata ) <EOL> else : <EOL> master_compute = aggregate . metadata [ '<STR_LIT>' ] <EOL> if master_compute == CONF . host and master_compute != host : <EOL> self . _join_slave ( aggregate . id , host , <EOL> slave_info . get ( '<STR_LIT>' ) , <EOL> slave_info . get ( '<STR_LIT:url>' ) , slave_info . get ( '<STR_LIT:user>' ) , <EOL> slave_info . get ( '<STR_LIT>' ) ) <EOL> metadata = { host : slave_info . get ( '<STR_LIT>' ) , } <EOL> aggregate . update_metadata ( metadata ) <EOL> elif master_compute and master_compute != host : <EOL> slave_info = self . _create_slave_info ( ) <EOL> self . compute_rpcapi . add_aggregate_host ( <EOL> context , aggregate , host , master_compute , slave_info ) <EOL> def remove_from_aggregate ( self , context , aggregate , host , slave_info = None ) : <EOL> """<STR_LIT>""" <EOL> slave_info = slave_info or dict ( ) <EOL> if not pool_states . is_hv_pool ( aggregate . metadata ) : <EOL> return <EOL> invalid = { pool_states . CREATED : _ ( '<STR_LIT>' ) , <EOL> pool_states . CHANGING : _ ( '<STR_LIT>' ) , <EOL> pool_states . DISMISSED : _ ( '<STR_LIT>' ) } <EOL> if aggregate . metadata [ pool_states . KEY ] in invalid . keys ( ) : <EOL> raise exception . InvalidAggregateActionDelete ( <EOL> aggregate_id = aggregate . id , <EOL> reason = invalid [ aggregate . metadata [ pool_states . KEY ] ] ) <EOL> master_compute = aggregate . metadata [ '<STR_LIT>' ] <EOL> if master_compute == CONF . host and master_compute != host : <EOL> host_uuid = aggregate . metadata [ host ] <EOL> self . _eject_slave ( aggregate . id , <EOL> slave_info . get ( '<STR_LIT>' ) , host_uuid ) <EOL> aggregate . update_metadata ( { host : None } ) <EOL> elif master_compute == host : <EOL> if len ( aggregate . hosts ) > <NUM_LIT:1> : <EOL> raise exception . InvalidAggregateActionDelete ( <EOL> aggregate_id = aggregate . id , <EOL> reason = _ ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> % host ) <EOL> self . _clear_pool ( aggregate . id ) <EOL> aggregate . update_metadata ( { '<STR_LIT>' : None , host : None } ) <EOL> elif master_compute and master_compute != host : <EOL> slave_info = self . _create_slave_info ( ) <EOL> self . compute_rpcapi . remove_aggregate_host ( <EOL> context , aggregate . id , host , master_compute , slave_info ) <EOL> else : <EOL> raise exception . AggregateError ( aggregate_id = aggregate . id , <EOL> action = '<STR_LIT>' , <EOL> reason = _ ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> % host ) <EOL> def _join_slave ( self , aggregate_id , host , compute_uuid , url , user , passwd ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> args = { '<STR_LIT>' : compute_uuid , <EOL> '<STR_LIT:url>' : url , <EOL> '<STR_LIT:user>' : user , <EOL> '<STR_LIT:password>' : passwd , <EOL> '<STR_LIT>' : jsonutils . dumps ( CONF . xenserver . use_join_force ) , <EOL> '<STR_LIT>' : self . _host_addr , <EOL> '<STR_LIT>' : CONF . xenserver . connection_username , <EOL> '<STR_LIT>' : CONF . xenserver . connection_password , } <EOL> self . _session . call_plugin ( '<STR_LIT>' , '<STR_LIT>' , args ) <EOL> except self . _session . XenAPI . Failure as e : <EOL> LOG . error ( _LE ( "<STR_LIT>" ) , e ) <EOL> raise exception . AggregateError ( aggregate_id = aggregate_id , <EOL> action = '<STR_LIT>' , <EOL> reason = _ ( '<STR_LIT>' <EOL> '<STR_LIT>' ) % host ) <EOL> def _eject_slave ( self , aggregate_id , compute_uuid , host_uuid ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> vm_ref = self . _session . VM . get_by_uuid ( compute_uuid ) <EOL> self . _session . VM . clean_shutdown ( vm_ref ) <EOL> host_ref = self . _session . host . get_by_uuid ( host_uuid ) <EOL> self . _session . pool . eject ( host_ref ) <EOL> except self . _session . XenAPI . Failure as e : <EOL> LOG . error ( _LE ( "<STR_LIT>" ) , e ) <EOL> raise exception . AggregateError ( aggregate_id = aggregate_id , <EOL> action = '<STR_LIT>' , <EOL> reason = six . text_type ( e . details ) ) <EOL> def _init_pool ( self , aggregate_id , aggregate_name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> pool_ref = self . _session . pool . get_all ( ) [ <NUM_LIT:0> ] <EOL> self . _session . pool . set_name_label ( pool_ref , aggregate_name ) <EOL> except self . _session . XenAPI . Failure as e : <EOL> LOG . error ( _LE ( "<STR_LIT>" ) , e ) <EOL> raise exception . AggregateError ( aggregate_id = aggregate_id , <EOL> action = '<STR_LIT>' , <EOL> reason = six . text_type ( e . details ) ) <EOL> def _clear_pool ( self , aggregate_id ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> pool_ref = self . _session . pool . get_all ( ) [ <NUM_LIT:0> ] <EOL> self . _session . pool . set_name_label ( pool_ref , '<STR_LIT>' ) <EOL> except self . _session . XenAPI . Failure as e : <EOL> LOG . error ( _LE ( "<STR_LIT>" ) , e ) <EOL> raise exception . AggregateError ( aggregate_id = aggregate_id , <EOL> action = '<STR_LIT>' , <EOL> reason = six . text_type ( e . details ) ) <EOL> def _create_slave_info ( self ) : <EOL> """<STR_LIT>""" <EOL> sender_url = swap_xapi_host ( <EOL> CONF . xenserver . connection_url , self . _host_addr ) <EOL> return { <EOL> "<STR_LIT:url>" : sender_url , <EOL> "<STR_LIT:user>" : CONF . xenserver . connection_username , <EOL> "<STR_LIT>" : CONF . xenserver . connection_password , <EOL> "<STR_LIT>" : vm_utils . get_this_vm_uuid ( None ) , <EOL> "<STR_LIT>" : self . _host_uuid , <EOL> } <EOL> def swap_xapi_host ( url , host_addr ) : <EOL> """<STR_LIT>""" <EOL> temp_url = urlparse . urlparse ( url ) <EOL> return url . replace ( temp_url . hostname , '<STR_LIT:%s>' % host_addr ) </s>
