<s> """<STR_LIT>""" <EOL> import os <EOL> import re <EOL> import signal <EOL> from zope . interface import classProvides <EOL> from twisted . internet import reactor , defer , protocol , process <EOL> from twisted . internet import error as neterror <EOL> from nagcat import errors , log , query <EOL> class SubprocessError ( errors . TestError ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , ex ) : <EOL> assert isinstance ( ex , neterror . ProcessTerminated ) <EOL> self . exitCode = ex . exitCode <EOL> self . signal = ex . signal <EOL> self . status = ex . status <EOL> super ( SubprocessError , self ) . __init__ ( ex . args [ <NUM_LIT:0> ] ) <EOL> class SubprocessProtocol ( protocol . ProcessProtocol ) : <EOL> """<STR_LIT>""" <EOL> timedout = False <EOL> def connectionMade ( self ) : <EOL> self . result = "<STR_LIT>" <EOL> if self . factory . conf [ '<STR_LIT:data>' ] : <EOL> self . transport . write ( self . factory . conf [ '<STR_LIT:data>' ] ) <EOL> self . transport . closeStdin ( ) <EOL> def outReceived ( self , data ) : <EOL> self . result += data <EOL> def errReceived ( self , data ) : <EOL> key = "<STR_LIT>" <EOL> self . factory . saved [ key ] = self . factory . saved . get ( key , "<STR_LIT>" ) + data <EOL> def timeout ( self ) : <EOL> self . timedout = True <EOL> self . transport . loseConnection ( ) <EOL> if self . transport . pid : <EOL> try : <EOL> os . kill ( - int ( self . transport . pid ) , signal . SIGTERM ) <EOL> except OSError , ex : <EOL> log . warn ( "<STR_LIT>" , ex ) <EOL> def processEnded ( self , reason ) : <EOL> if isinstance ( reason . value , neterror . ProcessDone ) : <EOL> result = self . result <EOL> elif isinstance ( reason . value , neterror . ProcessTerminated ) : <EOL> if self . timedout : <EOL> result = errors . Failure ( errors . TestCritical ( <EOL> "<STR_LIT>" ) , <EOL> result = self . result ) <EOL> elif reason . value . exitCode == <NUM_LIT> : <EOL> result = errors . Failure ( errors . TestCritical ( <EOL> "<STR_LIT>" ) ) <EOL> else : <EOL> result = errors . Failure ( SubprocessError ( reason . value ) , <EOL> result = self . result ) <EOL> else : <EOL> result = reason <EOL> self . factory . result ( result ) <EOL> class SubprocessFactory ( process . Process ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , query ) : <EOL> self . conf = query . conf <EOL> self . saved = query . saved <EOL> self . deferred = defer . Deferred ( ) <EOL> self . _startProcess ( ( "<STR_LIT>" , "<STR_LIT:-c>" , self . conf [ '<STR_LIT>' ] ) ) <EOL> def _startProcess ( self , command ) : <EOL> command = [ str ( x ) for x in command ] <EOL> log . debug ( "<STR_LIT>" , command ) <EOL> proto = SubprocessProtocol ( ) <EOL> proto . factory = self <EOL> call_id = reactor . callLater ( self . conf [ '<STR_LIT>' ] , proto . timeout ) <EOL> self . deferred . addBoth ( self . _cancelTimeout , call_id ) <EOL> call_id = reactor . addSystemEventTrigger ( '<STR_LIT>' , '<STR_LIT>' , <EOL> proto . timeout ) <EOL> self . deferred . addBoth ( self . _cancelCleanup , call_id ) <EOL> process . Process . __init__ ( self , reactor , command [ <NUM_LIT:0> ] , command , <EOL> self . conf [ '<STR_LIT>' ] , path = None , proto = proto ) <EOL> def result ( self , result ) : <EOL> self . deferred . callback ( result ) <EOL> def _cancelTimeout ( self , result , call_id ) : <EOL> if call_id . active ( ) : <EOL> call_id . cancel ( ) <EOL> return result <EOL> def _cancelCleanup ( self , result , call_id ) : <EOL> reactor . removeSystemEventTrigger ( call_id ) <EOL> return result <EOL> def _setupChild ( self , * args , ** kwargs ) : <EOL> os . setpgrp ( ) <EOL> process . Process . _setupChild ( self , * args , ** kwargs ) <EOL> class SubprocessBase ( query . Query ) : <EOL> """<STR_LIT>""" <EOL> name = "<STR_LIT>" <EOL> def __init__ ( self , nagcat , conf ) : <EOL> super ( SubprocessBase , self ) . __init__ ( nagcat , conf ) <EOL> env = os . environ . copy ( ) <EOL> if '<STR_LIT>' in conf : <EOL> env . update ( conf [ '<STR_LIT>' ] ) <EOL> self . conf [ '<STR_LIT>' ] = conf [ '<STR_LIT>' ] <EOL> self . conf [ '<STR_LIT:data>' ] = conf . get ( '<STR_LIT:data>' , "<STR_LIT>" ) <EOL> self . conf [ '<STR_LIT>' ] = env <EOL> def _start ( self ) : <EOL> proc = SubprocessFactory ( self ) <EOL> return proc . deferred <EOL> class SubprocessQuery ( SubprocessBase ) : <EOL> """<STR_LIT>""" <EOL> classProvides ( query . IQuery ) <EOL> name = "<STR_LIT>" <EOL> def _start ( self ) : <EOL> deferred = super ( SubprocessQuery , self ) . _start ( ) <EOL> deferred . addErrback ( self . _checkError ) <EOL> return deferred <EOL> def _checkError ( self , reason ) : <EOL> if isinstance ( reason . value , SubprocessError ) : <EOL> return errors . Failure ( errors . TestCritical ( <EOL> str ( reason . value ) ) , result = reason . result ) <EOL> else : <EOL> return reason <EOL> class NagiosPluginQuery ( query . Query ) : <EOL> """<STR_LIT>""" <EOL> classProvides ( query . IQuery ) <EOL> name = "<STR_LIT>" <EOL> perf_format = re . compile ( r'''<STR_LIT>''' , re . X ) <EOL> def __init__ ( self , nagcat , conf ) : <EOL> super ( NagiosPluginQuery , self ) . __init__ ( nagcat , conf ) <EOL> self . subquery = nagcat . new_query ( conf , qcls = SubprocessBase ) <EOL> self . addDependency ( self . subquery ) <EOL> self . conf . update ( self . subquery . conf ) <EOL> self . conf [ '<STR_LIT>' ] = str ( conf . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> def _start ( self ) : <EOL> deferred = defer . succeed ( self . subquery . result ) <EOL> deferred . addCallbacks ( self . _parseOutput , self . _checkError ) <EOL> return deferred <EOL> @ errors . callback <EOL> def _parseOutput ( self , result ) : <EOL> if not isinstance ( result , basestring ) : <EOL> return result <EOL> lines = result . split ( '<STR_LIT:\n>' , <NUM_LIT:1> ) <EOL> split = lines [ <NUM_LIT:0> ] . split ( '<STR_LIT:|>' , <NUM_LIT:1> ) <EOL> if self . conf [ '<STR_LIT>' ] : <EOL> if len ( split ) != <NUM_LIT:2> : <EOL> raise errors . Critical ( "<STR_LIT>" ) <EOL> for match in self . perf_format . finditer ( split [ <NUM_LIT:1> ] ) : <EOL> if match . group ( '<STR_LIT:label>' ) == self . conf [ '<STR_LIT>' ] : <EOL> return match . group ( '<STR_LIT:value>' ) <EOL> raise errors . Critical ( "<STR_LIT>" % <EOL> ( self . conf [ '<STR_LIT>' ] , ) ) <EOL> else : <EOL> return split [ <NUM_LIT:0> ] + '<STR_LIT:\n>' . join ( lines [ <NUM_LIT:1> : ] ) + '<STR_LIT:\n>' <EOL> def _checkError ( self , reason ) : <EOL> if isinstance ( reason . value , SubprocessError ) : <EOL> parsed = self . _parseOutput ( reason . result ) <EOL> if isinstance ( parsed , errors . Failure ) : <EOL> return parsed <EOL> if reason . value . exitCode == <NUM_LIT:1> : <EOL> return errors . Failure ( errors . TestWarning ( <EOL> parsed . split ( '<STR_LIT:\n>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] ) , result = parsed ) <EOL> elif reason . value . exitCode == <NUM_LIT:2> : <EOL> return errors . Failure ( errors . TestCritical ( <EOL> parsed . split ( '<STR_LIT:\n>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] ) , result = parsed ) <EOL> elif reason . value . exitCode == <NUM_LIT:3> : <EOL> return errors . Failure ( errors . TestUnknown ( <EOL> parsed . split ( '<STR_LIT:\n>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] ) , result = parsed ) <EOL> else : <EOL> return errors . Failure ( errors . TestUnknown ( <EOL> str ( reason . value ) ) , result = parsed ) <EOL> else : <EOL> return reason </s>
