File contents
#!/home/klm/work/zope/Zope/bin/python
# XXX ^^ Above, put the path to the bin/python of your Zope software home ^^
# -*- python -*-
"""Control Zope and ZEO server if it's configured
Usage:
%(zctl)s start [confname ...] [--zeo -arg ... [--zope]] -arg ...
%(zctl)s stop [confname ...]
%(zctl)s start_zeo
%(zctl)s stop_zeo
%(zctl)s status [confname ...]
%(zctl)s make_cgi [filename]
%(zctl)s debug
%(zctl)s test filename
%(zctl)s do [-i] [-f filename]* commands
The file 'zope.conf' must exist in the INSTANCE_HOME where '%(zctl)s' lives.
It contains configuration information for Zope, and optionally for ZEO.
Additional Zope configurations may be defined by creating subdirectories
of the INSTANCE_HOME containing 'conf.py'. If you specify the name of
one or more of these subdirectories in a '%(zctl)s start' or '%(zctl)s stop',
that configuration will be started or stopped instead of the default.
'%(zctl)s make_cgi' will write PCGI settings to the file you specify, or to
'Zope.cgi' if the name is omitted.
'%(zctl)s debug' will launch an interactive Python session with the Zope
application object loaded as 'app'.
""" % {'zctl': 'i1zctl.py'}
import sys, os, socket, time, string
from os.path import isfile, isdir, abspath
pjoin = os.path.join
psplit = os.path.split
env = os.environ
run = os.system
# Find out where we are, and where Python is.
if not sys.argv[0]: HERE = '.'
else: HERE = psplit(sys.argv[0])[0]
HERE = abspath(HERE)
PYTHON = '"%s"' % sys.executable
ZOPE_ENV = {}
ZEO = {} # ZEO is off by default
# Load configuration data into global variables
ZOPE_CONFIG = pjoin(HERE, 'zope.conf')
if not isfile(ZOPE_CONFIG):
print 'Zope configuration file "zope.conf" not found.'
sys.exit(1)
execfile(ZOPE_CONFIG, globals())
# Poke environment variables needed by Zope and ZEO
env['INSTANCE_HOME'] = HERE
ZOPE_HOME = abspath(ZOPE_HOME)
for k, v in ZEO.items():
env[k] = str(v)
PYTHONPATH = env.get('PYTHONPATH', '')
PYTHONPATH = "%s:%s/lib/python%s%s" % (ZOPE_HOME, ZOPE_HOME,
PYTHONPATH and '', PYTHONPATH)
# Commands
def test(args):
print PYTHON
print HERE
print ZOPE_HOME
print ZEO
def start(args):
"""Start Zope when ZEO is reachable, starting ZEO first if necessary."""
clients = []
zeo_args = []
zope_args = []
while args and args[0][:1] != '-':
clients.append(args.pop(0))
while args:
if args[0] == '--zeo':
args.pop(0)
while args and args[0][:2] != '--':
zeo_args.append(args.pop(0))
else:
if args[0] == '--zope':
args.pop(0)
while args and args[0][:2] != '--':
zope_args.append(args.pop(0))
if not clients:
clients.append('default')
cmd = '%s "%s/z2.py" %%s' % (PYTHON, ZOPE_HOME)
global ZOPE_PORT, ZOPE_LOG, ZOPE_OPTS, ZOPE_ENV, CLIENT_HOME
for client in clients:
args = list(zope_args)
if client != 'default':
ZOPE_PORT = ZOPE_LOG = ZOPE_OPTS = None
CLIENT_HOME = pjoin(HERE, client)
conf = pjoin(CLIENT_HOME, 'conf.py')
if not (isdir(CLIENT_HOME) and isfile(conf)):
print 'Client configuration file "%s" was not found.' % conf
continue
execfile(conf, globals())
args.append('"CLIENT_HOME=%s"' % CLIENT_HOME)
if ZOPE_OPTS is not None:
args.insert(0, ZOPE_OPTS)
if ZOPE_PORT is not None:
args.insert(0, '-P %s' % ZOPE_PORT)
if ZOPE_LOG is not None:
args.append('"STUPID_LOG_FILE=%s"' % ZOPE_LOG)
for k,v in ZOPE_ENV.items():
env[k] = str(v)
if ZEO:
start_zeo(zeo_args)
print 'Starting %s (%s) Zope...' % (client, ZOPE_PORT or 80)
run(cmd % string.join(args))
def start_zeo(args):
"""Try to start ZEO."""
host = ZEO.get('ZEO_SERVER_NAME', 'localhost')
port = ZEO['ZEO_SERVER_PORT']
if host == 'localhost' and not _check_for_service(host, port):
stop_zeo(None)
print "Starting ZEO server on", port
cmd = 'PYTHONPATH=%s %s %s/lib/python/ZEO/start.py -p %s %s &' % (
PYTHONPATH, PYTHON, ZOPE_HOME, port, string.join(args)
)
run(cmd)
count = 0
while not _check_for_service(host, port):
count = count + 1
if count > ZEO_WAIT_BAILOUT:
print ("ZEO connect failure, on port %s after %d seconds"
% (port, ZEO_WAIT_BAILOUT))
sys.exit(1)
print "waiting for ZEO server to start %d/%d" % (count,
ZEO_WAIT_BAILOUT)
time.sleep(1)
print "ZEO server ready."
def stop_zeo(args):
"""Stop the ZEO server."""
try:
pids = open('%s/var/ZEO_SERVER.pid' % HERE, 'r').read()
except:
return
print "Stopping ZEO pid: %s" % pids
run('kill %s' % pids)
def stop(args):
"""Stop client(s)."""
if not args:
args = ['var']
for client in args:
pidf = pjoin(HERE, client, 'Z2.pid')
if not isfile(pidf):
print '"%s" was not found' % pidf
continue
run('kill %s' % open(pidf, 'r').read())
def status(args):
"""Print status."""
print "NAME\tPORT\tPIDS"
if ZEO:
host = ZEO.get('ZEO_SERVER_NAME', 'localhost')
port = ZEO['ZEO_SERVER_PORT']
pids = ''
if _check_for_service(host, port):
if host == 'localhost':
pids = open('%s/var/ZEO_SERVER.pid' % HERE, 'r').read()
else:
pids = 'unknown'
print "ZEO\t%s\t%s" % (port, pids)
if not args:
import glob
for client in glob.glob('%s/*/conf.py' % HERE):
args.append(psplit(psplit(client)[0])[1])
for client in args:
pidf = pjoin(HERE, client, 'Z2.pid')
if isfile(pidf):
pids = open(pidf, 'r').read()
else:
pids = 'not found'
print '%s\t%s\t%s' % (client, '', pids)
def make_cgi(args):
"""Create a PCGI parameter file."""
if args:
fname = args.pop(0)
else:
fname = 'Zope.cgi'
write = open(fname, 'w').write
write('''\
#!%(ZOPE_HOME)s/pcgi/pcgi-wrapper
PCGI_NAME=Zope
PCGI_MODULE_PATH=%(ZOPE_HOME)s/lib/python/Zope
PCGI_PUBLISHER=%(ZOPE_HOME)s/pcgi/pcgi_publisher.py
PCGI_EXE=%(PYTHON)s
PCGI_SOCKET_FILE=%(HERE)s/var/pcgi.soc
PCGI_PID_FILE=%(HERE)s/var/pcgi.pid
PCGI_ERROR_LOG=%(HERE)s/var/pcgi.log
PCGI_DISPLAY_ERRORS=1
BOBO_REALM=Zope
BOBO_DEBUG_MODE=1
INSTANCE_HOME=%(HERE)s
''' % globals())
def do(args):
"""Execute python commands"""
if ZEO:
start_zeo([])
for k,v in ZOPE_ENV.items():
env[k] = str(v)
os.chdir(pjoin(ZOPE_HOME, 'lib', 'python'))
msg = """
Zope debugging session for %s
The root application object is bound to name 'app'.
To let other people see your changes, you must:
get_transaction().commit()
To see other people's changes, you must:
app._p_jar.sync()""" % HERE
options = "-c"
if not args or '-i' in args:
options = '-i ' + options
if args:
args.remove('-i')
print msg
while '-f' in args:
fpos = args.index('-f')
args.pop(fpos)
args[fpos] = 'execfile("%s");' % args[fpos]
cmd = ("%s %s 'import Zope, sys; app=Zope.app(); %s'"
% (PYTHON, options, string.join(args, " ")))
run(cmd)
def debug(args):
"""Start an interactive debugging session"""
args.insert(0, '-i')
do(args)
def test(args):
"""Run tests"""
args[0] = os.path.abspath(args[0])
args.insert(0, '-f')
do(args)
# Internal helper functions
def _check_for_service(host, port):
"""Return 1 if server is found at (host, port), 0 otherwise."""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((host, int(port)))
return 1
except socket.error:
return 0
def _dispatch():
"""Dispatch command line invocation."""
if len(sys.argv) == 1:
print """\
start [confname ...] [--zeo -arg ... [--zope]] -arg ...
stop [confname ...]
start_zeo
stop_zeo
status [confname ...]
make_cgi [filename]
debug
test filename
do [-i] [-f filename]* commands
"""
args = string.split(raw_input('command: '))
else:
args = sys.argv[1:]
action = string.lower(args.pop(0))
if action[:1] == '_':
print 'Invalid action "%s"' % action
sys.exit(1)
globals()[action](args)
if __name__ == "__main__":
_dispatch()