[Zope-Checkins] CVS: Zope2 - zctl_lib.py:1.1.2.1
evan@serenade.digicool.com
evan@serenade.digicool.com
Thu, 19 Apr 2001 16:45:50 -0400
Update of /cvs-repository/Zope2/utilities
In directory serenade.digicool.com:/home/evan/Zope/trunk/utilities
Added Files:
Tag: evan-makefile-branch
zctl_lib.py
Log Message:
Allow directories to opt out of module compilation with a .no_pycompile file.
--- Added File zctl_lib.py in package Zope2 ---
def zctl_usage(args):
print """Control Zope, and ZEO server if it's configured
Usage:
zctl.py start [--zeo -arg ... [--zope]] -arg ...
Start Zope, checking that ZEO is up and starting it, if necessary.
zctl.py stop
Stop Zope. Does not stop ZEO.
zctl.py debug
Open an interactive Python session with Zope loaded.
zctl.py test filename
zctl.py script filename
Load Zope environment, then execute file as a Python program.
zctl.py do [-i] [-f filename]* commands
Execute Python commands and zero or more files.
zctl.py stop_all
Stop Zope, and run ZEO stop script if possible.
zctl.py start_zeo
Run ZEO start script if possible.
zctl.py stop_zeo
Run ZEO stop script if possible.
zctl.py status
Show the status of Zope, and possibly ZEO.
zctl.py make_cgi [filename]
Write a Zope.cgi file for use with PCGI.
zctl.py usage | --help
Print this information.
'zctl.py' contains configuration information for Zope, and optionally
for connecting to ZEO, for a single Zope instance. The directory
containing the file 'zctl.py' is the INSTANCE_HOME. More than one
INSTANCE_HOME can be set up to use the same copy of the Zope software,
and each one can have its own Zope database(s), Products, and
Extensions.
If an instance uses a ZEO server, then you can run a 'zctl.py debug'
session without stopping the Zope instance.
"""
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 = os.curdir()
else: HERE = psplit(sys.argv[0])[0]
HERE = abspath(HERE)
ZOPE_HOME = abspath(ZOPE_HOME)
CLIENT_HOME = pjoin(HERE, 'var')
PYTHON = '"%s"' % sys.executable
ZOPE = {}
ZOPE_ENV = {}
ZEO = {} # ZEO is off by default
# Define 'constants'
OPTS, PORT, LOG, WAIT, SOCKET, CONTROL = (
'OPTS', 'PORT', 'LOG', 'WAIT', 'SOCKET', 'CONTROL')
# Commands
def zctl_start(args):
"""Start Zope when ZEO is reachable, starting ZEO first if necessary."""
pidf = pjoin(CLIENT_HOME, 'Z2.pid')
running = _check_pids(pidf)
if running:
for pid, up in running.items():
if up:
print 'There appears to be a Zope instance already running.'
print 'Either stop it, or delete "%s".' % pidf
return
zeo_args = []
zope_args = []
app = zope_args.append
while args:
arg = args.pop(0)
if arg[:2] == '--':
argmap = {'zeo': zeo_args, 'zope': zope_args}.get(arg[2:])
if argmap is None:
app(arg)
else:
app = argmap.append
else:
app(arg)
cmd = '%s "%s/z2.py" %%s' % (PYTHON, ZOPE_HOME)
args = list(zope_args)
if ZOPE.get(OPTS):
args.insert(0, ZOPE[OPTS])
if ZOPE.get(PORT):
args.insert(0, '-P %s' % ZOPE[PORT])
if ZOPE.get(LOG):
args.append('"STUPID_LOG_FILE=%s"' % ZOPE[LOG])
for k,v in ZOPE_ENV.items():
env[k] = str(v)
env['INSTANCE_HOME'] = HERE
if ZEO:
zctl_start_zeo(zeo_args)
env['ZEO_SOCKET'] = ZEO[SOCKET]
cmd = cmd % string.join(args)
print 'Starting Zope, using:'
print cmd
run(cmd)
def zctl_start_zeo(args):
"""Try to start ZEO."""
zeosocket = ZEO.get(SOCKET)
if zeosocket is None:
print 'Error: ZEO[SOCKET] is not defined.'
return
elif ':' in zeosocket:
zeosocket = tuple(string.split(zeosocket, ':'))
host, port = zeosocket
if ZEO.get(CONTROL) and not _check_for_service(zeosocket):
run(ZEO[CONTROL] + ' start ' + ZEO.get(OPTS, ''))
count = 0
ZEO_WAIT_BAILOUT = ZEO.get(WAIT, 60)
while not _check_for_service(zeosocket):
count = count + 1
if count > ZEO_WAIT_BAILOUT:
print ("ZEO connect failure, on %s after %d seconds"
% (zeosocket, ZEO_WAIT_BAILOUT))
sys.exit(1)
print "waiting for ZEO server to start %d/%d" % (count,
ZEO_WAIT_BAILOUT)
time.sleep(1)
if host == 'localhost' and not _check_for_service(host, port):
print "Starting ZEO server on", port
cmd = '%s %s/lib/python/ZEO/start.py -p %s %s &' % (
PYTHON, ZOPE_HOME, port, string.join(args)
)
run(cmd)
def zctl_stop_zeo(args):
"""Stop the ZEO server."""
if not ZEO.get(CONTROL):
print 'Error: ZEO[CONTROL] is not defined.'
return
run(ZEO[CONTROL] + ' stop')
def zctl_stop(args):
"""Stop client."""
pidf = pjoin(CLIENT_HOME, 'Z2.pid')
if not isfile(pidf):
print '"%s" was not found' % pidf
return
for pid in string.split(open(pidf).read()):
print 'Stopping Zope process %s' % pid
os.kill(int(pid), 15)
def zctl_stop_all(args):
"Stop client and ZEO server"
zctl_stop(args)
zctl_stop_zeo(args)
def zctl_status(args):
"""Print status."""
pidf = pjoin(CLIENT_HOME, 'Z2.pid')
running = _check_pids(pidf)
if running is None:
print 'No Zope process found.'
return
for pid, up in running.items():
if up is None:
print '%s is in pid file.' % pid
elif up:
print '%s is running.' % pid
else:
print '%s is in pid file, but not running.' % pid
def zctl_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=%(CLIENT_HOME)s/pcgi.soc
PCGI_PID_FILE=%(CLIENT_HOME)s/pcgi.pid
PCGI_ERROR_LOG=%(CLIENT_HOME)s/pcgi.log
PCGI_DISPLAY_ERRORS=1
BOBO_REALM=Zope
BOBO_DEBUG_MODE=1
INSTANCE_HOME=%(HERE)s
''' % globals())
def zctl_do(args):
"""Execute python commands"""
if ZEO:
start_zeo([])
for k,v in ZOPE_ENV.items():
env[k] = str(v)
env['INSTANCE_HOME'] = HERE
cwd = os.getcwd()
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]
imports = 'import Zope'
if not (os.path.samefile(cwd, os.getcwd()) or
os.path.samefile(cwd, HERE)):
imports = '%s; import sys; sys.path.append("%s")' % (
imports, cwd)
cmd = ("%s %s '%s; app=Zope.app(); %s'"
% (PYTHON, options, imports, string.join(args, " ")))
run(cmd)
def zctl_debug(args):
"""Start an interactive debugging session"""
args.insert(0, '-i')
zctl_do(args)
def zctl_script(args):
"""Execute a Python script"""
args[0] = os.path.abspath(args[0])
args.insert(0, '-f')
zctl_do(args)
def zctl_test(args):
"""Run a test"""
zctl_script(args)
# Internal helper functions
def _check_pids(pidfile):
"""Return dictionary of pids, or None if pidfile not found.
The value for each pid indicates whether the process is running.
"""
if isfile(pidfile):
pids = string.split(open(pidfile, 'r').read())
else:
return
running = {}
if isdir('/proc'):
for pid in pids:
running[pid] = isdir('/proc/%s' % pid)
else:
for pid in pids:
running[pid] = None
return running
def _check_for_service(ssock):
"""Return 1 if server is found, 0 otherwise."""
try:
if type(ssock) is type(()):
stype = socket.AF_INET
else:
stype = socket.AF_UNIX
s = socket.socket(stype, socket.SOCK_STREAM)
s.connect(ssock)
return 1
except socket.error:
return 0
def main():
"""Dispatch command line invocation."""
if len(sys.argv) == 1:
print """\
start [--zeo -arg ... [--zope]] -arg ...
stop
stop_all
start_zeo
stop_zeo
status
make_cgi [filename]
debug
test filename
do [-i] [-f filename]* commands
script filename
usage
"""
args = string.split(raw_input('command: '))
else:
args = sys.argv[1:]
action = string.lower(args.pop(0))
if action == '--help':
action = 'usage'
if not globals().has_key('zctl_'+action):
print 'Unknown command "%s"' % action
sys.exit(1)
for k, v in ZEO.items():
env['ZEO_'+k] = str(v)
globals()['zctl_'+action](args)