Revision: 1496 http://trac.macosforge.org/projects/calendarserver/changeset/1496 Author: dreid@apple.com Date: 2007-04-24 11:34:04 -0700 (Tue, 24 Apr 2007) Log Message: ----------- Ok this does two things: 1) it fixes #162 which it does by 2) allowing you to specify deep overrides on the command line using '/' seperated paths. For example -o MultiProcess/ProcessCount=1 So #162 is fixed by telling all subprocesses how many process their are, then for the ProcessCount=1 case we don't try to hook up the PDClientAddressWrapper hack. Fixes #162 Modified Paths: -------------- CalendarServer/trunk/twistedcaldav/cluster.py CalendarServer/trunk/twistedcaldav/tap.py CalendarServer/trunk/twistedcaldav/test/test_tap.py Modified: CalendarServer/trunk/twistedcaldav/cluster.py =================================================================== --- CalendarServer/trunk/twistedcaldav/cluster.py 2007-04-24 17:41:18 UTC (rev 1495) +++ CalendarServer/trunk/twistedcaldav/cluster.py 2007-04-24 18:34:04 UTC (rev 1496) @@ -56,7 +56,8 @@ class TwistdSlaveProcess(object): prefix = "caldav" - def __init__(self, twistd, tapname, configFile, interfaces, port, sslPort): + def __init__(self, twistd, tapname, configFile, + interfaces, port, sslPort): self.twistd = twistd self.tapname = tapname @@ -94,8 +95,11 @@ '-o', 'BindSSLPorts=%s' % (','.join(map(str, self.sslPorts)),), '-o', 'PIDFile=None', '-o', 'ErrorLogFile=None', - '-o', 'SharedSecret=%s' % (config.SharedSecret,)]) + '-o', 'SharedSecret=%s' % (config.SharedSecret,), + '-o', 'MultiProcess/ProcessCount=%d' % ( + config.MultiProcess['ProcessCount'],)]) + return args def getHostLine(self, ssl=None): Modified: CalendarServer/trunk/twistedcaldav/tap.py =================================================================== --- CalendarServer/trunk/twistedcaldav/tap.py 2007-04-24 17:41:18 UTC (rev 1495) +++ CalendarServer/trunk/twistedcaldav/tap.py 2007-04-24 18:34:04 UTC (rev 1496) @@ -25,6 +25,7 @@ import os import stat import sys +import copy from zope.interface import implements @@ -97,6 +98,49 @@ self.overrides = {} + def _coerceOption(self, configDict, key, value): + """ + Coerce the given C{val} to type of C{configDict[key]} + """ + if key in configDict: + if isinstance(configDict[key], bool): + value = value == "True" + + elif isinstance(configDict[key], (int, float, long)): + value = type(configDict[key])(value) + + elif isinstance(configDict[key], (list, tuple)): + value = value.split(',') + + elif isinstance(configDict[key], dict): + raise UsageError("Dict options not supported on the command line") + + elif value == 'None': + value = None + + return value + + def _setOverride(self, configDict, path, value, overrideDict): + """ + Set the value at path in configDict + """ + key = path[0] + + if len(path) == 1: + overrideDict[key] = self._coerceOption(configDict, key, value) + return + + if key in configDict: + if not isinstance(configDict[key], dict): + raise UsageError( + "Found intermediate path element that is not a dictionary") + + if key not in overrideDict: + overrideDict[key] = {} + + self._setOverride( + configDict[key], path[1:], value, overrideDict[key]) + def opt_option(self, option): """ Set an option to override a value in the config file. True, False, int, @@ -106,25 +150,9 @@ """ if '=' in option: - key, value = option.split('=') - - if key in defaultConfig: - if isinstance(defaultConfig[key], bool): - value = value == "True" - - elif isinstance(defaultConfig[key], (int, float, long)): - value = type(defaultConfig[key])(value) - - elif isinstance(defaultConfig[key], (list, tuple)): - value = value.split(',') - - elif isinstance(defaultConfig[key], dict): - raise UsageError("Dict options not supported on the command line") - - elif value == 'None': - value = None - - self.overrides[key] = value + path, value = option.split('=') + self._setOverride( + defaultConfig, path.split('/'), value, self.overrides) else: self.opt_option('%s=True' % (option,)) @@ -457,10 +485,13 @@ log.msg("Setting up service") if config.ProcessType == 'Slave': - realRoot = pdmonster.PDClientAddressWrapper( - logWrapper, - config.PythonDirector['ControlSocket'] - ) + if config.MultiProcess['ProcessCount'] > 1: + realRoot = pdmonster.PDClientAddressWrapper( + logWrapper, + config.PythonDirector['ControlSocket'] + ) + else: + realRoot = logWrapper logObserver = logging.AMPCommonAccessLoggingObserver(config.ControlSocket) Modified: CalendarServer/trunk/twistedcaldav/test/test_tap.py =================================================================== --- CalendarServer/trunk/twistedcaldav/test/test_tap.py 2007-04-24 17:41:18 UTC (rev 1495) +++ CalendarServer/trunk/twistedcaldav/test/test_tap.py 2007-04-24 18:34:04 UTC (rev 1496) @@ -154,7 +154,17 @@ self.assertEquals(config.Authentication['Basic']['Enabled'], myConfig['Authentication']['Basic']['Enabled']) + def test_specifyDictPath(self): + """ + Test that we can specify command line overrides to leafs using + a '/' seperated path. Such as '-o MultiProcess/ProcessCount=1' + """ + argv = ['-o', 'MultiProcess/ProcessCount=102'] + self.config.parseOptions(argv) + + self.assertEquals(config.MultiProcess['ProcessCount'], 102) + class BaseServiceMakerTests(unittest.TestCase): """ Utility class for ServiceMaker tests.