<s> """<STR_LIT>""" <EOL> """<STR_LIT>""" <EOL> import errno <EOL> import logging <EOL> from logging . handlers import SysLogHandler <EOL> import os <EOL> import pwd <EOL> import signal <EOL> import subprocess <EOL> import sys <EOL> import time <EOL> from SBusPythonFacade . SBus import SBus <EOL> from SBusPythonFacade . SBusDatagram import SBusDatagram <EOL> from SBusPythonFacade . SBusFileDescription import SBUS_FD_OUTPUT_OBJECT <EOL> from SBusPythonFacade . SBusStorletCommand import SBUS_CMD_DAEMON_STATUS <EOL> from SBusPythonFacade . SBusStorletCommand import SBUS_CMD_HALT <EOL> from SBusPythonFacade . SBusStorletCommand import SBUS_CMD_PING <EOL> from SBusPythonFacade . SBusStorletCommand import SBUS_CMD_START_DAEMON <EOL> from SBusPythonFacade . SBusStorletCommand import SBUS_CMD_STOP_DAEMON <EOL> from SBusPythonFacade . SBusStorletCommand import SBUS_CMD_STOP_DAEMONS <EOL> class daemon_factory ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , path , logger ) : <EOL> """<STR_LIT>""" <EOL> self . logger = logger <EOL> self . pipe_path = path <EOL> self . storlet_name_to_pipe_name = dict ( ) <EOL> self . storlet_name_to_pid = dict ( ) <EOL> self . NUM_OF_TRIES_PINGING_STARTING_DAEMON = <NUM_LIT:10> <EOL> def get_jvm_args ( self , daemon_language , storlet_path , storlet_name , <EOL> pool_size , uds_path , log_level , container_id ) : <EOL> """<STR_LIT>""" <EOL> str_library_path = "<STR_LIT>" <EOL> str_prfx = "<STR_LIT>" <EOL> str_dmn_clspth = str_prfx + '<STR_LIT::>' <EOL> str_dmn_clspth = str_dmn_clspth + str_prfx + '<STR_LIT>' <EOL> str_dmn_clspth = str_dmn_clspth + str_prfx + '<STR_LIT>' <EOL> str_dmn_clspth = str_dmn_clspth + str_prfx + '<STR_LIT>' <EOL> str_dmn_clspth = str_dmn_clspth + str_prfx + '<STR_LIT>' <EOL> str_dmn_clspth = str_dmn_clspth + str_prfx + '<STR_LIT>' <EOL> str_dmn_clspth = str_dmn_clspth + str_prfx + '<STR_LIT>' <EOL> str_dmn_clspth = str_dmn_clspth + str_prfx + '<STR_LIT>' <EOL> str_dmn_clspth = str_dmn_clspth + storlet_path <EOL> self . logger . debug ( '<STR_LIT>' % daemon_language ) <EOL> self . logger . debug ( '<STR_LIT>' % str_dmn_clspth ) <EOL> self . logger . debug ( '<STR_LIT>' % storlet_name ) <EOL> self . logger . debug ( '<STR_LIT>' % pool_size ) <EOL> self . logger . debug ( '<STR_LIT>' % uds_path ) <EOL> self . logger . debug ( '<STR_LIT>' % log_level ) <EOL> str_daemon_main_class = "<STR_LIT>" <EOL> n_error_id = <NUM_LIT:0> <EOL> error_text = '<STR_LIT>' <EOL> pargs = [ ] <EOL> if daemon_language == "<STR_LIT>" : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> if os . environ . get ( '<STR_LIT>' ) : <EOL> str_dmn_clspth = os . environ [ '<STR_LIT>' ] + '<STR_LIT::>' + str_dmn_clspth <EOL> if os . environ . get ( '<STR_LIT>' ) : <EOL> str_library_path = os . environ [ '<STR_LIT>' ] + '<STR_LIT::>' + str_library_path <EOL> os . environ [ '<STR_LIT>' ] = str_dmn_clspth <EOL> os . environ [ '<STR_LIT>' ] = str_library_path <EOL> pargs = [ str ( '<STR_LIT>' ) , <EOL> str ( str_daemon_main_class ) , <EOL> str ( storlet_name ) , <EOL> str ( uds_path ) , <EOL> str ( log_level ) , <EOL> str ( '<STR_LIT>' % pool_size ) , <EOL> str ( container_id ) ] <EOL> str_pargs = '<STR_LIT:U+0020>' . join ( map ( str , pargs ) ) <EOL> self . logger . debug ( '<STR_LIT>' % str_pargs ) <EOL> else : <EOL> n_error_id = - <NUM_LIT:1> <EOL> error_text = "<STR_LIT>" % pargs <EOL> self . logger . error ( error_text ) <EOL> return n_error_id , error_text , pargs <EOL> def spawn_subprocess ( self , pargs ) : <EOL> """<STR_LIT>""" <EOL> b_status = True <EOL> error_text = '<STR_LIT>' <EOL> try : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> self . logger . debug ( '<STR_LIT>' . format ( str ( pargs ) ) ) <EOL> dn = open ( '<STR_LIT>' , '<STR_LIT:w>' ) <EOL> daemon_p = subprocess . Popen ( pargs , <EOL> stdout = dn , <EOL> stderr = subprocess . PIPE , <EOL> shell = False ) <EOL> logger_p = subprocess . Popen ( '<STR_LIT>' , <EOL> stdin = daemon_p . stderr , <EOL> stdout = dn , <EOL> stderr = dn , <EOL> shell = False ) <EOL> jvm_pid = daemon_p . pid <EOL> time . sleep ( <NUM_LIT:1> ) <EOL> self . logger . debug ( '<STR_LIT>' . format ( jvm_pid ) ) <EOL> self . logger . debug ( '<STR_LIT>' . format ( logger_p . pid ) ) <EOL> storlet_name = pargs [ <NUM_LIT:2> ] <EOL> b_status , error_text = self . get_process_status_by_pid ( <EOL> jvm_pid , storlet_name ) <EOL> if b_status : <EOL> self . logger . debug ( '<STR_LIT>' + <EOL> '<STR_LIT>' . <EOL> format ( storlet_name , jvm_pid ) ) <EOL> self . storlet_name_to_pid [ storlet_name ] = jvm_pid <EOL> b_status , error_text = self . wait_for_daemon_to_initialize ( storlet_name ) <EOL> if not b_status : <EOL> raise '<STR_LIT>' <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> error_text = '<STR_LIT:OK>' <EOL> except Exception as e : <EOL> b_status = False <EOL> error_text = '<STR_LIT>' % str ( pargs ) <EOL> self . logger . error ( error_text ) <EOL> self . logger . error ( '<STR_LIT>' % str ( e ) ) <EOL> return b_status , error_text <EOL> def wait_for_daemon_to_initialize ( self , storlet_name ) : <EOL> """<STR_LIT>""" <EOL> storlet_pipe_name = self . storlet_name_to_pipe_name [ storlet_name ] <EOL> self . logger . debug ( '<STR_LIT>' . <EOL> format ( storlet_name , storlet_pipe_name ) ) <EOL> read_fd , write_fd = os . pipe ( ) <EOL> dtg = SBusDatagram . create_service_datagram ( SBUS_CMD_PING , write_fd ) <EOL> b_status = False <EOL> error_text = "<STR_LIT>" <EOL> for i in range ( self . NUM_OF_TRIES_PINGING_STARTING_DAEMON ) : <EOL> ret = SBus . send ( storlet_pipe_name , dtg ) <EOL> if ( ret >= <NUM_LIT:0> ) : <EOL> resp = os . read ( read_fd , <NUM_LIT> ) <EOL> if '<STR_LIT:OK>' == resp : <EOL> b_status = True <EOL> error_text = '<STR_LIT:OK>' <EOL> break <EOL> time . sleep ( <NUM_LIT:1> ) <EOL> os . close ( read_fd ) <EOL> os . close ( write_fd ) <EOL> return b_status , error_text <EOL> def process_start_daemon ( self , daemon_language , storlet_path , storlet_name , <EOL> pool_size , uds_path , log_level , container_id ) : <EOL> """<STR_LIT>""" <EOL> b_status = True <EOL> error_text = '<STR_LIT>' <EOL> pargs = [ ] <EOL> n_error_id , error_text , pargs = self . get_jvm_args ( daemon_language , <EOL> storlet_path , <EOL> storlet_name , <EOL> pool_size , <EOL> uds_path , <EOL> log_level , <EOL> container_id ) <EOL> if <NUM_LIT:0> != n_error_id : <EOL> self . logger . debug ( '<STR_LIT>' . <EOL> format ( storlet_name ) ) <EOL> b_status = False <EOL> if b_status : <EOL> self . logger . debug ( '<STR_LIT>' . <EOL> format ( storlet_name , uds_path ) ) <EOL> self . storlet_name_to_pipe_name [ storlet_name ] = uds_path <EOL> self . logger . debug ( '<STR_LIT>' . <EOL> format ( storlet_name ) ) <EOL> b_status , eror_text = self . get_process_status_by_name ( storlet_name ) <EOL> if b_status : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> self . logger . debug ( error_text ) <EOL> else : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> self . logger . debug ( error_text ) <EOL> b_status , error_text = self . spawn_subprocess ( pargs ) <EOL> return b_status , error_text <EOL> def get_process_status_by_name ( self , storlet_name ) : <EOL> """<STR_LIT>""" <EOL> self . logger . debug ( '<STR_LIT>' . format ( storlet_name ) ) <EOL> self . logger . debug ( '<STR_LIT>' . <EOL> format ( str ( self . storlet_name_to_pid . keys ( ) ) ) ) <EOL> b_status = False <EOL> error_text = '<STR_LIT>' <EOL> self . logger . debug ( '<STR_LIT>' . <EOL> format ( storlet_name ) ) <EOL> daemon_pid = self . storlet_name_to_pid . get ( storlet_name , - <NUM_LIT:1> ) <EOL> if - <NUM_LIT:1> != daemon_pid : <EOL> b_status , error_text = self . get_process_status_by_pid ( <EOL> daemon_pid , storlet_name ) <EOL> else : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> self . logger . debug ( error_text ) <EOL> return b_status , error_text <EOL> def get_process_status_by_pid ( self , daemon_pid , storlet_name ) : <EOL> """<STR_LIT>""" <EOL> b_status = False <EOL> error_text = '<STR_LIT>' <EOL> obtained_pid = <NUM_LIT:0> <EOL> obtained_code = <NUM_LIT:0> <EOL> try : <EOL> obtained_pid , obtained_code = os . waitpid ( daemon_pid , os . WNOHANG ) <EOL> error_text = '<STR_LIT>' . format ( storlet_name , obtained_pid , obtained_code ) <EOL> self . logger . debug ( error_text ) <EOL> except OSError as err : <EOL> if err . errno == errno . ESRCH : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> elif err . errno == errno . EPERM : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> else : <EOL> error_text = '<STR_LIT>' <EOL> else : <EOL> if <NUM_LIT:0> == obtained_pid and <NUM_LIT:0> == obtained_code : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> b_status = True <EOL> else : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> self . logger . debug ( error_text ) <EOL> return b_status , error_text <EOL> def process_kill ( self , storlet_name ) : <EOL> """<STR_LIT>""" <EOL> self . logger . debug ( '<STR_LIT>' . format ( storlet_name ) ) <EOL> b_success = True <EOL> error_text = '<STR_LIT>' <EOL> dmn_pid = self . storlet_name_to_pid . get ( storlet_name , - <NUM_LIT:1> ) <EOL> self . logger . debug ( '<STR_LIT>' . format ( dmn_pid ) ) <EOL> if - <NUM_LIT:1> != dmn_pid : <EOL> try : <EOL> os . kill ( dmn_pid , signal . SIGKILL ) <EOL> obtained_pid , obtained_code = os . waitpid ( dmn_pid , os . WNOHANG ) <EOL> error_text = '<STR_LIT>' . format ( storlet_name , obtained_pid , obtained_code ) <EOL> self . logger . debug ( error_text ) <EOL> except Exception : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> self . storlet_name_to_pid . pop ( storlet_name ) <EOL> else : <EOL> error_text = '<STR_LIT>' . format ( storlet_name ) <EOL> b_success = False <EOL> return b_success , error_text <EOL> def process_kill_all ( self ) : <EOL> """<STR_LIT>""" <EOL> for storlet_name in self . storlet_name_to_pid . keys ( ) : <EOL> self . process_kill ( storlet_name ) <EOL> return True , '<STR_LIT:OK>' <EOL> def shutdown_all_processes ( self ) : <EOL> """<STR_LIT>""" <EOL> answer = '<STR_LIT>' <EOL> for storlet_name in self . storlet_name_to_pid . keys ( ) : <EOL> self . shutdown_process ( storlet_name ) <EOL> answer += storlet_name + '<STR_LIT>' <EOL> self . logger . info ( '<STR_LIT>' ) <EOL> self . logger . info ( answer ) <EOL> return True , answer <EOL> def shutdown_process ( self , storlet_name ) : <EOL> """<STR_LIT>""" <EOL> b_status = False <EOL> self . logger . debug ( '<STR_LIT>' . format ( storlet_name ) ) <EOL> storlet_pipe_name = self . storlet_name_to_pipe_name [ storlet_name ] <EOL> self . logger . debug ( '<STR_LIT>' . <EOL> format ( storlet_name , storlet_pipe_name ) ) <EOL> read_fd , write_fd = os . pipe ( ) <EOL> dtg = SBusDatagram . create_service_datagram ( SBUS_CMD_HALT , write_fd ) <EOL> SBus . send ( storlet_pipe_name , dtg ) <EOL> os . close ( read_fd ) <EOL> os . close ( write_fd ) <EOL> dmn_pid = self . storlet_name_to_pid . get ( storlet_name , - <NUM_LIT:1> ) <EOL> self . logger . debug ( '<STR_LIT>' . format ( dmn_pid ) ) <EOL> if - <NUM_LIT:1> != dmn_pid : <EOL> os . waitpid ( dmn_pid , <NUM_LIT:0> ) <EOL> self . storlet_name_to_pid . pop ( storlet_name ) <EOL> b_status = True <EOL> return b_status <EOL> def dispatch_command ( self , dtg , container_id ) : <EOL> """<STR_LIT>""" <EOL> b_status = False <EOL> error_text = '<STR_LIT>' <EOL> b_iterate = True <EOL> command = - <NUM_LIT:1> <EOL> try : <EOL> command = dtg . get_command ( ) <EOL> except Exception : <EOL> error_text = "<STR_LIT>" "<STR_LIT>" <EOL> b_status = False <EOL> self . logger . error ( error_text ) <EOL> else : <EOL> self . logger . debug ( "<STR_LIT>" . format ( command ) ) <EOL> prms = dtg . get_exec_params ( ) <EOL> if command == SBUS_CMD_START_DAEMON : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> self . logger . debug ( '<STR_LIT>' % str ( prms ) ) <EOL> b_status , error_text = self . process_start_daemon ( prms [ '<STR_LIT>' ] , <EOL> prms [ '<STR_LIT>' ] , <EOL> prms [ '<STR_LIT>' ] , <EOL> prms [ '<STR_LIT>' ] , <EOL> prms [ '<STR_LIT>' ] , <EOL> prms [ '<STR_LIT>' ] , <EOL> container_id ) <EOL> elif command == SBUS_CMD_STOP_DAEMON : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> b_status , error_text = self . process_kill ( prms [ '<STR_LIT>' ] ) <EOL> elif command == SBUS_CMD_DAEMON_STATUS : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> b_status , error_text = self . get_process_status_by_name ( prms [ '<STR_LIT>' ] ) <EOL> elif command == SBUS_CMD_STOP_DAEMONS : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> b_status , error_text = self . process_kill_all ( ) <EOL> b_iterate = False <EOL> elif command == SBUS_CMD_HALT : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> b_status , error_text = self . shutdown_all_processes ( ) <EOL> b_iterate = False <EOL> elif command == SBUS_CMD_PING : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> b_status = True <EOL> error_text = '<STR_LIT:OK>' <EOL> else : <EOL> b_status = False <EOL> error_text = "<STR_LIT>" % command <EOL> self . logger . error ( error_text ) <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> return b_status , error_text , b_iterate <EOL> def main_loop ( self , container_id ) : <EOL> """<STR_LIT>""" <EOL> sbus = SBus ( ) <EOL> fd = sbus . create ( self . pipe_path ) <EOL> if fd < <NUM_LIT:0> : <EOL> self . logger . error ( "<STR_LIT>" ) <EOL> return <EOL> b_iterate = True <EOL> b_status = True <EOL> error_text = '<STR_LIT>' <EOL> while b_iterate : <EOL> rc = sbus . listen ( fd ) <EOL> if rc < <NUM_LIT:0> : <EOL> self . logger . error ( "<STR_LIT>" ) <EOL> return <EOL> self . logger . debug ( "<STR_LIT>" ) <EOL> dtg = sbus . receive ( fd ) <EOL> if not dtg : <EOL> self . logger . error ( "<STR_LIT>" ) <EOL> return <EOL> try : <EOL> outfd = dtg . get_first_file_of_type ( SBUS_FD_OUTPUT_OBJECT ) <EOL> except Exception : <EOL> self . logger . error ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> continue <EOL> else : <EOL> self . logger . debug ( "<STR_LIT>" % outfd . fileno ( ) ) <EOL> b_status , error_text , b_iterate = self . dispatch_command ( dtg , container_id ) <EOL> self . log_and_report ( outfd , b_status , error_text ) <EOL> outfd . close ( ) <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> def log_and_report ( self , outfd , b_status , error_text ) : <EOL> """<STR_LIT>""" <EOL> answer = str ( b_status ) + '<STR_LIT>' + error_text <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> self . logger . debug ( '<STR_LIT>' % answer ) <EOL> try : <EOL> outfd . write ( answer ) <EOL> self . logger . debug ( "<STR_LIT>" ) <EOL> except Exception : <EOL> self . logger . debug ( '<STR_LIT>' % answer ) <EOL> def start_logger ( logger_name , log_level , container_id ) : <EOL> """<STR_LIT>""" <EOL> logging . raiseExceptions = False <EOL> log_level = log_level . upper ( ) <EOL> if ( log_level == '<STR_LIT>' ) : <EOL> level = logging . DEBUG <EOL> elif ( log_level == '<STR_LIT>' ) : <EOL> level = logging . INFO <EOL> elif ( log_level == '<STR_LIT>' ) : <EOL> level = logging . WARN <EOL> elif ( log_level == '<STR_LIT>' ) : <EOL> level = logging . CRITICAL <EOL> else : <EOL> level = logging . ERROR <EOL> logger = logging . getLogger ( "<STR_LIT>" + container_id + "<STR_LIT>" + logger_name ) <EOL> if log_level == '<STR_LIT>' : <EOL> logging . disable ( logging . CRITICAL ) <EOL> else : <EOL> logger . setLevel ( level ) <EOL> for i in range ( <NUM_LIT:0> , <NUM_LIT:4> ) : <EOL> try : <EOL> sysLogh = SysLogHandler ( '<STR_LIT>' ) <EOL> break <EOL> except Exception as e : <EOL> if i < <NUM_LIT:3> : <EOL> time . sleep ( <NUM_LIT:1> ) <EOL> else : <EOL> raise e <EOL> str_format = '<STR_LIT>' + '<STR_LIT>' + '<STR_LIT>' <EOL> formatter = logging . Formatter ( str_format ) <EOL> sysLogh . setFormatter ( formatter ) <EOL> sysLogh . setLevel ( level ) <EOL> logger . addHandler ( sysLogh ) <EOL> return logger <EOL> def usage ( ) : <EOL> """<STR_LIT>""" <EOL> print ( "<STR_LIT>" ) <EOL> def main ( argv ) : <EOL> """<STR_LIT>""" <EOL> if ( len ( argv ) != <NUM_LIT:3> ) : <EOL> usage ( ) <EOL> return <EOL> pipe_path = argv [ <NUM_LIT:0> ] <EOL> log_level = argv [ <NUM_LIT:1> ] <EOL> container_id = argv [ <NUM_LIT:2> ] <EOL> logger = start_logger ( "<STR_LIT>" , log_level , container_id ) <EOL> logger . debug ( "<STR_LIT>" ) <EOL> SBus . start_logger ( "<STR_LIT>" , container_id = container_id ) <EOL> pw = pwd . getpwnam ( '<STR_LIT>' ) <EOL> os . setresgid ( pw . pw_gid , pw . pw_gid , pw . pw_gid ) <EOL> os . setresuid ( pw . pw_uid , pw . pw_uid , pw . pw_uid ) <EOL> factory = daemon_factory ( pipe_path , logger ) <EOL> factory . main_loop ( container_id ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> main ( sys . argv [ <NUM_LIT:1> : ] ) </s>
