<s> import os <EOL> import xmlrpclib <EOL> from amqplib . client_0_8 . method_framing import defaultdict <EOL> from django . conf import settings <EOL> from jsonobject . api import JsonObject <EOL> from jsonobject . properties import StringProperty , IntegerProperty <EOL> from dimagi . utils . decorators . memoized import memoized <EOL> from dimagi . utils . logging import notify_exception <EOL> SERVER_STATE_RUNNING = <NUM_LIT:1> <EOL> FAULT_NOT_RUNNING = <NUM_LIT> <EOL> class SupervisorException ( Exception ) : <EOL> pass <EOL> class ProcessInfo ( JsonObject ) : <EOL> host = StringProperty ( ) <EOL> name = StringProperty ( ) <EOL> group = StringProperty ( ) <EOL> start = IntegerProperty ( ) <EOL> stop = IntegerProperty ( ) <EOL> now = IntegerProperty ( ) <EOL> state = IntegerProperty ( ) <EOL> statename = StringProperty ( ) <EOL> spawnerr = StringProperty ( ) <EOL> exitstatus = IntegerProperty ( ) <EOL> stdout_logfile = StringProperty ( ) <EOL> stderr_logfile = StringProperty ( ) <EOL> pid = IntegerProperty ( ) <EOL> def wrap_exception ( ) : <EOL> def decorate ( func ) : <EOL> def call_function ( * args , ** kwargs ) : <EOL> try : <EOL> return func ( * args , ** kwargs ) <EOL> except SupervisorException : <EOL> raise <EOL> except Exception as e : <EOL> message = "<STR_LIT>" . format ( func . __name__ ) <EOL> notify_exception ( None , message ) <EOL> raise SupervisorException ( message , e ) <EOL> return call_function <EOL> return decorate <EOL> class SupervisorApi ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , host ) : <EOL> if not settings . SUPERVISOR_RPC_ENABLED : <EOL> raise SupervisorException ( '<STR_LIT>' <EOL> '<STR_LIT>' . format ( settings . SERVER_ENVIRONMENT ) ) <EOL> self . _url = '<STR_LIT>' . format ( <EOL> username = settings . SUPERVISOR_USERNAME , <EOL> password = settings . SUPERVISOR_PASSWORD , <EOL> host = host <EOL> ) <EOL> self . _server = xmlrpclib . Server ( self . _url ) <EOL> self . check_state ( ) <EOL> @ wrap_exception ( ) <EOL> def check_state ( self ) : <EOL> state = self . _server . supervisor . getState ( ) <EOL> if state [ '<STR_LIT>' ] != SERVER_STATE_RUNNING : <EOL> raise SupervisorException ( '<STR_LIT>' . format ( state [ '<STR_LIT>' ] ) ) <EOL> @ wrap_exception ( ) <EOL> def get_all_process_info ( self ) : <EOL> return [ ProcessInfo . wrap ( info ) for info in self . _server . supervisor . getAllProcessInfo ( ) ] <EOL> @ wrap_exception ( ) <EOL> def get_process_info ( self , name ) : <EOL> return ProcessInfo . wrap ( self . _server . supervisor . getProcessInfo ( name ) ) <EOL> @ wrap_exception ( ) <EOL> def start_process ( self , name , wait = True ) : <EOL> return self . _server . supervisor . startProcess ( name , wait ) <EOL> @ wrap_exception ( ) <EOL> def stop_process ( self , name , wait = True ) : <EOL> try : <EOL> return self . _server . supervisor . stopProcess ( name , wait ) <EOL> except xmlrpclib . Fault as f : <EOL> if f . faultCode == FAULT_NOT_RUNNING : <EOL> return True <EOL> else : <EOL> raise <EOL> @ wrap_exception ( ) <EOL> def restart_process ( self , name , wait = True ) : <EOL> return self . stop_process ( name , wait ) and self . start_process ( name , wait ) <EOL> class HQSupervisorApi ( object ) : <EOL> def __init__ ( self , inventory_group ) : <EOL> self . inventory_group = inventory_group <EOL> self . servers = { <EOL> host : SupervisorApi ( host ) <EOL> for host in settings . ENVIRONMENT_HOSTS [ inventory_group ] <EOL> } <EOL> @ staticmethod <EOL> def _add_host ( process_info , host ) : <EOL> process_info . host = host <EOL> return process_info <EOL> @ memoized <EOL> def get_all_process_info ( self ) : <EOL> return [ <EOL> HQSupervisorApi . _add_host ( process_info , host ) <EOL> for host , server in self . servers . items ( ) <EOL> for process_info in server . get_all_process_info ( ) <EOL> ] <EOL> def refresh_process_infos ( self ) : <EOL> self . get_all_process_info . reset_cache ( self ) <EOL> self . get_all_process_info ( ) <EOL> def _process_info_by_host_name ( self ) : <EOL> mapping = defaultdict ( defaultdict ) <EOL> for info in self . _get_all_process_info ( ) : <EOL> mapping [ info . host ] [ info . name ] = info <EOL> return mapping <EOL> def get_process_info ( self , host , name ) : <EOL> process_info = self . _process_info_by_host_name ( ) [ host ] [ name ] <EOL> return HQSupervisorApi . _add_host ( host , process_info ) <EOL> def start_process ( self , host , name , wait = True ) : <EOL> return self . servers [ host ] . start_process ( name , wait = wait ) <EOL> def stop_process ( self , host , name , wait = True ) : <EOL> return self . servers [ host ] . stop_process ( name , wait = wait ) <EOL> def restart_process ( self , host , name , wait = True ) : <EOL> return self . servers [ host ] . restart_process ( name , wait ) <EOL> class PillowtopSupervisorApi ( HQSupervisorApi ) : <EOL> def __init__ ( self ) : <EOL> super ( PillowtopSupervisorApi , self ) . __init__ ( '<STR_LIT>' ) <EOL> @ memoized <EOL> def get_pillow_process_info ( self , pillow_name ) : <EOL> process_info = [ <EOL> info for info in self . get_all_process_info ( ) <EOL> if pillow_name in info . name <EOL> ] <EOL> try : <EOL> return process_info [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> raise SupervisorException ( '<STR_LIT>' . format ( pillow_name ) ) <EOL> def refresh_process_infos ( self ) : <EOL> self . get_pillow_process_info . reset_cache ( ) <EOL> super ( PillowtopSupervisorApi , self ) . refresh_process_infos ( ) <EOL> def start_pillow ( self , pillow_name ) : <EOL> info = self . get_pillow_process_info ( pillow_name ) <EOL> return self . start_process ( info . host , info . name ) <EOL> def stop_pillow ( self , pillow_name ) : <EOL> info = self . get_pillow_process_info ( pillow_name ) <EOL> return self . stop_process ( info . host , info . name ) <EOL> def restart_pillow ( self , pillow_name ) : <EOL> info = self . get_pillow_process_info ( pillow_name ) <EOL> return self . restart_process ( info . host , info . name ) <EOL> def pillow_supervisor_status ( pillow_name ) : <EOL> return all_pillows_supervisor_status ( [ pillow_name ] ) [ pillow_name ] <EOL> def all_pillows_supervisor_status ( pillow_names ) : <EOL> def status ( state , message = None ) : <EOL> return { <EOL> '<STR_LIT>' : state , <EOL> '<STR_LIT>' : message <EOL> } <EOL> try : <EOL> supervisor = PillowtopSupervisorApi ( ) <EOL> except Exception as e : <EOL> return { name : status ( '<STR_LIT>' , str ( e ) ) for name in pillow_names } <EOL> def get_status ( pillow_name ) : <EOL> try : <EOL> info = supervisor . get_pillow_process_info ( pillow_name ) <EOL> return status ( info . statename ) <EOL> except Exception as e : <EOL> return status ( '<STR_LIT>' , str ( e ) ) <EOL> return { name : get_status ( name ) for name in pillow_names } </s>
