m Ec@sVdZdkZdkZdkZdkZdkZdkZdkZdkZe djoudk l Z l Z l Z lZe ee eidZe eidjoeiie enndklZdZdefd YZd eifd YZd fd YZeeedZe djo endS(szdctl -- control an application run by zdaemon. Usage: python zdctl.py [-C URL] [-S schema.xml] [-h] [-p PROGRAM] [zdrun-options] [action [arguments]] Options: -C/--configure URL -- configuration file or URL -S/--schema XML Schema -- XML schema for configuration file -h/--help -- print usage message and exit -b/--backoff-limit SECONDS -- set backoff limit to SECONDS (default 10) -d/--daemon -- run as a proper daemon; fork a subprocess, close files etc. -f/--forever -- run forever (by default, exit when backoff limit is exceeded) -h/--help -- print this usage message and exit -i/--interactive -- start an interactive shell after executing commands -l/--logfile -- log file to be read by logtail command -p/--program PROGRAM -- the program to run -s/--socket-name SOCKET -- Unix socket name for client (default "zdsock") -u/--user USER -- run as this user (or numeric uid) -m/--umask UMASK -- use this umask for daemon subprocess (default is 022) -x/--exit-codes LIST -- list of fatal exit codes (default "0,2") -z/--directory DIRECTORY -- directory to chdir to when using -d (default off) action [arguments] -- see below Actions are commands like "start", "stop" and "status". If -i is specified or no action is specified on the command line, a "shell" interpreting actions typed interactively is started (unless the configuration option default_to_interactive is set to false). Use the action "help" to find out about available actions. Nt__main__(sdirnamesbasenamesabspathsnormpathitzdaemon(s RunnerOptionscCs |iS(N(targtsplit(R((t,/data/zmath/zope/lib/python/zdaemon/zdctl.pyt string_listAst ZDCtlOptionscBs)tZdZdZdZdZRS(Nic Cs%ti||idddddddd|i|id dd d d d |id ddd |idddddtdd|idddd|idd|iddtii t i d}tii |\}}|djo |}n|idd d|d!dS("Nt schemafiletshortsS:tlongsschema=tdefaults schema.xmlthandlert interactivetitflagitdefault_to_interactivesrunner.default_to_interactivetprogramsrunner.programsp:sprogram=trequireds"no program specified; use -p or -Ctlogfilesrunner.logfilesl:slogfile=tpythons runner.pythontzdruns runner.zdrunis.pytprompts runner.promptt>(t RunnerOptionst__init__tselftaddtset_schemafiletNoneRtostpathtbasenametsystargvt programnametsplitexttbasetext(RR%R$R"((RRIs$       cOsti||||i o3|i o(|ip|idnd|_n|ipt i |_n|i ppt djot i d}nt}tiitii|}tii|}tii|d|_ ndS(Ns+either -i or an action argument is requirediRiszdrun.py(RtrealizeRtargstkwdsR RtusageRR t executableRt__name__R!tfilet__file__RRtnormpathtabspathtdirnametdirtjoin(RR'R(R,R1((RR&]s     cCs ||_dS(N(R,RR(RR,((RRts(R+t __module__tpositional_args_allowedRR&R(((RREs  tZDCmdcBstZdZdZdZdZdZdZdZdZ d Z dd d Z d Z d ZdZdZdZdZdZdZdZddZdZdZdZdZdZdZdZdZdZd Z d!Z!d"Z"d#Z#d$Z$d%Z%d&Z&d'Z'd(Z(d)Z)d*Z*d+Z+RS(,NcCs||_|iid|_tii||i|ioti d|i}|o_|i d}t |hdh<}||iijo!dGHdG|iiGHdG|GHqqndS(Nt s(?m)^args=(.*)$it __builtins__s/WARNING! zdrun is managing a different program!sour program =sdaemon's args =(toptionsRRtcmdtCmdRt get_statust zd_statustretsearchtmtgrouptstevalR'R(RR8R'R?RA((RR{s   cCs|idS(N(Rt do_status(R((Rt emptylinescCstititi}yv|i|ii|i|d|i dd}x*|i d}|pPn||7}qUW|i|SWntij o }dSnXdS(sSend an action to the zdrun server and return the response. Return None if the server is not up or any other error happened. s itiN(tsockettAF_UNIXt SOCK_STREAMtsocktconnectRR8tsocknametsendtactiontshutdowntresponsetrecvtdatatcloseterrortmsgR(RRMRIRTRQRO((Rt send_actions"  cCsd|_d|_d|_|id}|pdSntid|}|pdSnd|_t |i d|_||_dS(Nitstatuss(?m)^application=(\d+)$i( Rtzd_uptzd_pidRR<RUtrespR=R>R?tintR@(RR?RY((RR;s    cCsyT|ixC|p8tiidtiitid|iqWWnt j o dGHnX||i GHdS(Ns. is^C( RR;tcondR tstdouttwritetflushttimetsleeptKeyboardInterruptRTt__dict__(RR[RT((Rtawhiles     cCsdGHdGHdS(Ns3help -- Print a list of available actions.s)help -- Print help for .((R((Rt help_helpscCsHdS(Ni((RR((Rtdo_EOFscCs dGHdS(Ns)To quit, type ^D or use the quit command.((R((Rthelp_EOFscsiipiiiig}|idd7}|idd7}|idd7}|iddd d 7}|id d d d 7}|id d7}|idd7}iio)|iddt ii7}n|idddi t t ii 7}|idd7}|iiiiio ti}n ti}ti||d|n,ipidndiGHdSidddS(Ns-SRs-Ct configfiles-bt backofflimits-dtdaemonRis-ftforevers-sRKs-utusers-mtumasks-xt exitcodest,s-zt directoryitstarts&daemon process already running; pid=%dcsiS(N(RRX((R(Rtss&daemon process started, pid=%(zd_pid)d(RR;RWR8RRR't _get_overrideRltoctR2tmaptstrRmtextendRRiRtP_NOWAITRtP_WAITtspawnvpRXRURc(RRR'R((RRtdo_starts4   1     ic Cs%t|i|}|djogSn|ii} | dj ox|iiD]~\}} ||joe| o^| } x;| i dD]*}t| |d} | djoPqqW| |jogSnPqMqMWn|o|o |g}q!g}n*|djot|}n||g}|S(Nt.(tgetattrRR8tnametvalueRt configroott names_listtntcntvRtpRtoptR'tsvalueRu( RRR}RRR'R~RRRRR((RRrs2            cCsdGHdGHdS(Ns"start -- Start the daemon process.s. If it is already running, do nothing.((R((Rt help_startscsWiip dGHn7ip dGHn$ididddS(Nsdaemon manager not runningsdaemon process not runningtstopcsi S(N(RRX((R(RRqssdaemon process stopped(RR;RWRXRURc(RR((RRtdo_stop s      cCsdGHdGHdS(Ns stop -- Stop the daemon process.s) If it is not running, do nothing.((R((Rt help_stopscsUiipi|n'ididddS(NtrestartcsidfjS(Ni(RRXtpid((RR(RRq ss(daemon process restarted, pid=%(zd_pid)d(RR;RXRRzRRURc(RRR((RRRt do_restarts   cCs dGHdS(Ns2restart -- Stop and then start the daemon process.((R((Rt help_restart#scCs|p ti}n)yt|}WndG| GHdSnX|i|ip dGHdSnd|i|fGHyti |i|Wn!ti j o}dG|GHnXd||ifGHdS(Nsinvalid signal numbersdaemon process not runnings kill(%d, %d)sError:ssignal %d sent to process %d( RtsignaltSIGTERMtsigRZRR;RXRtkillRSRT(RRRRT((Rtdo_kill&s"    cCsdGHdGHdS(Ns4kill [sig] -- Send signal sig to the daemon process.s, The default signal is SIGTERM.((R((Rt help_kill;scs$iddidS(Ncsi S(N(RRX((R(RRq@ssdaemon process stopped(RRcRC(RR((RRtdo_wait?scCs dGHdS(Ns,wait -- Wait for the daemon process to exit.((R((Rt help_waitCsREcCs|ddgjo dGHdSn|i|ip dGHn |ip dGHn d|iGH|djo|io |iGHndS(NREs-ls$status argument must be absent or -lsdaemon manager not runnings2daemon manager running; daemon process not runningsprogram running; pid=%d(RRR;RWRXR<(RR((RRCFs      cCsdGHdGHdS(Ns3status [-l] -- Print status for the daemon process.s7 With -l, show raw status output as well.((R((Rt help_statusTscCs^|p d}nyt|d|}Wn(tj o}|GH|idSnX|dS(NR8tshow_(RR|RtmethodtAttributeErrorterrt help_show(RRRR((Rtdo_showXs   cCsdGHdGt|iiGHdGt|iiGHdGt|iiGHdGt|iiGHdGt|iiGHdGt|iiGHdGt|ii GHd Gt|ii GHd Gt|ii GHd Gt|ii GHd Gt|ii GHd Gt|iiGHdGt|iiGH|ii}|p tid}ti|ndGt|GHdGt|iiGHdGt|iiGHdGt|iiGHdS(Nszdctl/zdrun options:s schemafile: s configfile: s interactive: sdefault_to_interactive:s zdrun: s python: s program: s backofflimit:s daemon: s forever: s sockname: s exitcodes: s user: is umask: s directory: s logfile: s hang_around: (treprRR8RRgR RRRRRhRiRjRKRmRkRlRRsRoRt hang_around(RRl((Rt show_optionscs. cCsdGHtiidd}dG|GHdGtiGHdGttiGHdGttiGHdGttiGHd GHx ti D]}d t|GHqwWdS( Ns Python info:s s s Version: s Platform: s Executable: s Arguments: s Directory: sPath:s ( R tversiontreplacetplatformRR*R!RtgetcwdRR1(RRR1((Rt show_python}s   cCs|iH|idS(N(RRR(R((Rtshow_alls cCsdGHdGHdGHdS(Ns"show options -- show zdctl optionss.show python -- show Python version and detailss!show all -- show all of the above((R((RRscGsBdddg}g}|D]!}|i|o ||qq~S(NR8Rtall(R8t_[1]txt startswithttext(RRtignoredRRR8((Rt complete_showscCs|ittidS(N(RRRuRtSIGUSR2(RR((Rt do_logreopenscCsdGHdGHdS(Ns9logreopen -- Send a SIGUSR2 signal to the daemon process.s5 This is designed to reopen the log file.((R((Rthelp_logreopenscCs|p$|ii}|p dGHdSq+nyt|}|iWnFtj oHn4tj o}|GHnt j o}|GHnXdS(Ns4No default log file specified; use logtail ( RRR8Rt TailHelperthelperttailfRatIOErrorRTtOSError(RRRRT((Rt do_logtails    cCsdGHdGHdGHdS(Ns6logtail [logfile] -- Run tail -f on the given logfile.s. A default file may exist.s. Hit ^C to exit this mode.((R((Rt help_logtailscCsM|ptidpd}nyti|Wntj oHnXdS(NtSHELLs/bin/sh(RRtgetenvtsystemRa(RR((Rtdo_shells cCsdGHdGHdGHdS(Ns+shell [command] -- Execute a shell command.s> Without a command, start an interactive sh.s(An alias for this command is ! [command]((R((Rt help_shellscCs|o7|i}|iiod|iig|}qDnd}t}d|_y|i |Wnt j o dGHn0X||_|iiodG|iiGHndGHdS(Ns-CisConfiguration not reloadedsConfiguration reloaded froms,Configuration reloaded without a config file( RRR'RR8RgRRR4R&t SystemExit(RRR'R8((Rt do_reloads       cCsdGHdGHdGHdGHdGHdS(Ns-reload [options] -- Reload the configuration.s4 Without options, this reparses the command line.s4 With options, this substitutes 'options' for thes7 command line, except that if no -C option is given,s( the last configuration file is used.((R((Rt help_reloads cCsm|i|i}|o dGHdSndi|ii}|GHyti|Wnt j oHnXdS(Ns;To run the program in the foreground, please stop it first.R6( RR;RXRR2R8RRRRa(RRRR((Rt do_foregrounds  cCs|i|dS(N(RRR(RR((Rtdo_fgscCsdGHdGHdS(Ns/foreground -- Run the program in the forground.sfg -- an alias for foreground.((R((Rthelp_foregroundscCs|idS(N(RR(R((Rthelp_fgscs\iip dGHn<ip,dGHididdndGHdS(Nsdaemon manager not runnings3daemon process not running; stopping daemon managertexitcsi S(N(RRW((R(RRqssdaemon manager stoppeds/daemon process and daemon manager still runningi(RR;RWRXRURc(RR((RRtdo_quits     cCsdGHdGHdGHdS(Nsquit -- Exit the zdctl shell.s- If the daemon process is not running,s stop the daemon manager.((R((Rt help_quits(,R+R3RRDRUR;RcRdReRfRzRRrRRRRRRRRRRCRRRRRRRRRRRRRRRRRRRRR(((RR5ysR        "                         RcBs5tZdZdZdZddZdZRS(NicCst|d|_dS(Ntr(topentfnameRtf(RR((RRscCs|id\}}x+|D]#}tii|tiiqWx|i }||}|djod}dGH|}n|djoM|i i | d|i i|}tii|tii|}ntidqFWdS(Ni iis==> File truncated <==i(RttailtsztlinestlineR R\R]R^tfsizetnewszt bytes_addedRtseektreadtbytesR_R`(RRRRRRR((RR s(       i c Cs|iidd|ii}}g}g}d}x|djoPn|ii||ii d}|djoOt ||joPn|i di|}|o |i|g}n|i||d}||ijoPn|d}q;W|i ||fS(Niiis RE(RRRttelltposRRRt num_bytesRtbytetlentmaxtreverseR2Rtappendt MAX_BUFFSIZE( RRRRRRRRR((RRs2       cCsti|iitiS(N(RtfstatRRtfilenotstattST_SIZE(R((RR;s(R+R3RRRRR(((RRs    cCs|djo t}n|i|||}|io|idi|in|i oPy dk }Wnt j onXdGdi|i GH|i |indS(NR6sprogram:(R8RRR&R'tcmdclasstctonecmdR2R treadlinet ImportErrorRRCtcmdloop(R'R8RRR((Rtmain>s        (t__doc__RR=R9R R_RRFRR+tos.pathR0RR/R.R!t scriptdirtlowerRRtzdaemon.zdoptionsRRRR:R5RRR(RRRRFRRR/RR9RR.R R=RR5R_R0RR((Rt?+s,           4: