[CalendarServer-changes] [963] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Jan 8 09:30:53 PST 2007
Revision: 963
http://trac.macosforge.org/projects/calendarserver/changeset/963
Author: dreid at apple.com
Date: 2007-01-08 09:30:53 -0800 (Mon, 08 Jan 2007)
Log Message:
-----------
merge users/dreid/cluster-2 to provide support for a variety of clustering schemes including multiprocess support on a single machine with a tcp load balancer. The default by is still a single process.
Modified Paths:
--------------
CalendarServer/trunk/bin/caldavd
CalendarServer/trunk/conf/caldavd-test.plist
CalendarServer/trunk/conf/caldavd.plist
CalendarServer/trunk/run
CalendarServer/trunk/support/Makefile.Apple
CalendarServer/trunk/twistedcaldav/config.py
CalendarServer/trunk/twistedcaldav/tap.py
Added Paths:
-----------
CalendarServer/trunk/lib-patches/Twisted/twisted.python.procutils.patch
CalendarServer/trunk/lib-patches/Twisted/twisted.runner.procmon.patch
CalendarServer/trunk/twistedcaldav/cluster.py
Modified: CalendarServer/trunk/bin/caldavd
===================================================================
--- CalendarServer/trunk/bin/caldavd 2007-01-08 17:22:20 UTC (rev 962)
+++ CalendarServer/trunk/bin/caldavd 2007-01-08 17:30:53 UTC (rev 963)
@@ -27,6 +27,7 @@
configfile="";
twistdpath="$(type -p twistd)";
plugin_name="caldav";
+service_type="";
py_version ()
{
@@ -78,7 +79,7 @@
if [ "${1--}" != "-" ]; then echo "${1}"; echo; fi;
- echo "Usage: ${program} [-hX] [-u username] [-g groupname] [-T twistd] [-f caldavd.plist]";
+ echo "Usage: ${program} [-hX] [-u username] [-g groupname] [-T twistd] [-t type] [-f caldavd.plist]";
echo "Options:";
echo " -h Print this help and exit";
echo " -X Do not daemonize";
@@ -86,12 +87,13 @@
echo " -g Group to run as";
echo " -f Configuration file to read";
echo " -T Path to twistd binary";
+ echo " -t Service type (master, slave, standalone, cluster)";
if [ "${1-}" == "-" ]; then return 0; fi;
exit 64;
}
-while getopts 'hXu:g:f:T:P:' option; do
+while getopts 'hXu:g:f:T:P:t:' option; do
case "${option}" in
'?') usage; ;;
'h') usage -; exit 0; ;;
@@ -101,6 +103,7 @@
'u') username="-u ${OPTARG}"; ;;
'g') groupname="-g ${OPTARG}"; ;;
'P') plugin_name="${OPTARG}"; ;;
+ 't') service_type="-o ServerType=${OPTARG}"; ;;
esac;
done;
@@ -108,4 +111,4 @@
if [ $# != 0 ]; then usage "Unrecognized arguments:" "$@"; fi;
-exec "${python}" "${twistdpath}" "${daemonize}" ${username} ${groupname} "${plugin_name}" ${configfile};
+exec "${python}" "${twistdpath}" "${daemonize}" ${username} ${groupname} "${plugin_name}" ${configfile} ${service_type};
Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist 2007-01-08 17:22:20 UTC (rev 962)
+++ CalendarServer/trunk/conf/caldavd-test.plist 2007-01-08 17:30:53 UTC (rev 963)
@@ -29,6 +29,11 @@
<key>DocumentRoot</key>
<string>twistedcaldav/test/data/</string>
+ <key>BindAddress</key>
+ <array>
+ <string>127.0.0.1</string>
+ </array>
+
<key>Port</key>
<integer>8008</integer>
@@ -186,5 +191,35 @@
<array>
<string>/principals/user/admin/</string>
</array>
+
+ <key>ServerType</key>
+ <string>singleprocess</string>
+
+ <key>MultiProcess</key>
+ <dict>
+ <key>NumProcesses</key>
+ <integer>2</integer>
+
+ <key>LoadBalancer</key>
+ <dict>
+ <key>Enabled</key>
+ <true/>
+
+ <key>Scheduler</key>
+ <!-- Least Connections -->
+ <string>leastconns</string>
+ <!-- Round Robin -->
+ <!-- <string>roundrobin</string> -->
+ <!-- Least Connections and Round Robin -->
+ <!-- <string>leastconnsrr</string> -->
+
+ </dict>
+ </dict>
+
+ <key>pydirLocation</key>
+ <string>../pydirector-1.0.0/pydir.py</string>
+
+ <key>pydirConfig</key>
+ <string>conf/pydir.xml</string>
</dict>
</plist>
Modified: CalendarServer/trunk/conf/caldavd.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd.plist 2007-01-08 17:22:20 UTC (rev 962)
+++ CalendarServer/trunk/conf/caldavd.plist 2007-01-08 17:30:53 UTC (rev 963)
@@ -29,6 +29,10 @@
<key>DocumentRoot</key>
<string>/Library/CalendarServer/Documents</string>
+ <key>BindAddress</key>
+ <array>
+ </array>
+
<key>Port</key>
<integer>8008</integer>
@@ -132,5 +136,33 @@
<array>
<string>/principals/user/admin/</string>
</array>
+ <key>ServerType</key>
+ <string>singleprocess</string>
+
+ <key>MultiProcess</key>
+ <dict>
+ <key>NumProcesses</key>
+ <integer>0</integer>
+
+ <key>LoadBalancer</key>
+ <dict>
+ <key>Enabled</key>
+ <false/>
+
+ <key>Scheduler</key>
+ <!-- Least Connections -->
+ <string>leastconns</string>
+ <!-- Round Robin -->
+ <!-- <string>roundrobin</string> -->
+ <!-- Least Connections and Round Robin -->
+ <!-- <string>leastconnsrr</string> -->
+ </dict>
+ </dict>
+
+ <key>pydirLocation</key>
+ <string>/usr/share/caldavd/bin/pydir++.py</string>
+
+ <key>pydirConfig</key>
+ <string>/etc/caldvad/pydir.xml</string>
</dict>
</plist>
Copied: CalendarServer/trunk/lib-patches/Twisted/twisted.python.procutils.patch (from rev 962, CalendarServer/branches/users/dreid/cluster-2/lib-patches/Twisted/twisted.python.procutils.patch)
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.python.procutils.patch (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.python.procutils.patch 2007-01-08 17:30:53 UTC (rev 963)
@@ -0,0 +1,13 @@
+Index: twisted/python/procutils.py
+===================================================================
+--- twisted/python/procutils.py (revision 18545)
++++ twisted/python/procutils.py (working copy)
+@@ -33,7 +33,7 @@
+ """
+ result = []
+ exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep))
+- for p in os.environ['PATH'].split(os.pathsep):
++ for p in os.environ.get('PATH', '').split(os.pathsep):
+ p = os.path.join(p, name)
+ if os.access(p, flags):
+ result.append(p)
Copied: CalendarServer/trunk/lib-patches/Twisted/twisted.runner.procmon.patch (from rev 962, CalendarServer/branches/users/dreid/cluster-2/lib-patches/Twisted/twisted.runner.procmon.patch)
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.runner.procmon.patch (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.runner.procmon.patch 2007-01-08 17:30:53 UTC (rev 963)
@@ -0,0 +1,29 @@
+Index: twisted/runner/procmon.py
+===================================================================
+--- twisted/runner/procmon.py (revision 18545)
++++ twisted/runner/procmon.py (working copy)
+@@ -130,10 +130,10 @@
+ self.consistency = reactor.callLater(self.consistencyDelay,
+ self._checkConsistency)
+
+- def addProcess(self, name, args, uid=None, gid=None):
++ def addProcess(self, name, args, uid=None, gid=None, env={}):
+ if self.processes.has_key(name):
+ raise KeyError("remove %s first" % name)
+- self.processes[name] = args, uid, gid
++ self.processes[name] = args, uid, gid, env
+ if self.active:
+ self.startProcess(name)
+
+@@ -175,9 +175,9 @@
+ p = self.protocols[name] = LoggingProtocol()
+ p.service = self
+ p.name = name
+- args, uid, gid = self.processes[name]
++ args, uid, gid, env = self.processes[name]
+ self.timeStarted[name] = time.time()
+- reactor.spawnProcess(p, args[0], args, uid=uid, gid=gid)
++ reactor.spawnProcess(p, args[0], args, uid=uid, gid=gid, env=env)
+
+ def _forceStopProcess(self, proc):
+ try:
Modified: CalendarServer/trunk/run
===================================================================
--- CalendarServer/trunk/run 2007-01-08 17:22:20 UTC (rev 962)
+++ CalendarServer/trunk/run 2007-01-08 17:30:53 UTC (rev 963)
@@ -35,6 +35,7 @@
install="";
daemonize="-X";
plugin_name="caldav";
+ service_type="singleprocess";
usage ()
{
@@ -53,12 +54,13 @@
echo " -d Run caldavd as a daemon";
echo " -i Perform a system install into dst; implies -s";
echo " -I Perform a home install into dst; implies -s";
+ echo " -t Select the type of server to run (singleprocess, multiprocess, or master)";
if [ "${1-}" == "-" ]; then return 0; fi;
exit 64;
}
-while getopts 'hvsfnpdP:i:I:' option; do
+while getopts 'hvsfnpdP:i:I:t:' option; do
case "$option" in
'?') usage; ;;
'h') usage -; exit 0; ;;
@@ -71,6 +73,7 @@
'P') plugin_name="${OPTARG}"; ;;
'i') setup_only="true"; install="${OPTARG}"; install_flag="--root="; ;;
'I') setup_only="true"; install="${wd}/build/dst"; install_flag="--root="; install_home="${OPTARG}"; ;;
+ 't') service_type="${OPTARG}"; ;;
esac;
done;
shift $((${OPTIND} - 1));
@@ -186,7 +189,7 @@
-f "${config}" \
-T "${twisted}/bin/twistd" \
-P "${plugin_name}" \
- ;
+ -t "${service_type}";
cd /;
fi;
}
@@ -527,6 +530,20 @@
fi;
#
+# PyDirector
+#
+
+if ! py_have_module pydirector; then
+ pydirector="${top}/pydirector-1.0.0";
+
+ www_get "PyDirector" "${pydirector}" http://easynews.dl.sourceforge.net/sourceforge/pythondirector/pydirector-1.0.0.tar.gz;
+ py_build "PyDirector" "${pydirector}" false;
+ py_install "PyDirector" "${pydirector}";
+
+ export PYTHONPATH="${PYTHONPATH}:${pydirector}/build/${py_platform_libdir}";
+fi;
+
+#
# Calendar Server
#
Modified: CalendarServer/trunk/support/Makefile.Apple
===================================================================
--- CalendarServer/trunk/support/Makefile.Apple 2007-01-08 17:22:20 UTC (rev 962)
+++ CalendarServer/trunk/support/Makefile.Apple 2007-01-08 17:30:53 UTC (rev 963)
@@ -63,6 +63,7 @@
Twisted::
@echo "Building Twisted..."
$(_v) cd $(BuildDirectory)/Twisted && $(Environment) $(PYTHON) twisted/topfiles/setup.py install $(PY_INSTALL_FLAGS)
+ $(_v) cd $(BuildDirectory)/Twisted && $(Environment) $(PYTHON) twisted/runner/topfiles/setup.py build
$(_v) cd $(BuildDirectory)/Twisted && $(TwistedSubEnvironment) $(PYTHON) twisted/web/topfiles/setup.py build
$(_v) cd $(BuildDirectory)/Twisted && $(TwistedSubEnvironment) $(PYTHON) twisted/web2/topfiles/setup.py build
Copied: CalendarServer/trunk/twistedcaldav/cluster.py (from rev 962, CalendarServer/branches/users/dreid/cluster-2/twistedcaldav/cluster.py)
===================================================================
--- CalendarServer/trunk/twistedcaldav/cluster.py (rev 0)
+++ CalendarServer/trunk/twistedcaldav/cluster.py 2007-01-08 17:30:53 UTC (rev 963)
@@ -0,0 +1,177 @@
+##
+# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# DRI: David Reid, dreid at apple.com
+##
+
+import os
+import sys
+import tempfile
+
+from twisted.runner import procmon
+
+from twistedcaldav.config import config
+
+serviceTemplate = """
+ <service name="%(name)s">
+ <listen ip="%(bindAddress)s:%(port)s" />
+ <group name="main" scheduler="%(scheduler)s">
+ %(hosts)s
+ </group>
+ <enable group="main" />
+ </service>
+"""
+
+configTemplate = """
+<pdconfig>
+ %(services)s
+</pdconfig>
+"""
+
+hostTemplate = '<host name="%(name)s" ip="%(bindAddress)s:%(port)s" />'
+
+
+class TwistdSlaveProcess(object):
+ prefix = "caldav"
+
+ def __init__(self, twistdLocation, configFile, interfaces, port, sslPort):
+ self.twistd = twistdLocation
+
+ self.configFile = configFile
+
+ self.port = port
+ self.sslPort = sslPort
+
+ self.pidFile = os.path.join(
+ os.path.dirname(config.PIDFile),
+ '%s.pid' % (self.getName(),))
+
+ self.interfaces = interfaces
+
+ def getName(self):
+ return '%s-%s' % (self.prefix, self.port)
+
+ def getSSLName(self):
+ return '%s-%s' % (self.prefix, self.sslPort)
+
+ def getCommandLine(self):
+ return [
+ sys.executable,
+ self.twistd, '-n', 'caldav',
+ '-f', self.configFile,
+ '-o', 'ServerType=singleprocess',
+ '-o', 'BindAddress=%s' % (','.join(self.interfaces),),
+ '-o', 'Port=%s' % (self.port,),
+ '-o', 'SSLPort=%s' % (self.sslPort,),
+ '-o', 'PIDFile=%s' % (self.pidFile,)]
+
+ def getHostLine(self, ssl=None):
+ name = self.getName()
+ port = self.port
+
+ if ssl:
+ name = self.getSSLName()
+ port = self.sslPort
+
+ return hostTemplate % {'name': name,
+ 'port': port,
+ 'bindAddress': '127.0.0.1'}
+
+def makeService_multiprocess(self, options):
+ service = procmon.ProcessMonitor()
+
+ parentEnv = {'PYTHONPATH': os.environ.get('PYTHONPATH', ''),}
+
+ hosts = []
+ sslHosts = []
+
+ port = config.Port
+ sslport = config.SSLPort
+
+ bindAddress = ['127.0.0.1']
+
+ if not config.MultiProcess['LoadBalancer']['Enabled']:
+ bindAddress = config.BindAddress
+
+ for p in xrange(0, config.MultiProcess['NumProcesses']):
+ port += 1
+ sslport += 1
+
+ process = TwistdSlaveProcess(config.twistdLocation,
+ options['config'],
+ bindAddress,
+ port, sslport)
+
+ service.addProcess(process.getName(),
+ process.getCommandLine(),
+ uid=options.parent['uid'],
+ gid=options.parent['gid'],
+ env=parentEnv)
+
+ if not config.SSLOnly:
+ hosts.append(process.getHostLine())
+
+ if config.SSLEnable:
+ sslHosts.append(process.getHostLine(ssl=True))
+
+ if config.MultiProcess['LoadBalancer']['Enabled']:
+ services = []
+
+ if not config.BindAddress:
+ config.BindAddress = ['']
+
+ for bindAddress in config.BindAddress:
+ if not config.SSLOnly:
+ services.append(serviceTemplate % {
+ 'name': 'http',
+ 'bindAddress': bindAddress,
+ 'port': config.Port,
+ 'scheduler':
+ config.MultiProcess['LoadBalancer']['Scheduler'],
+ 'hosts': '\n'.join(hosts)
+ })
+
+ if config.SSLEnable:
+ services.append(serviceTemplate % {
+ 'name': 'https',
+ 'bindAddress': bindAddress,
+ 'port': config.SSLPort,
+ 'scheduler':
+ config.MultiProcess['LoadBalancer']['Scheduler'],
+ 'hosts': '\n'.join(sslHosts),
+ })
+
+ pdconfig = configTemplate % {
+ 'services': '\n'.join(services),
+ }
+
+ fd, fname = tempfile.mkstemp(prefix='pydir')
+ os.write(fd, pdconfig)
+ os.close(fd)
+
+ service.addProcess('pydir', [sys.executable,
+ config.pydirLocation,
+ fname])
+
+ return service
+
+def makeService_pydir(self, options):
+ service = procmon.ProcessMonitor()
+
+ service.addProcess('pydir', [sys.executable,
+ config.pydirLocation,
+ config.pydirConfig])
+
+ return service
Modified: CalendarServer/trunk/twistedcaldav/config.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/config.py 2007-01-08 17:22:20 UTC (rev 962)
+++ CalendarServer/trunk/twistedcaldav/config.py 2007-01-08 17:30:53 UTC (rev 963)
@@ -23,6 +23,7 @@
defaultConfigFile = '/etc/caldavd/caldavd.plist'
defaultConfig = {
+ 'BindAddress': ['127.0.0.1'],
'CalendarUserProxyEnabled': True,
'DirectoryService': {
'params': {'node': '/Search'},
@@ -46,7 +47,6 @@
'ServerStatsFile': '/Library/CalendarServer/Documents/stats.plist',
'UserQuotaBytes': 104857600,
'Verbose': False,
- 'twistdLocation': '/usr/share/caldavd/bin/twistd',
'SACLEnable': False,
'Authentication': {
'Basic': {
@@ -61,10 +61,23 @@
'ServicePrincipal': '',
},
},
- 'AdminPrincipals': ['/principals/user/admin/']
-}
+ 'AdminPrincipals': ['/principals/user/admin/'],
+ 'twistdLocation': '/usr/share/caldavd/bin/twistd',
+ 'pydirLocation': '/usr/share/caldavd/bin/pydir++.py',
+ 'pydirConfig': '/etc/caldavd/pydir.xml',
+ 'ServerType': 'singleprocess',
+
+ 'MultiProcess': {
+ 'NumProcesses': 10,
+ 'LoadBalancer': {
+ 'Enabled': True,
+ 'Scheduler': 'leastconns',
+ },
+ },
+ }
+
class Config (object):
def __init__(self, defaults):
self.update(defaults)
Modified: CalendarServer/trunk/twistedcaldav/tap.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/tap.py 2007-01-08 17:22:20 UTC (rev 962)
+++ CalendarServer/trunk/twistedcaldav/tap.py 2007-01-08 17:30:53 UTC (rev 963)
@@ -23,7 +23,7 @@
from twisted.python import log
-from twisted.python.usage import Options
+from twisted.python.usage import Options, UsageError
from twisted.python.reflect import namedClass
from twisted.application import internet, service
@@ -41,6 +41,7 @@
from twisted.web2.log import LogWrapperResource
from twisted.web2.server import Site
+from twistedcaldav.cluster import makeService_multiprocess, makeService_pydir
from twistedcaldav.config import config, parseConfig, defaultConfig
from twistedcaldav.logging import RotatingFileAccessLoggingObserver
from twistedcaldav.root import RootResource
@@ -102,7 +103,7 @@
value = value.split(',')
elif isinstance(defaultConfig[key], dict):
- raise usage.UsageError(
+ raise UsageError(
"We do not support dict options on the command line")
self.overrides[key] = value
@@ -140,7 +141,7 @@
principalResourceClass = DirectoryPrincipalProvisioningResource
calendarResourceClass = CalendarHomeProvisioningFile
- def makeService(self, options):
+ def makeService_singleprocess(self, options):
#
# Setup the Directory
#
@@ -248,19 +249,46 @@
service = CalDAVService(logObserver)
- if not config.SSLOnly:
- httpService = internet.TCPServer(int(config.Port), channel)
+ if not config.BindAddress:
+ config.BindAddress = ['']
- httpService.setServiceParent(service)
+ for bindAddress in config.BindAddress:
+ if not config.SSLOnly:
+ httpService = internet.TCPServer(int(config.Port), channel,
+ interface=bindAddress)
+ httpService.setServiceParent(service)
- if config.SSLEnable:
- from twisted.internet.ssl import DefaultOpenSSLContextFactory
- httpsService = internet.SSLServer(
- int(config.SSLPort),
- channel,
- DefaultOpenSSLContextFactory(config.SSLPrivateKey,
- config.SSLCertificate))
+ if config.SSLEnable:
+ from twisted.internet.ssl import DefaultOpenSSLContextFactory
+ httpsService = internet.SSLServer(
+ int(config.SSLPort),
+ channel,
+ DefaultOpenSSLContextFactory(config.SSLPrivateKey,
+ config.SSLCertificate),
+ interface=bindAddress
+ )
+ httpsService.setServiceParent(service)
+
+ return service
- httpsService.setServiceParent(service)
+ makeService_slave = makeService_singleprocess
+
+ makeService_multiprocess = makeService_multiprocess
+
+ makeService_master = makeService_pydir
+
+ def makeService(self, options):
+ serverType = config.ServerType
+
+ serviceMethod = getattr(self, 'makeService_%s' % (serverType,), None)
+
+ if not serviceMethod:
+ raise UsageError(
+ ("Unknown server type %s, please choose: singleprocess, "
+ "multiprocess, master, slave" % (serverType,)))
+
+ else:
+ return serviceMethod(options)
- return service
+
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070108/aa19ce56/attachment.html
More information about the calendarserver-changes
mailing list