[Zodb-checkins] CVS: ZODB3/zdaemon - sample.conf:1.3 schema.xml:1.4 zdctl.py:1.20 zdoptions.py:1.8 zdrun.py:1.5
Guido van Rossum
guido@python.org
Tue, 21 Jan 2003 13:20:12 -0500
Update of /cvs-repository/ZODB3/zdaemon
In directory cvs.zope.org:/tmp/cvs-serv8707
Modified Files:
sample.conf schema.xml zdctl.py zdoptions.py zdrun.py
Log Message:
Make zdrun and zdctl share more configuration.
zrdun no longer has a "client" mode; you have to do that using zdctl.
This isn't completely cooked yet; I have disabled some tests that were
using zdrun's client mode until I find time to figure out how to
rewrite those tests.
=== ZODB3/zdaemon/sample.conf 1.2 => 1.3 ===
--- ZODB3/zdaemon/sample.conf:1.2 Mon Jan 20 11:21:02 2003
+++ ZODB3/zdaemon/sample.conf Tue Jan 21 13:19:38 2003
@@ -1,11 +1,9 @@
# Sample config file for zdctl.py and zdrun.py (which share a schema).
-<zdctl>
- # This is a pure example
- program sleep 100
-</zdctl>
-
-<zdrun>
+<runner>
+ # Harmless example
+ program sleep 100
+ # Repeat the defaults
backoff-limit 10
daemon True
forever True
@@ -13,4 +11,4 @@
exit-codes 0,2
# user has no default
directory /
-</zdrun>
+</runner>
=== ZODB3/zdaemon/schema.xml 1.3 => 1.4 ===
--- ZODB3/zdaemon/schema.xml:1.3 Mon Jan 20 11:21:02 2003
+++ ZODB3/zdaemon/schema.xml Tue Jan 21 13:19:38 2003
@@ -4,11 +4,10 @@
Schema for zdctl.py and zdrun.py.
</description>
- <sectiontype name="zdctl">
+ <sectiontype name="runner">
+ <key name="python" datatype="existing-path" />
+ <key name="zdrun" datatype="existing-path" />
<key name="program" datatype="string-list" required="yes" />
- </sectiontype>
-
- <sectiontype name="zdrun">
<key name="backoff-limit" datatype="integer" default="10" />
<key name="daemon" datatype="boolean" default="False" />
<key name="forever" datatype="boolean" default="False" />
@@ -19,7 +18,6 @@
<key name="directory" datatype="existing-directory" default="/" />
</sectiontype>
- <section name="*" type="zdctl" attribute="zdctl" required="yes" />
- <section name="*" type="zdrun" attribute="zdrun" required="yes" />
+ <section name="*" type="runner" attribute="runner" required="yes" />
</schema>
=== ZODB3/zdaemon/zdctl.py 1.19 => 1.20 ===
--- ZODB3/zdaemon/zdctl.py:1.19 Mon Jan 20 11:32:41 2003
+++ ZODB3/zdaemon/zdctl.py Tue Jan 21 13:19:38 2003
@@ -14,12 +14,21 @@
##############################################################################
"""zdctl -- control an application run by zdaemon.
-Usage: python zdctl.py [-C URL] [-h] [-p PROGRAM] [action [arguments]]
+Usage: python zdctl.py [-C URL] [-h] [-p PROGRAM]
+ [zdrun-options] [action [arguments]]
Options:
-C/--configuration URL -- configuration file or URL
-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
-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)
+-x/--exit-codes LIST -- list of fatal exit codes (default "0,2")
+-z/--directory DIRECTORY -- directory to chdir to when using -d (default "/")
action [arguments] -- see below
Actions are commands like "start", "stop" and "status". If no action
@@ -45,46 +54,48 @@
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])))))
+ # (but only when the script is run from inside the zdaemon package)
+ from os.path import dirname, basename, abspath, normpath
+ scriptdir = dirname(normpath(abspath(sys.argv[0])))
+ if basename(scriptdir).lower() == "zdaemon":
+ sys.path.append(dirname(scriptdir))
import ZConfig
-from zdaemon.zdoptions import ZDOptions
+from zdaemon.zdoptions import RunnerOptions
def string_list(arg):
return arg.split()
-class ZDCtlOptions(ZDOptions):
+class ZDCtlOptions(RunnerOptions):
positional_args_allowed = 1
- # 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, "zdrun.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
-
def __init__(self):
- ZDOptions.__init__(self)
- self.add("program", "zdctl.program", "p:", "program=",
+ RunnerOptions.__init__(self)
+ self.add("program", "runner.program", "p:", "program=",
handler=string_list,
required="no program specified; use -p or -C")
+ self.add("python", "runner.python")
+ self.add("zdrun", "runner.zdrun")
+
+ def realize(self, *args, **kwds):
+ RunnerOptions.realize(self, *args, **kwds)
+
+ # Where's python?
+ if not self.python:
+ self.python = sys.executable
+
+ # Where's zdrun?
+ if not self.zdrun:
+ if __name__ == "__main__":
+ file = sys.argv[0]
+ else:
+ file = __file__
+ file = os.path.normpath(os.path.abspath(file))
+ dir = os.path.dirname(file)
+ self.zdrun = os.path.join(dir, "zdrun.py")
class ZDCmd(cmd.Cmd):
@@ -101,7 +112,7 @@
s = m.group(1)
args = eval(s, {"__builtins__": {}})
if args != self.options.program:
- print "WARNING! zdaemon is managing a different program!"
+ print "WARNING! zdrun is managing a different program!"
print "our program =", self.options.program
print "daemon's args =", args
@@ -109,7 +120,7 @@
pass # We don't want a blank line to repeat the last command
def send_action(self, action):
- """Send an action to the zdaemon server and return the response.
+ """Send an action to the zdrun server and return the response.
Return None if the server is not up or any other error happened.
"""
@@ -169,7 +180,7 @@
if not self.zd_up:
args = [
self.options.python,
- self.options.zdaemon,
+ self.options.zdrun,
"-b", str(self.options.backofflimit),
"-d",
"-s", self.options.sockname,
@@ -287,7 +298,7 @@
def show_options(self):
print "schemafile: ", repr(self.options.schemafile)
print "configfile: ", repr(self.options.configfile)
- print "zdaemon: ", repr(self.options.zdaemon)
+ print "zdrun: ", repr(self.options.zdrun)
print "program: ", repr(self.options.program)
print "backofflimit:", repr(self.options.backofflimit)
print "forever: ", repr(self.options.forever)
=== ZODB3/zdaemon/zdoptions.py 1.7 => 1.8 ===
--- ZODB3/zdaemon/zdoptions.py:1.7 Mon Jan 20 11:21:02 2003
+++ ZODB3/zdaemon/zdoptions.py Tue Jan 21 13:19:38 2003
@@ -273,6 +273,24 @@
EventLogger.event_logger.logger = logger
+class RunnerOptions(ZDOptions):
+
+ def __init__(self):
+ ZDOptions.__init__(self)
+ self.add("backofflimit", "runner.backoff_limit",
+ "b:", "backoff-limit=", int, default=10)
+ self.add("daemon", "runner.daemon", "d", "daemon", flag=1, default=0)
+ self.add("forever", "runner.forever", "f", "forever",
+ flag=1, default=0)
+ self.add("sockname", "runner.socket_name", "s:", "socket-name=",
+ ZConfig.datatypes.existing_dirpath, default="zdsock")
+ self.add("exitcodes", "runner.exit_codes", "x:", "exit-codes=",
+ list_of_ints, default=[0, 2])
+ self.add("user", "runner.user", "u:", "user=")
+ self.add("zdirectory", "runner.directory", "z:", "directory=",
+ ZConfig.datatypes.existing_directory, default="/")
+
+
# ZConfig datatype
def list_of_ints(arg):
=== ZODB3/zdaemon/zdrun.py 1.4 => 1.5 ===
--- ZODB3/zdaemon/zdrun.py:1.4 Mon Jan 20 11:32:41 2003
+++ ZODB3/zdaemon/zdrun.py Tue Jan 21 13:19:38 2003
@@ -15,12 +15,10 @@
"""zrdun -- run an application as a daemon.
Usage: python zrdun.py [zrdun-options] program [program-arguments]
-Or: python zrdun.py -c [command]
Options:
-C/--configuration URL -- configuration file or URL
-b/--backoff-limit SECONDS -- set backoff limit to SECONDS (default 10)
--c/--client -- client mode, to sends a command to the daemon manager
-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
@@ -30,20 +28,6 @@
-z/--directory DIRECTORY -- directory to chdir to when using -d (default "/")
program [program-arguments] -- an arbitrary application to run
-Client mode options:
- -s SOCKET -- socket name (a Unix pathname) for client communication
- [command] -- the command to send to the daemon manager (default "status")
-
-Client commands are:
- help -- return command help
- status -- report application status (this is the default command)
- kill [signal] -- send a signal to the application
- (default signal is SIGTERM)
- start -- start the application if not already running
- stop -- stop the application if running; daemon manager keeps running
- restart -- stop followed by start
- exit -- stop the application and exit
-
This daemon manager has two purposes: it restarts the application when
it dies, and (when requested to do so with the -d option) it runs the
application in the background, detached from the foreground tty
@@ -91,32 +75,28 @@
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])))))
+ # (but only when the script is run from inside the zdaemon package)
+ from os.path import dirname, basename, abspath, normpath
+ scriptdir = dirname(normpath(abspath(sys.argv[0])))
+ if basename(scriptdir).lower() == "zdaemon":
+ sys.path.append(dirname(scriptdir))
import ZConfig.datatypes
import zLOG
-from zdaemon.zdoptions import ZDOptions, list_of_ints
+from zdaemon.zdoptions import RunnerOptions
+
-class ZDRunOptions(ZDOptions):
+class ZDRunOptions(RunnerOptions):
positional_args_allowed = 1
+ program = None
- def __init__(self):
- ZDOptions.__init__(self)
- self.add("backofflimit", "zdrun.backoff_limit",
- "b:", "backoff-limit=", int, default=10)
- self.add("isclient", None, "c", "client", flag=1, default=0)
- self.add("daemon", "zdrun.daemon", "d", "daemon", flag=1, default=0)
- self.add("forever", "zdrun.forever", "f", "forever",
- flag=1, default=0)
- self.add("sockname", "zdrun.socket_name", "s:", "socket-name=",
- ZConfig.datatypes.existing_dirpath, default="zdsock")
- self.add("exitcodes", "zdrun.exit_codes", "x:", "exit-codes=",
- list_of_ints, default=[0, 2])
- self.add("user", "zdrun.user", "u:", "user=")
- self.add("zdirectory", "zdrun.directory", "z:", "directory=",
- ZConfig.datatypes.existing_directory, default="/")
+ def realize(self, *args, **kwds):
+ RunnerOptions.realize(self, *args, **kwds)
+ if self.args:
+ self.program = self.args
+ if not self.program:
+ self.usage("no program specified (use -C or positional args)")
class Subprocess:
@@ -224,47 +204,6 @@
"""
self.pid = 0
-class Client:
-
- """A class representing the control client."""
-
- def __init__(self, options, args=None):
- """Constructor.
-
- Arguments are an ZDRunOptions instance and a list of program
- arguments representing the command to send to the server.
- """
- self.options = options
- if args is None:
- args = options.args
- if not args:
- self.command = "status"
- else:
- self.command = " ".join(args)
-
- def doit(self):
- """Send the command to the server and write the results to stdout."""
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- try:
- sock.connect(self.options.sockname)
- except socket.error, msg:
- sys.stderr.write("Can't connect to %r: %s\n" %
- (self.options.sockname, msg))
- sys.exit(1)
- sock.send(self.command + "\n")
- sock.shutdown(1) # We're not writing any more
- lastdata = ""
- while 1:
- data = sock.recv(1000)
- if not data:
- break
- sys.stdout.write(data)
- lastdata = data
- if not lastdata:
- sys.stderr.write("No response received\n")
- sys.exit(1)
- if not lastdata.endswith("\n"):
- sys.stdout.write("\n")
class Daemonizer:
@@ -272,11 +211,7 @@
self.options = ZDRunOptions()
self.options.realize(args)
self.set_uid()
- if self.options.isclient:
- clt = Client(self.options)
- clt.doit()
- else:
- self.run()
+ self.run()
def set_uid(self):
if self.options.user is None: