[Zope-Checkins] CVS: Zope/lib/python/zdaemon - zdctl.py:1.9.10.1 zdctl.sh:1.2.18.1 Daemon.py:1.11.4.6 zdaemon.py:1.22.2.2
Chris McDonough
chrism@zope.com
Fri, 3 Jan 2003 01:39:50 -0500
Update of /cvs-repository/Zope/lib/python/zdaemon
In directory cvs.zope.org:/tmp/cvs-serv28978
Modified Files:
Tag: chrism-install-branch
Daemon.py zdaemon.py
Added Files:
Tag: chrism-install-branch
zdctl.py zdctl.sh
Log Message:
Merging chrism-install-branch with HEAD (hopefully for one of the last
times).
=== Added File Zope/lib/python/zdaemon/zdctl.py ===
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""zdctl -- control an application run by zdaemon.
Usage: python zdctl.py -C config-file [action [arguments]]
Options:
-C/--configuration URL -- configuration file or URL
action [arguments] -- see below
If no action is specified on the command line, a "shell" interpreting
actions typed interactively is started.
Use the action "help" to find out about available actions.
"""
from __future__ import nested_scopes
# XXX Related code lives in lib/python/Controller/ZctlLib.py on the
# 'chrism-install-branch' branch.
# The code there knows more about Zope and about Windows, but doesn't
# use zdaemon.py or ZConfig.
import os
import re
import cmd
import sys
import time
import signal
import socket
if __name__ == "__main__":
# Add the parent of the script directory to the module search path
from os.path import dirname, abspath, normpath
sys.path.append(dirname(dirname(normpath(abspath(sys.argv[0])))))
from ZEO.runsvr import Options
class ZDOptions(Options):
# Where's python?
python = sys.executable
# Where's zdaemon?
if __name__ == "__main__":
_file = sys.argv[0]
else:
_file = __file__
_file = os.path.normpath(os.path.abspath(_file))
_dir = os.path.dirname(_file)
zdaemon = os.path.join(_dir, "zdaemon.py")
# Options for zdaemon
backofflimit = 10 # -b SECONDS
forever = 0 # -f
sockname = os.path.abspath("zdsock") # -s SOCKET
exitcodes = [0, 2] # -x LIST
user = None # -u USER
zdirectory = "/" # -z DIRECTORY
# Program (and arguments) for zdaemon
program = None
def load_configuration(self):
Options.load_configuration(self) # Sets self.rootconf
if not self.rootconf:
self.usage("a configuration file is required; use -C")
# XXX Should allow overriding more zdaemon options here
if self.program is None:
self.program = self.rootconf.getlist("program")
if self.program is None:
self.usage("no program specified in configuration")
class ZDCmd(cmd.Cmd):
prompt = "(zdctl) "
def __init__(self, options):
self.options = options
cmd.Cmd.__init__(self)
self.get_status()
if self.zd_status:
m = re.search("(?m)^args=(.*)$", self.zd_status)
if m:
s = m.group(1)
args = eval(s, {"__builtins__": {}})
if args != self.options.program:
print "WARNING! zdaemon is managing a different program!"
print "our program =", self.options.program
print "daemon's args =", args
def send_action(self, action):
"""Send an action to the zdaemon server and return the response.
Return None if the server is not up or any other error happened.
"""
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
sock.connect(self.options.sockname)
sock.send(action + "\n")
sock.shutdown(1) # We're not writing any more
response = ""
while 1:
data = sock.recv(1000)
if not data:
break
response += data
sock.close()
return response
except socket.error, msg:
return None
def get_status(self):
self.zd_up = 0
self.zd_pid = 0
self.zd_status = None
resp = self.send_action("status")
if not resp:
return
m = re.search("(?m)^application=(\d+)$", resp)
if not m:
return
self.zd_up = 1
self.zd_pid = int(m.group(1))
self.zd_status = resp
def awhile(self, cond, msg):
try:
self.get_status()
while not cond():
sys.stdout.write(". ")
sys.stdout.flush()
time.sleep(1)
self.get_status()
except KeyboardInterrupt:
print "^C"
else:
print msg % self.__dict__
def help_help(self):
print "help -- Print a list of available actions."
print "help <action> -- Print help for <action>."
def do_start(self, arg):
self.get_status()
if not self.zd_up:
args = [
self.options.python,
self.options.zdaemon,
"-b", str(self.options.backofflimit),
"-d",
"-s", self.options.sockname,
"-x", ",".join(map(str, self.options.exitcodes)),
"-z", self.options.zdirectory,
]
if self.options.forever:
args.append("-f")
if self.options.user:
argss.extend(["-u", str(self.options.user)])
args.extend(self.options.program)
os.spawnvp(os.P_WAIT, args[0], args)
elif not self.zd_pid:
self.send_action("start")
else:
print "daemon process already running; pid=%d" % self.zd_pid
return
self.awhile(lambda: self.zd_pid,
"daemon process started, pid=%(zd_pid)d")
def help_start(self):
print "start -- Start the daemon process."
print " If it is already running, do nothing."
def do_stop(self, arg):
self.get_status()
if not self.zd_up:
print "daemon manager not running"
elif not self.zd_pid:
print "daemon process not running"
else:
self.send_action("stop")
self.awhile(lambda: not self.zd_pid, "daemon process stopped")
def help_stop(self):
print "stop -- Stop the daemon process."
print " If it is not running, do nothing."
def do_restart(self, arg):
self.get_status()
pid = self.zd_pid
if not pid:
self.do_start(arg)
else:
self.send_action("restart")
self.awhile(lambda: self.zd_pid not in (0, pid),
"daemon process restarted, pid=%(zd_pid)d")
def help_restart(self):
print "restart -- Stop and then start the daemon process."
def do_kill(self, arg):
if not arg:
sig = signal.SIGTERM
else:
try:
sig = int(arg)
except: # int() can raise any number of exceptions
print "invalid signal number", `arg`
return
self.get_status()
if not self.zd_pid:
print "daemon process not running"
return
print "kill(%d, %d)" % (self.zd_pid, sig)
try:
os.kill(self.zd_pid, sig)
except os.error, msg:
print "Error:", msg
else:
print "signal %d sent to process %d" % (sig, self.zd_pid)
def help_kill(self):
print "kill [sig] -- Send signal sig to the daemon process."
print " The default signal is SIGTERM."
def do_wait(self, arg):
self.awhile(lambda: not self.zd_pid, "daemon process stopped")
self.do_status()
def help_wait(self):
print "wait -- Wait for the daemon process to exit."
def do_status(self, arg=""):
self.get_status()
if not self.zd_up:
print "daemon manager not running"
elif not self.zd_pid:
print "daemon manager running; daemon process not running"
else:
print "program running; pid=%d" % self.zd_pid
if arg == "-l" and self.zd_status:
print self.zd_status
def help_status(self):
print "status [-l] -- Print status for the daemon process."
print " With -l, show raw status output as well."
def do_logreopen(self, arg):
self.do_kill(str(signal.SIGUSR2))
def help_logreopen(self):
print "logreopen -- Send a SIGUSR2 signal to the daemon process."
print " This is designed to reopen the log file."
def do_quit(self, arg):
self.get_status()
if not self.zd_up:
print "daemon manager not running"
elif not self.zd_pid:
print "daemon process not running; stopping daemon manager"
self.send_action("exit")
self.awhile(lambda: not self.zd_up, "daemon manager stopped")
else:
print "daemon process and daemon manager still running"
return 1
def help_quit(self):
print "quit -- Exit the zdctl shell."
print (" If the daemon process is not running, "
"stop the daemon manager.")
def main(args=None):
options = ZDOptions(args)
c = ZDCmd(options)
if options.args:
c.onecmd(" ".join(options.args))
else:
print "program:", " ".join(options.program)
c.do_status()
c.cmdloop()
if __name__ == "__main__":
main()
=== Added File Zope/lib/python/zdaemon/zdctl.sh ===
#! /bin/sh
#
# Copy this script into the /etc/rc.d/init.d directory and edit the
# description line below and the pathnames; then run chkconfig(8).
#
# chkconfig: 345 90 10
# description: start a Zope-related server (Zope, ZEO or ZRS)
# Edit to indicate which Python to use
PYTHON=/usr/local/bin/python2.2
# Edit to indicate where the core Zope software lives
ZOPE_HOME=$HOME/projects/Zope
# Edit to indicate where your Zope instance lives
INSTANCE_HOME=$HOME/projects/Zope
# Edit to indicate where your config file is
CONFIG_LOCATION=$INSTANCE_HOME/sample.conf
# You shouldn't need to edit these
SOFTWARE_HOME=$ZOPE_HOME/lib/python
ZDCTL=$SOFTWARE_HOME/zdaemon/zdctl.py
CMD="$PYTHON $ZDCTL -C $CONFIG_LOCATION"
# Parse the command line
case $1 in
[a-z]*[a-z]) $CMD "$@";;
-i) $CMD;;
*) echo "Usage: $0 start|stop|restart|status|help|etc."
echo " $0 -i starts an interactive zdctl shell."
;;
esac
=== Zope/lib/python/zdaemon/Daemon.py 1.11.4.5 => 1.11.4.6 ===
--- Zope/lib/python/zdaemon/Daemon.py:1.11.4.5 Sun Nov 24 18:53:58 2002
+++ Zope/lib/python/zdaemon/Daemon.py Fri Jan 3 01:39:15 2003
@@ -12,7 +12,7 @@
#
##############################################################################
-import os, sys, time, signal
+import os, sys, signal
import zLOG
pyth = sys.executable
=== Zope/lib/python/zdaemon/zdaemon.py 1.22.2.1 => 1.22.2.2 ===
--- Zope/lib/python/zdaemon/zdaemon.py:1.22.2.1 Sun Nov 24 18:53:58 2002
+++ Zope/lib/python/zdaemon/zdaemon.py Fri Jan 3 01:39:15 2003
@@ -1,7 +1,18 @@
#! /usr/bin/env python
-
-"""
-zdaemon -- run an application as a daemon.
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+"""zdaemon -- run an application as a daemon.
Usage: python zdaemon.py [zdaemon-options] program [program-arguments]
Or: python zdaemon.py -c [command]
@@ -154,7 +165,7 @@
print __doc__,
sys.exit(0)
if o == "-s":
- self.sockname = a
+ self.sockname = os.path.abspath(a)
if o == "-u":
self.user = a
if o == "-x":
@@ -797,6 +808,7 @@
def main(args=None):
assert os.name == "posix", "This code makes many Unix-specific assumptions"
+ zLOG.initialize()
d = Daemonizer()
d.main(args)