Log in |
Installing, configuring, and administering ZEOSummaryThis document describes in detail how to install, configure, and administer ZEO in conjunction with Zope. Since I haven't gotten it to work yet, I discuss all the alternatives I've tried. This is not an introduction to ZEO. Please see the references [ref] for that. UpdateI have gotten scenario 3 to work [scenario3] at least from a Hello World perspective (I can login to the ZMI and the Control Panel | Database Management tab indicates ClientStorage is being used). The other scenarios I've documented:
fail in the same way. Zope works fine if I omit custom_zodb.py (that is, without ZEO). ZEO works fine, as demonstrated with the non-Zope test script [testzeo]. When I add the custom_zodb.py to the instance home (which in scenario 2 is the same as software home), Zope appears to start just fine (when I examine the stupid log file, there are no errors). However, when I access the ZMI (e.g., http://localhost:8080/manage), Zope seems to hang--and nothing is written to the stupid log file. VersionsThese are the versions of ZEO, Zope, and Python I discuss in this document. ZEO
Zope
Python
Operating systemI performed these installations on Red Hat Linux 7.3 unless otherwise noted. All the command samples that aren't prefixed by "sudo" are performed as a normal user. That won't work for you unless you configure /etc/sudoers. I simply added the following line to /etc/sudoers:
mark ALL=(ALL) ALL
If you haven't configured /etc/sudoers, consider it. Otherwise, simply login as root (i.e., type Single point of failureYou cannot install ZEO without first installing Zope. However, you don't have to run Zope on the computer where your ZEO storage server (ZSS) resides. If you can afford the hardware, it's preferable from the standpoint of reliability to run ZEO on a separate computer from your Zope client(s). The reason is that your ZSS becomes your single point of failure and you want to minimize the risk that something can go wrong on the computer where it resides. The general principle is the fewer things you run, the fewer chances something can go wrong. Having said that, it's convenient to be able to install both ZEO and the Zope client on the same computer when you're just getting familiar with ZEO. Installation overviewThe basic process of installing, configuring, and running ZEO is:
The basic process of installing, configuring, and running a Zope client is:
Configuration overview: ZEOTODO: Refine this section! When you start ZEO, you don't need to specify a storage for ZEO to serve. If you don't specify a storage, it will serve up a default storage derived from the environment. I prefer to specify the storage for ZEO to serve explicitly rather than rely on this implicit behavior. The way you specify a storage for ZEO to serve (it can serve more than one storage) is with the -S option to ZEO's start.py. You can see our sample zeo_start file [zeostart] specifies this option explicitly. This is the syntax of the -S option:
-S storage_name=module_name:attribute_name
I haven't figured out a good layout for ZEO yet, so in the meantime, I just place my storage module in the ZEO folder and name it StorageConfig.py. When you specify the module_name in the -S option, you omit the .py extension. The storage_name is the name by which ZEO clients will specify the storage they want to be served. The attribute_name is the name assigned to the storage in the module. Configuring ZEO involves:
Notice that we explicitly specify the storage to serve in zeo_start via the -S option. Without that, ZEO will derive the storage to serve from the environment. When you're trying to understand what's happening, this implicit behavior can be confusing, to say the least. Our -S option ( One of the things that confused me about this particular installation scenario is after I installed Zope, I had two Data.fs files: one in /usr/share/zope/var and one in /var/zope/var. The reason is the Zope RPM was designed to create an INSTANCE_HOME in /var/zope/. Once I understood that, I still wondered, "So which Data.fs do I serve up from ZEO?" In other words, if I have a dedicated ZEO machine, INSTANCE_HOME is not only irrelevant, it seems confusing. I realize ZEO is piggybacking on top of Zope, but it might go a long way towards clarifying the administration tasks specific to ZEO to make the installation of ZEO less dependent on and bound up with the installation of Zope since it seems likely that ZEO will often be run on a dedicated machine where Zope will not be run. Use casesThese are the use cases I discuss:
Installing ZEOThese are the scenarios I've tried:
Installation scenario 1: RPMI prefer RPMs because they are simple to install and remove; and they provide a uniform way to query what's installed. Further, if you need esoteric compilation switches, you can make your own RPM. The approach I describe in this scenario has several disadvantages:
Install Python
Install Zope
Install ZEO
Configure ZEO
Start ZEOTo start ZEO, you merely need to run zeo_start:
$ sudo /usr/share/zope/zeo_start
Stop ZEOTo stop ZEO, use zeo_stop:
$ sudo /usr/share/zope/zeo_stop
Test ZEO
You should see something like this scroll across each screen:
{'_pack_time': 925771972.67781401, 'Application': <Application instance at 855fd70>}
Configure Zope
Start ZopeYou can start Zope using the /sbin/service facility:
$ sudo /sbin/service zope start
Stop ZopeYou can stop Zope using the /sbin/service facility:
$ sudo /sbin/service zope stop
Test Zope
UninstallingIf you're experimenting with different scenarios described here and you want to remove this one without preserving any of the files installed or generated during your experimentation, here's a quick and easy way to do it.
Installation scenario 2: Source tarball, latest distributed releaseInstall Python
Install Zope
Install ZEO
Configure ZEO
Start ZEOTo start ZEO, you merely need to run zeo_start:
$ sudo /usr/local/zope/zeo_start
Stop ZEOTo stop ZEO, use zeo_stop:
$ sudo /usr/local/zope/zeo_stop
Test ZEO
You should see something like this scroll across each screen:
{'_pack_time': 925771972.67781401, 'Application': <Application instance at 855fd70>}
Configure Zope
Start ZopeYou can start Zope using the start script:
$ sudo /usr/local/zope/start
Stop ZopeYou can stop Zope using the stop script:
$ sudo /usr/local/zope/stop
Test Zope
Uninstalling
Installation scenario 3: CVSYou can access the Zope CVS . You can use the cvs-zope [cvszope] script to make accessing Zope's CVS even easier. Install PythonUse the same procedure as defined in scenario 2 [scenario2]. Install ZopeDecide which branch you want to use:
I haven't gotten the latter to work with ZEO yet, but I have gotten the former to work.
Install ZEO
Start ZEO and ZopeThe zctl script in the instance home allows you to start Zope and ZEO separately. If you start Zope and you're using ZEO but ZEO is not running, zctl will start ZEO for you. However, it seems like you have to run zctl from the instance home directory:
$ cd /opt/zope_instances/zope_1
$ sudo -u zope ./zctl start
TODO: Why doesn't it work starting as root (sudo ./zctl start)? Effective user control in Zope is problematic and is currently being overhauled. Installation scenario 4: Red Hat 7.2, ZEO 1, previous releasesTODO Running ZEO with one Zope client on the same computerTODO Running ZEO with one Zope client on a different computerTODO Running ZEO with multiple Zope clientsTODO Migrating from a standalone Zope server to ZEOTODO Managing a Zope client: Products, External Methods, etc.TODO Configuration issuesSecurityHow do you secure a ZEO server? The following snippet from the much outdated ZEOFactSheet suggests you can: To support distribution to externally controlled Zope sites, the ZSS can restrict connections (1) by address, (2) require a security key, and/or (3) permit read-only access. These features make ZEO a good fit for the classic "Internet mirror". ReferencesHere are the ZEO resources I have found useful:
Useful scriptsTODO: Explain settings in each script. This is the buildrpm script:
#!/bin/bash
if [ -z "$1" ] ; then
echo "Usage: `basename $0` srpm"
exit 1
fi
srpm=$1
if [ ! -d $HOME/rpm ] ; then
mkdir $HOME/rpm
mkdir $HOME/rpm/SOURCES
mkdir $HOME/rpm/SPECS
mkdir $HOME/rpm/BUILD
mkdir $HOME/rpm/SRPMS
mkdir $HOME/rpm/RPMS
mkdir $HOME/rpm/RPMS/i386
fi
if [ ! -f $HOME/.rpmmacros ] ; then
echo "%_topdir $HOME/rpm" > $HOME/.rpmmacros
fi
rpmbuild --rebuild $srpm
xxx This Python script performs a simplistic test for large file support. I have no idea whether the test is valid. This code is from the the Zope branch chrism-install-branch in the file $/Zope/inst/configure.py:
# lfs.py
import sys
OK=0
f = open(sys.argv[0], 'r')
try:
# 2**31 == 2147483648
f.seek(2147483649L)
f.close()
OK=1
except (IOError, OverflowError):
f.close()
if OK:
print "large file support enabled"
else:
print "large file support not enabled"
xxx This Python script (based on code posted by Greg Ward) can be used to test access to ZEO without using Zope:
#!/usr/bin/env python2.1
import sys
usage = "Usage: %s host port storage pythonpath"
prog = sys.argv[0]
try:
host = sys.argv[1]
port = int(sys.argv[2])
storage_name = sys.argv[3]
pythonpath = sys.argv[4]
except IndexError:
print usage % prog
sys.exit(1)
sys.path.insert(0, pythonpath)
import time
from pprint import pprint
from ZEO.ClientStorage import ClientStorage
from ZODB.DB import DB
s = ClientStorage((host, port), storage=storage_name)
db = DB(s)
conn = db.open()
# Pause 5 seconds.
pause = 5
while 1:
pprint(conn.root())
time.sleep(pause)
xxx This is the zeo_start file:
#!/bin/sh
reldir=`dirname $0`
use_unix_sockets=0
zope_user=zope
port=8800
host=127.0.0.1
if [ $use_unix_sockets == 1 ] ; then
socket_file=$reldir/var/zeo.soc
if [ -S $socket_file ] ; then
rm $socket_file
fi
exec python2.1 $reldir/lib/python/ZEO/start.py \
-S main=StorageConfig:main_storage \
-u $zope_user \
-U $socket_file \
ZEO_SERVER_PID=$reldir/var/ZEO_SERVER.pid \
STUPID_LOG_FILE=$reldir/var/ZEO_EVENTS.log \
"$@"
else
exec python2.1 $reldir/lib/python/ZEO/start.py \
-S main=StorageConfig:main_storage \
-u $zope_user \
-p $port \
-h $host \
ZEO_SERVER_PID=$reldir/var/ZEO_SERVER.pid \
STUPID_LOG_FILE=$reldir/var/ZEO_EVENTS.log \
"$@"
fi
xxx This is the zeo_stop file:
#!/bin/sh
reldir=`dirname $0`
kill `cat $reldir/var/ZEO_SERVER.pid`
xxx This is the StorageConfig.py module:
import os
zope_path = # You must specify this; e.g., /usr/share/zope
storage_path = os.path.join(zope_path, "var", "Data.fs")
import ZODB.FileStorage
main_storage = ZODB.FileStorage.FileStorage(storage_path)
xxx This is the zope start file for the RPM installation:
#!/bin/sh
export INSTANCE_HOME=/var/zope
cd $INSTANCE_HOME
/usr/bin/env python2.1 z2.py \
-u zope \
-z /usr/share/zope \
-Z /var/run/zwatchdog.pid \
-w 127.0.0.1:8080 \
-f '' \
-m '' \
-l /var/log/zope \
STUPID_LOG_FILE=/var/zope/zope_stupid.log \
ZEO_CLIENT=8800 \
FORCE_PRODUCT_LOAD=1 \
>> /var/log/zope 2>&1 \
&
xxx ... [customzodb] This is the custom_zodb.py module:
import os
zope_path = # You must specify this; e.g., /usr/share/zope
socket_file = os.path.join(zope_path, "var", "zeo.soc")
use_unix_sockets = 0
zeo_server = "127.0.0.1"
port = 8800
storage_name = "main"
from ZEO.ClientStorage import ClientStorage
if use_unix_sockets:
Storage = ClientStorage(socket_file, storage=storage_name)
else:
Storage = ClientStorage((zeo_server, port), storage=storage_name)
xxx This is the Zope start script for a source install:
#! /bin/sh
reldir=`dirname $0`
INST_HOME=`cd $reldir; pwd`
STUPID_LOG_FILE=$reldir/var/ZOPE_EVENTS.log
PYTHONPATH=$reldir/lib/python
export INST_HOME
export STUPID_LOG_FILE
export PYTHONPATH
exec python2.1 \
$INST_HOME/z2.py \
-u zope \
-w 127.0.0.1:8080 \
-f '' \
-m '' \
-l /var/log/zope \
ZEO_CLIENT=8800 \
FORCE_PRODUCT_LOAD=1 \
"$@"
xxx I place this script in a directory that's on the $PATH so that I can access easily access Zope's CVS:
#!/bin/bash
CVSROOT=:pserver:anonymous@cvs.zope.org:/cvs-repository
export CVSROOT
cvs login
bash -login
|