<s> """<STR_LIT>""" <EOL> from __future__ import absolute_import <EOL> from __future__ import print_function <EOL> import copy <EOL> import functools <EOL> import logging <EOL> import re <EOL> import signal <EOL> import sys <EOL> import threading <EOL> import time <EOL> from argparse import ArgumentParser <EOL> from . compat import OrderedDict , captureWarnings <EOL> from sparts import vtask <EOL> from . deps import HAS_PSUTIL , HAS_DAEMONIZE <EOL> from . sparts import _SpartsObject , option <EOL> from sparts import daemon <EOL> class VService ( _SpartsObject ) : <EOL> """<STR_LIT>""" <EOL> DEFAULT_LOGLEVEL = '<STR_LIT>' <EOL> DEFAULT_LOGFILE = None <EOL> DEFAULT_PID = lambda cls : '<STR_LIT>' % cls . __name__ <EOL> REGISTER_SIGNAL_HANDLERS = True <EOL> TASKS = [ ] <EOL> VERSION = '<STR_LIT>' <EOL> _name = None <EOL> dryrun = option ( action = '<STR_LIT:store_true>' , help = '<STR_LIT>' ) <EOL> level = option ( default = DEFAULT_LOGLEVEL , help = '<STR_LIT>' ) <EOL> logfile = option ( default = lambda cls : cls . DEFAULT_LOGFILE , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> register_tasks = option ( name = '<STR_LIT>' , default = None , <EOL> metavar = '<STR_LIT>' , nargs = '<STR_LIT:*>' , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if HAS_DAEMONIZE : <EOL> daemon = option ( <EOL> action = '<STR_LIT:store_true>' , <EOL> help = '<STR_LIT>' , <EOL> ) <EOL> pidfile = option ( <EOL> default = DEFAULT_PID , <EOL> help = '<STR_LIT>' , <EOL> metavar = '<STR_LIT>' , <EOL> ) <EOL> kill = option ( <EOL> action = '<STR_LIT:store_true>' , <EOL> help = '<STR_LIT>' , <EOL> ) <EOL> status = option ( <EOL> action = '<STR_LIT:store_true>' , <EOL> help = '<STR_LIT>' , <EOL> ) <EOL> if HAS_PSUTIL : <EOL> runit_install = option ( action = '<STR_LIT:store_true>' , <EOL> help = '<STR_LIT>' ) <EOL> def __init__ ( self , ns ) : <EOL> super ( VService , self ) . __init__ ( ) <EOL> self . logger = logging . getLogger ( self . name ) <EOL> self . options = ns <EOL> self . initLogging ( ) <EOL> self . _stop = False <EOL> self . _restart = False <EOL> self . tasks = vtask . Tasks ( ) <EOL> for t in vtask . REGISTERED : <EOL> self . tasks . register ( t ) <EOL> for t in self . TASKS : <EOL> self . tasks . register ( t ) <EOL> self . warnings = OrderedDict ( ) <EOL> self . warning_id = <NUM_LIT:0> <EOL> self . exported_values = { } <EOL> self . start_time = time . time ( ) <EOL> def initService ( self ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def _loptName ( cls , name ) : <EOL> return '<STR_LIT>' + name . replace ( '<STR_LIT:_>' , '<STR_LIT:->' ) <EOL> def preprocessOptions ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . getOption ( '<STR_LIT>' ) : <EOL> self . _install ( ) <EOL> if HAS_DAEMONIZE : <EOL> if self . status : <EOL> if daemon . status ( pidfile = self . pidfile , logger = self . logger ) : <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> else : <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> if self . kill : <EOL> if daemon . kill ( pidfile = self . pidfile , logger = self . logger ) : <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> else : <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> if self . options . tasks == [ ] : <EOL> print ( "<STR_LIT>" ) <EOL> for t in self . tasks : <EOL> print ( "<STR_LIT>" % t . __name__ ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> def _createTasks ( self ) : <EOL> all_tasks = set ( self . tasks ) <EOL> selected_tasks = self . options . tasks <EOL> if selected_tasks is None : <EOL> selected_tasks = [ t . __name__ for t in all_tasks ] <EOL> unregister_tasks = [ t for t in all_tasks <EOL> if t . __name__ not in selected_tasks ] <EOL> for t in unregister_tasks : <EOL> self . tasks . unregister ( t ) <EOL> self . tasks . create ( self ) <EOL> self . initService ( ) <EOL> self . tasks . init ( ) <EOL> def _handleShutdownSignals ( self , signum , frame ) : <EOL> assert signum in ( signal . SIGINT , signal . SIGTERM ) <EOL> self . logger . info ( '<STR_LIT>' , signum ) <EOL> self . shutdown ( ) <EOL> def _startTasks ( self ) : <EOL> if self . REGISTER_SIGNAL_HANDLERS : <EOL> signal . signal ( signal . SIGINT , self . _handleShutdownSignals ) <EOL> signal . signal ( signal . SIGTERM , self . _handleShutdownSignals ) <EOL> self . tasks . start ( ) <EOL> self . logger . debug ( "<STR_LIT>" ) <EOL> def getTask ( self , name ) : <EOL> """<STR_LIT>""" <EOL> return self . tasks . get ( name ) <EOL> def requireTask ( self , name ) : <EOL> """<STR_LIT>""" <EOL> return self . tasks . require ( name ) <EOL> def shutdown ( self ) : <EOL> """<STR_LIT>""" <EOL> self . logger . info ( "<STR_LIT>" ) <EOL> self . stop ( ) <EOL> def restart ( self ) : <EOL> """<STR_LIT>""" <EOL> self . logger . info ( "<STR_LIT>" ) <EOL> self . _restart = True <EOL> self . stop ( ) <EOL> def stop ( self ) : <EOL> self . _stop = True <EOL> def _wait ( self ) : <EOL> try : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> while not self . _stop : <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> except KeyboardInterrupt : <EOL> self . logger . info ( '<STR_LIT>' ) <EOL> for t in reversed ( self . tasks ) : <EOL> t . stop ( ) <EOL> try : <EOL> self . logger . info ( '<STR_LIT>' ) <EOL> for t in reversed ( self . tasks ) : <EOL> self . logger . debug ( '<STR_LIT>' , t ) <EOL> t . join ( ) <EOL> except KeyboardInterrupt : <EOL> self . logger . warning ( '<STR_LIT>' ) <EOL> def join ( self ) : <EOL> """<STR_LIT>""" <EOL> while not self . _stop : <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> for t in reversed ( self . tasks ) : <EOL> t . join ( ) <EOL> @ classmethod <EOL> def initFromCLI ( cls , name = None ) : <EOL> """<STR_LIT>""" <EOL> ap = cls . _buildArgumentParser ( ) <EOL> ns = ap . parse_args ( ) <EOL> instance = cls . initFromOptions ( ns , name = name ) <EOL> return instance <EOL> @ classmethod <EOL> def initFromOptions ( cls , ns , name = None ) : <EOL> """<STR_LIT>""" <EOL> instance = cls ( ns ) <EOL> if name is not None : <EOL> instance . name = name <EOL> instance . preprocessOptions ( ) <EOL> if HAS_DAEMONIZE and ns . daemon : <EOL> daemon . daemonize ( <EOL> command = functools . partial ( cls . _runloop , instance ) , <EOL> name = instance . name , <EOL> pidfile = ns . pidfile , <EOL> logger = instance . logger , <EOL> ) <EOL> else : <EOL> return cls . _runloop ( instance ) <EOL> @ classmethod <EOL> def _runloop ( cls , instance ) : <EOL> while not instance . _stop : <EOL> try : <EOL> instance . _createTasks ( ) <EOL> instance . _startTasks ( ) <EOL> except Exception : <EOL> instance . logger . exception ( "<STR_LIT>" ) <EOL> instance . shutdown ( ) <EOL> instance . _wait ( ) <EOL> if instance . _restart : <EOL> instance = cls ( instance . options ) <EOL> instance . logger . info ( "<STR_LIT>" ) <EOL> def startBG ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _createTasks ( ) <EOL> self . _startTasks ( ) <EOL> t = threading . Thread ( target = self . _wait ) <EOL> t . start ( ) <EOL> return t <EOL> @ property <EOL> def name ( self ) : <EOL> if self . _name is None : <EOL> self . _name = self . __class__ . __name__ <EOL> return self . _name <EOL> @ name . setter <EOL> def name ( self , value ) : <EOL> self . _name = value <EOL> def initLogging ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . logfile : <EOL> logging . basicConfig ( level = self . loglevel , filename = self . logfile ) <EOL> else : <EOL> logging . basicConfig ( level = self . loglevel , stream = sys . stderr ) <EOL> captureWarnings ( True ) <EOL> @ classmethod <EOL> def _makeArgumentParser ( cls ) : <EOL> """<STR_LIT>""" <EOL> return ArgumentParser ( ) <EOL> @ classmethod <EOL> def _buildArgumentParser ( cls ) : <EOL> ap = cls . _makeArgumentParser ( ) <EOL> cls . _addArguments ( ap ) <EOL> all_tasks = vtask . Tasks ( ) <EOL> all_tasks . register_all ( cls . TASKS ) <EOL> all_tasks . register_all ( vtask . REGISTERED ) <EOL> for t in all_tasks : <EOL> t . _addArguments ( ap ) <EOL> return ap <EOL> @ property <EOL> def loglevel ( self ) : <EOL> return getattr ( logging , self . options . level ) <EOL> def getOption ( self , name , default = None ) : <EOL> return getattr ( self . options , name , default ) <EOL> def setOption ( self , name , value ) : <EOL> setattr ( self . options , name , value ) <EOL> def getOptions ( self ) : <EOL> return self . options . __dict__ <EOL> def _install ( self ) : <EOL> if not HAS_PSUTIL : <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> import sparts . runit <EOL> sparts . runit . install ( self . name ) <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> def getChildren ( self ) : <EOL> return dict ( ( t . name , t ) for t in self . tasks ) <EOL> def getWarnings ( self ) : <EOL> return self . warnings <EOL> def registerWarning ( self , message ) : <EOL> wid = self . warning_id <EOL> self . warning_id += <NUM_LIT:1> <EOL> self . warnings [ wid ] = message <EOL> return wid <EOL> def clearWarnings ( self ) : <EOL> self . warnings = OrderedDict ( ) <EOL> def clearWarning ( self , id ) : <EOL> if id not in self . warnings : <EOL> return False <EOL> del self . warnings [ id ] <EOL> return True <EOL> def getExportedValue ( self , name ) : <EOL> return self . exported_values . get ( name , '<STR_LIT>' ) <EOL> def setExportedValue ( self , name , value ) : <EOL> if value is None : <EOL> del self . exported_values [ name ] <EOL> else : <EOL> self . exported_values [ name ] = value <EOL> def getExportedValues ( self ) : <EOL> return copy . copy ( self . exported_values ) <EOL> def getRegexExportedValues ( self , regex ) : <EOL> matcher = re . compile ( regex ) <EOL> keys = [ key for key in self . exported_values . keys ( ) <EOL> if matcher . match ( key ) is not None ] <EOL> return self . getSelectedExportedValues ( keys ) <EOL> def getSelectedExportedValues ( self , keys ) : <EOL> return dict ( [ ( key , self . getExportedValue ( key ) ) <EOL> for key in keys ] ) </s>
