<s> __author__ = '<STR_LIT>' <EOL> import errno <EOL> import fcntl <EOL> import sys <EOL> import pwd <EOL> import os <EOL> import time <EOL> import atexit <EOL> import resource <EOL> import signal <EOL> import tempfile <EOL> from scalyr_agent . platform_controller import PlatformController , DefaultPaths , AgentAlreadyRunning <EOL> from scalyr_agent . platform_controller import CannotExecuteAsUser , AgentNotRunning <EOL> import scalyr_agent . util as scalyr_util <EOL> from __scalyr__ import get_install_root , TARBALL_INSTALL , DEV_INSTALL , PACKAGE_INSTALL <EOL> class PosixPlatformController ( PlatformController ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , stdin = '<STR_LIT>' , stdout = '<STR_LIT>' , stderr = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> self . __stdin = stdin <EOL> self . __stdout = stdout <EOL> self . __stderr = stderr <EOL> self . __pidfile = None <EOL> self . __pidfile_from_options = None <EOL> self . __termination_handler = None <EOL> self . __status_handler = None <EOL> self . __no_change_user = False <EOL> self . __init_log_lines = [ ] <EOL> self . __is_initializing = True <EOL> self . __verify_command_in_pidfile = False <EOL> PlatformController . __init__ ( self ) <EOL> def can_handle_current_platform ( self ) : <EOL> """<STR_LIT>""" <EOL> return True <EOL> def add_options ( self , options_parser ) : <EOL> """<STR_LIT>""" <EOL> options_parser . add_option ( <EOL> "<STR_LIT>" , "<STR_LIT>" , dest = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> options_parser . add_option ( "<STR_LIT>" , "<STR_LIT>" , action = "<STR_LIT:store_true>" , dest = "<STR_LIT>" , default = False , <EOL> help = "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> def consume_options ( self , options ) : <EOL> """<STR_LIT>""" <EOL> self . __pidfile_from_options = options . pid_file <EOL> self . __no_change_user = options . no_change_user <EOL> def consume_config ( self , config , path_to_config ) : <EOL> """<STR_LIT>""" <EOL> if config is not None : <EOL> self . __pidfile = os . path . join ( config . agent_log_path , '<STR_LIT>' ) <EOL> self . __verify_command_in_pidfile = config . pidfile_advanced_reuse_guard <EOL> elif self . __pidfile_from_options is None : <EOL> self . __pidfile = os . path . join ( self . default_paths . agent_log_path , '<STR_LIT>' ) <EOL> print >> sys . stderr , '<STR_LIT>' % self . __pidfile <EOL> else : <EOL> self . __pidfile = os . path . abspath ( self . __pidfile_from_options ) <EOL> print >> sys . stderr , '<STR_LIT>' % self . __pidfile <EOL> @ property <EOL> def default_paths ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _install_type == PACKAGE_INSTALL : <EOL> return DefaultPaths ( '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' ) <EOL> elif self . _install_type == TARBALL_INSTALL : <EOL> install_location = get_install_root ( ) <EOL> return DefaultPaths ( os . path . join ( install_location , '<STR_LIT>' ) , <EOL> os . path . join ( install_location , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> os . path . join ( install_location , '<STR_LIT:data>' ) ) <EOL> else : <EOL> assert ( self . _install_type == DEV_INSTALL ) <EOL> base_dir = os . path . join ( os . path . expanduser ( '<STR_LIT>' ) , '<STR_LIT>' ) <EOL> return DefaultPaths ( os . path . join ( base_dir , '<STR_LIT>' ) , <EOL> os . path . join ( base_dir , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> os . path . join ( base_dir , '<STR_LIT:data>' ) ) <EOL> def emit_init_log ( self , logger , include_debug ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( '<STR_LIT>' % scalyr_util . get_pid_tid ( ) ) <EOL> for line_entry in self . __init_log_lines : <EOL> if not line_entry [ <NUM_LIT:1> ] or include_debug : <EOL> logger . info ( '<STR_LIT>' % line_entry [ <NUM_LIT:0> ] ) <EOL> if include_debug : <EOL> logger . info ( '<STR_LIT>' ) <EOL> current_child = os . getpid ( ) <EOL> current_parent = self . __get_ppid ( os . getpid ( ) ) <EOL> remaining_parents = <NUM_LIT:10> <EOL> while current_parent is not None and remaining_parents > <NUM_LIT:0> : <EOL> if _can_read_command_line ( current_parent ) : <EOL> logger . info ( '<STR_LIT>' % ( current_parent , <EOL> _read_command_line ( current_parent ) , <EOL> current_child ) ) <EOL> else : <EOL> logger . info ( '<STR_LIT>' % ( current_parent , current_child ) ) <EOL> current_child = current_parent <EOL> current_parent = self . __get_ppid ( current_parent ) <EOL> remaining_parents -= <NUM_LIT:1> <EOL> return <EOL> def __write_pidfile ( self , debug_logger = None , logger = None ) : <EOL> pidfile = PidfileManager ( self . __pidfile ) <EOL> pidfile . set_options ( debug_logger = debug_logger , logger = logger ) <EOL> writer = pidfile . create_writer ( ) <EOL> release_callback = writer . write_pid ( ) <EOL> if release_callback is None : <EOL> return False <EOL> atexit . register ( release_callback ) <EOL> return True <EOL> def __daemonize ( self ) : <EOL> """<STR_LIT>""" <EOL> original_pid = os . getpid ( ) <EOL> def debug_logger ( message ) : <EOL> self . _log_init_debug ( '<STR_LIT>' % ( message , original_pid , scalyr_util . get_pid_tid ( ) ) ) <EOL> def logger ( message ) : <EOL> self . _log_init ( '<STR_LIT>' % ( message , original_pid , scalyr_util . get_pid_tid ( ) ) ) <EOL> reporter = StatusReporter ( ) <EOL> debug_logger ( '<STR_LIT>' ) <EOL> try : <EOL> pid = os . fork ( ) <EOL> if pid > <NUM_LIT:0> : <EOL> status_line = reporter . read_status ( timeout = <NUM_LIT> , timeout_status = '<STR_LIT>' ) <EOL> if status_line == '<STR_LIT:success>' : <EOL> return False <EOL> elif status_line == '<STR_LIT>' : <EOL> self . is_agent_running ( fail_if_running = True ) <EOL> raise AgentAlreadyRunning ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> elif status_line == '<STR_LIT>' : <EOL> sys . stderr . write ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> return False <EOL> else : <EOL> sys . stderr . write ( "<STR_LIT>" <EOL> "<STR_LIT>" % status_line ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> except OSError , e : <EOL> sys . stderr . write ( "<STR_LIT>" % ( e . errno , e . strerror ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> except SystemExit , e : <EOL> raise e <EOL> except Exception , e : <EOL> reporter . report_status ( '<STR_LIT>' % str ( e ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> debug_logger ( '<STR_LIT>' ) <EOL> try : <EOL> os . chdir ( "<STR_LIT:/>" ) <EOL> os . setsid ( ) <EOL> os . umask ( <NUM_LIT:0> ) <EOL> pid = os . fork ( ) <EOL> if pid > <NUM_LIT:0> : <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> except OSError , e : <EOL> reporter . report_status ( '<STR_LIT>' % ( e . errno , e . strerror ) ) <EOL> sys . stderr . write ( '<STR_LIT>' % ( e . errno , e . strerror ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> except SystemExit , e : <EOL> raise e <EOL> except Exception , e : <EOL> reporter . report_status ( '<STR_LIT>' % str ( e ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> debug_logger ( '<STR_LIT>' ) <EOL> try : <EOL> sys . stdout . flush ( ) <EOL> sys . stderr . flush ( ) <EOL> si = file ( self . __stdin , '<STR_LIT:r>' ) <EOL> so = file ( self . __stdout , '<STR_LIT>' ) <EOL> se = file ( self . __stderr , '<STR_LIT>' , <NUM_LIT:0> ) <EOL> os . dup2 ( si . fileno ( ) , sys . stdin . fileno ( ) ) <EOL> os . dup2 ( so . fileno ( ) , sys . stdout . fileno ( ) ) <EOL> os . dup2 ( se . fileno ( ) , sys . stderr . fileno ( ) ) <EOL> if not self . __write_pidfile ( debug_logger = debug_logger , logger = logger ) : <EOL> reporter . report_status ( '<STR_LIT>' ) <EOL> return False <EOL> reporter . report_status ( '<STR_LIT:success>' ) <EOL> logger ( '<STR_LIT>' ) <EOL> return True <EOL> except Exception , e : <EOL> reporter . report_status ( '<STR_LIT>' % str ( e ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> def __get_ppid ( self , pid ) : <EOL> """<STR_LIT>""" <EOL> if os . path . isfile ( '<STR_LIT>' % pid ) : <EOL> pf = None <EOL> try : <EOL> try : <EOL> pf = file ( '<STR_LIT>' % pid , '<STR_LIT:r>' ) <EOL> ppid = int ( pf . read ( ) . split ( ) [ <NUM_LIT:3> ] ) <EOL> if ppid == <NUM_LIT:0> : <EOL> return None <EOL> else : <EOL> return ppid <EOL> except : <EOL> return None <EOL> finally : <EOL> if pf is not None : <EOL> pf . close ( ) <EOL> else : <EOL> return None <EOL> def _log_init ( self , line , is_debug = False ) : <EOL> """<STR_LIT>""" <EOL> if self . __is_initializing : <EOL> current_time = time . time ( ) <EOL> time_str = '<STR_LIT>' % ( time . strftime ( "<STR_LIT>" , time . gmtime ( current_time ) ) , <EOL> int ( current_time % <NUM_LIT:1> * <NUM_LIT:1000> ) ) <EOL> self . __init_log_lines . append ( [ '<STR_LIT>' % ( line , time_str ) , is_debug ] ) <EOL> def _log_init_debug ( self , line ) : <EOL> """<STR_LIT>""" <EOL> self . _log_init ( line , True ) <EOL> def get_file_owner ( self , file_path ) : <EOL> """<STR_LIT>""" <EOL> return pwd . getpwuid ( os . stat ( file_path ) . st_uid ) . pw_name <EOL> def get_current_user ( self ) : <EOL> """<STR_LIT>""" <EOL> return pwd . getpwuid ( os . geteuid ( ) ) . pw_name <EOL> def set_file_owner ( self , file_path , owner ) : <EOL> """<STR_LIT>""" <EOL> os . chown ( file_path , pwd . getpwnam ( owner ) . pw_uid , - <NUM_LIT:1> ) <EOL> def run_as_user ( self , user_name , script_file , script_binary , script_arguments ) : <EOL> """<STR_LIT>""" <EOL> if os . geteuid ( ) != <NUM_LIT:0> : <EOL> raise CannotExecuteAsUser ( '<STR_LIT>' ) <EOL> if script_file is None : <EOL> raise CannotExecuteAsUser ( '<STR_LIT>' ) <EOL> if self . __no_change_user : <EOL> raise CannotExecuteAsUser ( '<STR_LIT>' ) <EOL> arguments = [ '<STR_LIT>' , '<STR_LIT>' , user_name , sys . executable , script_file , '<STR_LIT>' ] + script_arguments <EOL> print >> sys . stderr , ( '<STR_LIT>' % user_name ) <EOL> return os . execvp ( "<STR_LIT>" , arguments ) <EOL> def is_agent ( self ) : <EOL> """<STR_LIT>""" <EOL> agent_pid = self . __read_pidfile ( ) <EOL> if agent_pid is not None : <EOL> if agent_pid == os . getpid ( ) : <EOL> return <NUM_LIT:0> <EOL> else : <EOL> return agent_pid <EOL> if os . path . isfile ( self . __pidfile ) : <EOL> return - <NUM_LIT:1> <EOL> else : <EOL> return - <NUM_LIT:2> <EOL> def is_agent_running ( self , fail_if_running = False , fail_if_not_running = False ) : <EOL> """<STR_LIT>""" <EOL> self . _log_init_debug ( '<STR_LIT>' % scalyr_util . get_pid_tid ( ) ) <EOL> pid = self . __read_pidfile ( ) <EOL> if fail_if_running and pid is not None : <EOL> raise AgentAlreadyRunning ( '<STR_LIT>' % ( <EOL> self . __pidfile , pid ) ) <EOL> if fail_if_not_running and pid is None : <EOL> raise AgentNotRunning ( '<STR_LIT>' % self . __pidfile ) <EOL> return pid is not None <EOL> def start_agent_service ( self , agent_run_method , quiet , fork = True ) : <EOL> """<STR_LIT>""" <EOL> self . _log_init_debug ( '<STR_LIT>' % scalyr_util . get_pid_tid ( ) ) <EOL> def handle_terminate ( signal_num , frame ) : <EOL> if self . __termination_handler is not None : <EOL> self . __termination_handler ( ) <EOL> def handle_interrupt ( signal_num , frame ) : <EOL> if self . __status_handler is not None : <EOL> self . __status_handler ( ) <EOL> if fork : <EOL> if not self . __daemonize ( ) : <EOL> return <EOL> else : <EOL> if not self . __write_pidfile ( ) : <EOL> raise AgentAlreadyRunning ( '<STR_LIT>' % ( <EOL> self . __pidfile , str ( self . __read_pidfile ( ) ) ) ) <EOL> original_term = signal . signal ( signal . SIGTERM , handle_terminate ) <EOL> original_interrupt = signal . signal ( signal . SIGINT , handle_interrupt ) <EOL> try : <EOL> self . __is_initializing = False <EOL> result = agent_run_method ( self ) <EOL> if result is not None : <EOL> sys . exit ( result ) <EOL> else : <EOL> sys . exit ( <NUM_LIT> ) <EOL> finally : <EOL> signal . signal ( signal . SIGTERM , original_term ) <EOL> signal . signal ( signal . SIGINT , original_interrupt ) <EOL> def stop_agent_service ( self , quiet ) : <EOL> """<STR_LIT>""" <EOL> pid = self . __read_pidfile ( ) <EOL> if not pid : <EOL> message = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> sys . stderr . write ( message % self . __pidfile ) <EOL> return <NUM_LIT:0> <EOL> if not quiet : <EOL> print '<STR_LIT>' <EOL> try : <EOL> term_attempts = <NUM_LIT:50> <EOL> while term_attempts > <NUM_LIT:0> : <EOL> os . kill ( pid , signal . SIGTERM ) <EOL> PosixPlatformController . __sleep ( <NUM_LIT:0.1> ) <EOL> term_attempts -= <NUM_LIT:1> <EOL> if not quiet : <EOL> print '<STR_LIT>' <EOL> while <NUM_LIT:1> : <EOL> os . kill ( pid , signal . SIGKILL ) <EOL> PosixPlatformController . __sleep ( <NUM_LIT:0.1> ) <EOL> except OSError , err : <EOL> err = str ( err ) <EOL> if err . find ( "<STR_LIT>" ) > <NUM_LIT:0> : <EOL> if os . path . exists ( self . __pidfile ) : <EOL> os . remove ( self . __pidfile ) <EOL> else : <EOL> print '<STR_LIT>' <EOL> print str ( err ) <EOL> return <NUM_LIT:1> <EOL> if not quiet : <EOL> print '<STR_LIT>' <EOL> return <NUM_LIT:0> <EOL> def request_agent_status ( self ) : <EOL> """<STR_LIT>""" <EOL> pid = self . __read_pidfile ( ) <EOL> if pid is None : <EOL> return errno . ESRCH <EOL> try : <EOL> os . kill ( pid , signal . SIGINT ) <EOL> except OSError , e : <EOL> if e . errno == errno . ESRCH or e . errno == errno . EPERM : <EOL> return e . errno <EOL> raise e <EOL> return None <EOL> def register_for_termination ( self , handler ) : <EOL> """<STR_LIT>""" <EOL> self . __termination_handler = handler <EOL> def register_for_status_requests ( self , handler ) : <EOL> """<STR_LIT>""" <EOL> self . __status_handler = handler <EOL> @ staticmethod <EOL> def __sleep ( seconds ) : <EOL> try : <EOL> time . sleep ( seconds ) <EOL> except Exception : <EOL> print '<STR_LIT>' <EOL> def sleep ( self , seconds ) : <EOL> """<STR_LIT>""" <EOL> def handle_alarm ( signal_num , frame ) : <EOL> pass <EOL> signal . signal ( signal . SIGALRM , handle_alarm ) <EOL> signal . alarm ( seconds ) <EOL> signal . pause ( ) <EOL> signal . alarm ( <NUM_LIT:0> ) <EOL> def get_usage_info ( self ) : <EOL> """<STR_LIT>""" <EOL> usage_info = resource . getrusage ( resource . RUSAGE_SELF ) <EOL> user_cpu = usage_info [ <NUM_LIT:0> ] <EOL> system_cpu = usage_info [ <NUM_LIT:1> ] <EOL> rss_size = usage_info [ <NUM_LIT:2> ] <EOL> return user_cpu , system_cpu , rss_size <EOL> def __read_pidfile ( self ) : <EOL> def debug_logger ( message ) : <EOL> self . _log_init_debug ( '<STR_LIT>' % ( message , scalyr_util . get_pid_tid ( ) ) ) <EOL> def logger ( message ) : <EOL> self . _log_init ( '<STR_LIT>' % ( message , scalyr_util . get_pid_tid ( ) ) ) <EOL> manager = PidfileManager ( self . __pidfile ) <EOL> manager . set_options ( debug_logger = debug_logger , logger = logger ) <EOL> return manager . read_pid ( ) <EOL> class PidfileManager ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , pidfile ) : <EOL> """<STR_LIT>""" <EOL> self . __pidfile = pidfile <EOL> self . __logger = None <EOL> self . __debug_logger = None <EOL> def read_pid ( self ) : <EOL> """<STR_LIT>""" <EOL> pf = None <EOL> self . _log_debug ( '<STR_LIT>' ) <EOL> try : <EOL> try : <EOL> pf = file ( self . __pidfile , '<STR_LIT:r>' ) <EOL> raw_contents = pf . read ( ) <EOL> except IOError : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> if not '<STR_LIT:\n>' in raw_contents : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> contents = raw_contents . strip ( ) . split ( ) <EOL> try : <EOL> fcntl . flock ( pf , fcntl . LOCK_SH | fcntl . LOCK_NB ) <EOL> was_locked = False <EOL> try : <EOL> fcntl . flock ( pf , fcntl . LOCK_UN ) <EOL> except IOError , e : <EOL> self . _log_debug ( '<STR_LIT>' % str ( e ) ) <EOL> except IOError , e : <EOL> if ( e . errno == errno . EAGAIN ) or ( e . errno == errno . EACCES ) : <EOL> was_locked = True <EOL> else : <EOL> self . _log_debug ( '<STR_LIT>' % str ( e ) ) <EOL> was_locked = False <EOL> pf . close ( ) <EOL> pf = None <EOL> finally : <EOL> if pf is not None : <EOL> pf . close ( ) <EOL> pid = int ( contents [ <NUM_LIT:0> ] ) <EOL> if was_locked : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return pid <EOL> if len ( contents ) == <NUM_LIT:2> and contents [ <NUM_LIT:1> ] == '<STR_LIT>' : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> try : <EOL> os . kill ( pid , <NUM_LIT:0> ) <EOL> except OSError , e : <EOL> if e . errno == errno . ESRCH : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> elif e . errno != errno . EPERM : <EOL> raise e <EOL> self . _log ( '<STR_LIT>' ) <EOL> return pid <EOL> def create_writer ( self ) : <EOL> """<STR_LIT>""" <EOL> return PidfileManager . PidWriter ( self . __pidfile , self ) <EOL> def set_options ( self , logger = None , debug_logger = None ) : <EOL> """<STR_LIT>""" <EOL> if logger is not None : <EOL> self . __logger = logger <EOL> if debug_logger is not None : <EOL> self . __debug_logger = debug_logger <EOL> def _log_debug ( self , message ) : <EOL> if self . __debug_logger is not None : <EOL> self . __debug_logger ( message ) <EOL> def _log ( self , message ) : <EOL> if self . __logger is not None : <EOL> self . __logger ( message ) <EOL> class PidWriter ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , pidfile , manager ) : <EOL> """<STR_LIT>""" <EOL> self . __pidfile = pidfile <EOL> self . __manager = manager <EOL> self . __locked_fd = None <EOL> def acquire_pid_lock ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . __manager . read_pid ( ) is not None : <EOL> return None <EOL> fd = None <EOL> """<STR_LIT>""" <EOL> if not os . path . isfile ( self . __pidfile ) : <EOL> try : <EOL> self . _log_debug ( '<STR_LIT>' ) <EOL> fd = os . open ( self . __pidfile , os . O_CREAT | os . O_EXCL | os . O_WRONLY ) <EOL> except OSError , e : <EOL> if e . errno != errno . EEXIST : <EOL> raise e <EOL> if fd is None : <EOL> try : <EOL> fd = os . open ( self . __pidfile , os . O_WRONLY ) <EOL> self . _log_debug ( '<STR_LIT>' ) <EOL> except OSError , e : <EOL> if e . errno == errno . ENOENT : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> else : <EOL> raise e <EOL> fp = None <EOL> try : <EOL> try : <EOL> fp = os . fdopen ( fd , '<STR_LIT:w>' ) <EOL> fcntl . flock ( fp , fcntl . LOCK_EX | fcntl . LOCK_NB ) <EOL> except IOError , e : <EOL> if ( e . errno == errno . EAGAIN ) or ( e . errno == errno . EACCES ) : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> else : <EOL> raise e <EOL> self . __locked_fd = fp <EOL> self . _log ( '<STR_LIT>' ) <EOL> fp = None <EOL> fd = None <EOL> return self . __release_lock <EOL> finally : <EOL> if fp is not None : <EOL> fp . close ( ) <EOL> elif fd is not None : <EOL> os . close ( fd ) <EOL> def write_pid ( self , pid = None ) : <EOL> """<STR_LIT>""" <EOL> if self . __locked_fd is None : <EOL> self . acquire_pid_lock ( ) <EOL> else : <EOL> try : <EOL> fcntl . flock ( self . __locked_fd , fcntl . LOCK_EX | fcntl . LOCK_NB ) <EOL> self . _log_debug ( '<STR_LIT>' ) <EOL> except IOError , e : <EOL> if ( e . errno == errno . EAGAIN ) or ( e . errno == errno . EACCES ) : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> else : <EOL> raise e <EOL> if self . __locked_fd is None : <EOL> self . _log ( '<STR_LIT>' ) <EOL> return None <EOL> if pid is None : <EOL> pid = os . getpid ( ) <EOL> fp = self . __locked_fd <EOL> fp . truncate ( ) <EOL> fp . write ( '<STR_LIT>' % pid ) <EOL> self . _log ( '<STR_LIT>' ) <EOL> fp . flush ( ) <EOL> os . fsync ( fp . fileno ( ) ) <EOL> return self . __release_lock <EOL> def __release_lock ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . __locked_fd is None : <EOL> return <EOL> os . unlink ( self . __pidfile ) <EOL> try : <EOL> fcntl . flock ( self . __locked_fd , fcntl . LOCK_UN ) <EOL> except IOError , e : <EOL> self . _log ( '<STR_LIT>' % str ( e ) ) <EOL> self . __locked_fd . close ( ) <EOL> self . __locked_fd = None <EOL> def _log_debug ( self , message ) : <EOL> self . __manager . _log_debug ( message ) <EOL> def _log ( self , message ) : <EOL> self . __manager . _log ( message ) <EOL> class StatusReporter ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , duplicate_reporter = None ) : <EOL> """<STR_LIT>""" <EOL> self . __has_reported = False <EOL> if duplicate_reporter is None : <EOL> self . __fp = tempfile . TemporaryFile ( ) <EOL> else : <EOL> source_fp = duplicate_reporter . __fp <EOL> assert not hasattr ( source_fp , '<STR_LIT:file>' ) <EOL> self . __fp = os . fdopen ( os . dup ( source_fp . fileno ( ) ) , '<STR_LIT>' ) <EOL> assert self . __fp . fileno ( ) != source_fp . fileno ( ) <EOL> def close ( self ) : <EOL> """<STR_LIT>""" <EOL> self . __fp . close ( ) <EOL> def report_status ( self , message ) : <EOL> """<STR_LIT>""" <EOL> self . __fp . write ( '<STR_LIT>' % len ( message ) ) <EOL> self . __fp . write ( '<STR_LIT:%s>' % message ) <EOL> self . __fp . flush ( ) <EOL> def read_status ( self , timeout = None , timeout_status = None ) : <EOL> """<STR_LIT>""" <EOL> if timeout is not None : <EOL> deadline = time . time ( ) + timeout <EOL> else : <EOL> deadline = None <EOL> while True : <EOL> if deadline is not None and time . time ( ) > deadline : <EOL> return timeout_status <EOL> self . __fp . seek ( <NUM_LIT:0> ) <EOL> num_bytes = self . __fp . readline ( ) <EOL> if num_bytes != '<STR_LIT>' : <EOL> message = self . __fp . read ( ) <EOL> if len ( message ) == int ( num_bytes ) : <EOL> return message <EOL> time . sleep ( <NUM_LIT> ) <EOL> @ property <EOL> def has_reported ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . __has_reported <EOL> def _can_read_command_line ( pid ) : <EOL> """<STR_LIT>""" <EOL> return os . path . isfile ( '<STR_LIT>' % pid ) <EOL> def _read_command_line ( pid ) : <EOL> """<STR_LIT>""" <EOL> pf = None <EOL> try : <EOL> pf = file ( '<STR_LIT>' % pid , '<STR_LIT:r>' ) <EOL> return pf . read ( ) . strip ( ) <EOL> finally : <EOL> if pf is not None : <EOL> pf . close ( ) </s>
