[CalendarServer-changes] [12483] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Mar 12 11:23:16 PDT 2014
Revision: 12483
http://trac.calendarserver.org//changeset/12483
Author: sagen at apple.com
Date: 2014-01-30 13:20:16 -0800 (Thu, 30 Jan 2014)
Log Message:
-----------
Starting work on directory proxy service
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tap/caldav.py
CalendarServer/trunk/twisted/plugins/caldav.py
CalendarServer/trunk/twistedcaldav/stdconfig.py
Added Paths:
-----------
CalendarServer/trunk/txdav/dps/
CalendarServer/trunk/txdav/dps/__init__.py
CalendarServer/trunk/txdav/dps/protocol.py
CalendarServer/trunk/txdav/dps/service.py
Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py 2014-01-30 18:51:26 UTC (rev 12482)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py 2014-01-30 21:20:16 UTC (rev 12483)
@@ -520,6 +520,27 @@
)
self.monitor.addProcessObject(process, PARENT_ENVIRONMENT)
+ if (
+ config.DirectoryProxy.Enabled and
+ config.DirectoryProxy.SocketPath != ""
+ ):
+ log.info("Adding directory proxy service")
+
+ dpsArgv = [
+ sys.executable,
+ sys.argv[0],
+ ]
+ if config.UserName:
+ dpsArgv.extend(("-u", config.UserName))
+ if config.GroupName:
+ dpsArgv.extend(("-g", config.GroupName))
+ dpsArgv.extend((
+ "--reactor=%s" % (config.Twisted.reactor,),
+ "-n", "caldav_directoryproxy",
+ "-f", self.configPath,
+ ))
+ self.monitor.addProcess("directoryproxy", dpsArgv,
+ env=PARENT_ENVIRONMENT)
class WorkSchedulingService(Service):
Modified: CalendarServer/trunk/twisted/plugins/caldav.py
===================================================================
--- CalendarServer/trunk/twisted/plugins/caldav.py 2014-01-30 18:51:26 UTC (rev 12482)
+++ CalendarServer/trunk/twisted/plugins/caldav.py 2014-01-30 21:20:16 UTC (rev 12483)
@@ -23,6 +23,7 @@
from twisted.internet.protocol import Factory
Factory.noisy = False
+
def serviceMakerProperty(propname):
def getProperty(self):
return getattr(reflect.namedClass(self.serviceMakerClass), propname)
@@ -50,3 +51,4 @@
TwistedCalDAV = TAP("calendarserver.tap.caldav.CalDAVServiceMaker")
+DirectoryProxy = TAP("txdav.dps.service.DirectoryProxyServiceMaker")
Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py 2014-01-30 18:51:26 UTC (rev 12482)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py 2014-01-30 21:20:16 UTC (rev 12483)
@@ -22,7 +22,7 @@
from twisted.python.runtime import platform
-from plistlib import PlistParser #@UnresolvedImport
+from plistlib import PlistParser # @UnresolvedImport
from twext.python.log import Logger, InvalidLogLevelError, LogLevel
from txweb2.dav.resource import TwistedACLInheritable
@@ -52,25 +52,25 @@
"twistedcaldav.directory.xmlfile.XMLDirectoryService": {
"xmlFile": "accounts.xml",
"recordTypes": ("users", "groups"),
- "statSeconds" : 15,
+ "statSeconds": 15,
},
"twistedcaldav.directory.appleopendirectory.OpenDirectoryService": {
"node": "/Search",
- "cacheTimeout": 1, # Minutes
- "batchSize": 100, # for splitting up large queries
+ "cacheTimeout": 1, # Minutes
+ "batchSize": 100, # for splitting up large queries
"negativeCaching": False,
"restrictEnabledRecords": False,
"restrictToGroup": "",
"recordTypes": ("users", "groups"),
},
"twistedcaldav.directory.ldapdirectory.LdapDirectoryService": {
- "cacheTimeout": 1, # Minutes
+ "cacheTimeout": 1, # Minutes
"negativeCaching": False,
"warningThresholdSeconds": 3,
- "batchSize": 500, # for splitting up large queries
- "requestTimeoutSeconds" : 10,
- "requestResultsLimit" : 200,
- "optimizeMultiName" : False,
+ "batchSize": 500, # for splitting up large queries
+ "requestTimeoutSeconds": 10,
+ "requestResultsLimit": 200,
+ "optimizeMultiName": False,
"queryLocationsImplicitly": True,
"restrictEnabledRecords": False,
"restrictToGroup": "",
@@ -79,7 +79,7 @@
"tls": False,
"tlsCACertFile": None,
"tlsCACertDir": None,
- "tlsRequireCert": None, # never, allow, try, demand, hard
+ "tlsRequireCert": None, # never, allow, try, demand, hard
"credentials": {
"dn": None,
"password": None,
@@ -90,76 +90,76 @@
"guidAttr": "entryUUID",
"users": {
"rdn": "ou=People",
- "attr": "uid", # used only to synthesize email address
- "emailSuffix": None, # used only to synthesize email address
- "filter": None, # additional filter for this type
- "loginEnabledAttr" : "", # attribute controlling login
- "loginEnabledValue" : "yes", # "True" value of above attribute
- "calendarEnabledAttr" : "", # attribute controlling enabledForCalendaring
- "calendarEnabledValue" : "yes", # "True" value of above attribute
- "mapping" : { # maps internal record names to LDAP
+ "attr": "uid", # used only to synthesize email address
+ "emailSuffix": None, # used only to synthesize email address
+ "filter": None, # additional filter for this type
+ "loginEnabledAttr": "", # attribute controlling login
+ "loginEnabledValue": "yes", # "True" value of above attribute
+ "calendarEnabledAttr": "", # attribute controlling enabledForCalendaring
+ "calendarEnabledValue": "yes", # "True" value of above attribute
+ "mapping": { # maps internal record names to LDAP
"recordName": "uid",
- "fullName" : "cn",
- "emailAddresses" : ["mail"],
- "firstName" : "givenName",
- "lastName" : "sn",
+ "fullName": "cn",
+ "emailAddresses": ["mail"],
+ "firstName": "givenName",
+ "lastName": "sn",
},
},
"groups": {
"rdn": "ou=Group",
- "attr": "cn", # used only to synthesize email address
- "emailSuffix": None, # used only to synthesize email address
- "filter": None, # additional filter for this type
- "mapping" : { # maps internal record names to LDAP
+ "attr": "cn", # used only to synthesize email address
+ "emailSuffix": None, # used only to synthesize email address
+ "filter": None, # additional filter for this type
+ "mapping": { # maps internal record names to LDAP
"recordName": "cn",
- "fullName" : "cn",
- "emailAddresses" : ["mail"],
- "firstName" : "givenName",
- "lastName" : "sn",
+ "fullName": "cn",
+ "emailAddresses": ["mail"],
+ "firstName": "givenName",
+ "lastName": "sn",
},
},
"locations": {
"rdn": "ou=Places",
- "attr": "cn", # used only to synthesize email address
- "emailSuffix": None, # used only to synthesize email address
- "filter": None, # additional filter for this type
- "calendarEnabledAttr" : "", # attribute controlling enabledForCalendaring
- "calendarEnabledValue" : "yes", # "True" value of above attribute
- "mapping" : { # maps internal record names to LDAP
+ "attr": "cn", # used only to synthesize email address
+ "emailSuffix": None, # used only to synthesize email address
+ "filter": None, # additional filter for this type
+ "calendarEnabledAttr": "", # attribute controlling enabledForCalendaring
+ "calendarEnabledValue": "yes", # "True" value of above attribute
+ "mapping": { # maps internal record names to LDAP
"recordName": "cn",
- "fullName" : "cn",
- "emailAddresses" : ["mail"],
- "firstName" : "givenName",
- "lastName" : "sn",
+ "fullName": "cn",
+ "emailAddresses": ["mail"],
+ "firstName": "givenName",
+ "lastName": "sn",
},
},
"resources": {
"rdn": "ou=Resources",
- "attr": "cn", # used only to synthesize email address
- "emailSuffix": None, # used only to synthesize email address
- "filter": None, # additional filter for this type
- "calendarEnabledAttr" : "", # attribute controlling enabledForCalendaring
- "calendarEnabledValue" : "yes", # "True" value of above attribute
- "mapping" : { # maps internal record names to LDAP
+ "attr": "cn", # used only to synthesize email address
+ "emailSuffix": None, # used only to synthesize email address
+ "filter": None, # additional filter for this type
+ "calendarEnabledAttr": "", # attribute controlling enabledForCalendaring
+ "calendarEnabledValue": "yes", # "True" value of above attribute
+ "mapping": { # maps internal record names to LDAP
"recordName": "cn",
- "fullName" : "cn",
- "emailAddresses" : ["mail"],
- "firstName" : "givenName",
- "lastName" : "sn",
+ "fullName": "cn",
+ "emailAddresses": ["mail"],
+ "firstName": "givenName",
+ "lastName": "sn",
},
},
},
"groupSchema": {
- "membersAttr": "member", # how members are specified
- "nestedGroupsAttr": None, # how nested groups are specified
- "memberIdAttr": None, # which attribute the above refer to
+ "membersAttr": "member", # how members are specified
+ "nestedGroupsAttr": None, # how nested groups are specified
+ "memberIdAttr": None, # which attribute the above refer to
},
"resourceSchema": {
- "resourceInfoAttr": None, # contains location/resource info
- "autoAcceptGroupAttr": None, # auto accept group
+ "resourceInfoAttr": None, # contains location/resource info
+ "autoAcceptGroupAttr": None, # auto accept group
},
"poddingSchema": {
- "serverIdAttr": None, # maps to augments server-id
+ "serverIdAttr": None, # maps to augments server-id
},
},
}
@@ -167,22 +167,22 @@
DEFAULT_RESOURCE_PARAMS = {
"twistedcaldav.directory.xmlfile.XMLDirectoryService": {
"xmlFile": "resources.xml",
- "recordTypes" : ("locations", "resources", "addresses"),
+ "recordTypes": ("locations", "resources", "addresses"),
},
"twistedcaldav.directory.appleopendirectory.OpenDirectoryService": {
"node": "/Search",
- "cacheTimeout": 1, # Minutes
+ "cacheTimeout": 1, # Minutes
"negativeCaching": False,
"restrictEnabledRecords": False,
"restrictToGroup": "",
- "recordTypes" : ("locations", "resources"),
+ "recordTypes": ("locations", "resources"),
},
}
DEFAULT_AUGMENT_PARAMS = {
"twistedcaldav.directory.augment.AugmentXMLDB": {
"xmlFiles": ["augments.xml", ],
- "statSeconds" : 15,
+ "statSeconds": 15,
},
"twistedcaldav.directory.augment.AugmentSqliteDB": {
"dbpath": "augments.sqlite",
@@ -229,8 +229,8 @@
"standardizeSyntheticUIDs": False,
"addDSAttrXProperties": False,
"appleInternalServer": False,
- "additionalAttributes" : [],
- "allowedAttributes" : [],
+ "additionalAttributes": [],
+ "allowedAttributes": [],
},
}
@@ -248,14 +248,16 @@
#
"ServerHostName": "", # Network host name.
"HTTPPort": 0, # HTTP port (0 to disable HTTP)
- "SSLPort" : 0, # SSL port (0 to disable HTTPS)
- "EnableSSL" : False, # Whether to listen on SSL port(s)
- "RedirectHTTPToHTTPS" : False, # If True, all nonSSL requests redirected to an SSL Port
- "SSLMethod" : "SSLv3_METHOD", # SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD
- "SSLCiphers" : "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM",
- "StrictTransportSecuritySeconds" : 7 * 24 * 60 * 60, # max-age value for
- # Strict-Transport-Security header; set to 0 to disable header.
+ "SSLPort": 0, # SSL port (0 to disable HTTPS)
+ "EnableSSL": False, # Whether to listen on SSL port(s)
+ "RedirectHTTPToHTTPS": False, # If True, all nonSSL requests redirected to an SSL Port
+ "SSLMethod": "SSLv3_METHOD", # SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD
+ "SSLCiphers": "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM",
+ # Max-age value for Strict-Transport-Security header; set to 0 to
+ # disable header.
+ "StrictTransportSecuritySeconds": 7 * 24 * 60 * 60,
+
#
# Network address configuration information
#
@@ -264,54 +266,54 @@
"BindAddresses": [], # List of IP addresses to bind to [empty = all]
"BindHTTPPorts": [], # List of port numbers to bind to for HTTP
# [empty = same as "Port"]
- "BindSSLPorts" : [], # List of port numbers to bind to for SSL
+ "BindSSLPorts": [], # List of port numbers to bind to for SSL
# [empty = same as "SSLPort"]
- "InheritFDs" : [], # File descriptors to inherit for HTTP requests
+ "InheritFDs": [], # File descriptors to inherit for HTTP requests
# (empty = don't inherit)
"InheritSSLFDs": [], # File descriptors to inherit for HTTPS requests
# (empty = don't inherit)
- "MetaFD" : 0, # Inherited file descriptor to call recvmsg() on to
+ "MetaFD": 0, # Inherited file descriptor to call recvmsg() on to
# receive sockets (none = don't inherit)
- "UseMetaFD" : True, # Use a 'meta' FD, i.e. an FD to transmit other FDs
+ "UseMetaFD": True, # Use a 'meta' FD, i.e. an FD to transmit other FDs
# to slave processes.
- "UseDatabase" : True, # True: database; False: files
+ "UseDatabase": True, # True: database; False: files
- "TransactionTimeoutSeconds" : 0, # Timeout transactions that take longer than
+ "TransactionTimeoutSeconds": 0, # Timeout transactions that take longer than
# the specified number of seconds. Zero means
# no timeouts
- "DBType" : "", # 2 possible values: empty, meaning 'spawn postgres
+ "DBType": "", # 2 possible values: empty, meaning 'spawn postgres
# yourself', or 'postgres', meaning 'connect to a
# postgres database as specified by the 'DSN'
# configuration key. Will support more values in
# the future.
- "SpawnedDBUser" : "caldav", # The username to use when DBType is empty
+ "SpawnedDBUser": "caldav", # The username to use when DBType is empty
- "DBImportFile" : "", # File path to SQL file to import at startup (includes schema)
+ "DBImportFile": "", # File path to SQL file to import at startup (includes schema)
- "DSN" : "", # Data Source Name. Used to connect to an external
+ "DSN": "", # Data Source Name. Used to connect to an external
# database if DBType is non-empty. Format varies
# depending on database type.
- "DBAMPFD" : 0, # Internally used by database to tell slave
+ "DBAMPFD": 0, # Internally used by database to tell slave
# processes to inherit a file descriptor and use it
# as an AMP connection over a UNIX socket; see
# twext.enterprise.adbapi2.ConnectionPoolConnection
- "SharedConnectionPool" : False, # Use a shared database connection pool in
+ "SharedConnectionPool": False, # Use a shared database connection pool in
# the master process, rather than having
# each client make its connections directly.
- "FailIfUpgradeNeeded" : True, # Set to True to prevent the server or utility
+ "FailIfUpgradeNeeded": True, # Set to True to prevent the server or utility
# tools from running if the database needs a schema
# upgrade.
- "StopAfterUpgradeTriggerFile" : "stop_after_upgrade", # if this file exists in ConfigRoot, stop
+ "StopAfterUpgradeTriggerFile": "stop_after_upgrade", # if this file exists in ConfigRoot, stop
# the service after finishing upgrade phase
- "UpgradeHomePrefix" : "", # When upgrading, only upgrade homes where the owner UID starts with
+ "UpgradeHomePrefix": "", # When upgrading, only upgrade homes where the owner UID starts with
# with the specified prefix. The upgrade will only be partial and only
# apply to upgrade pieces that affect entire homes. The upgrade will
# need to be run again without this prefix set to complete the overall
@@ -320,42 +322,42 @@
#
# Work queue configuration information
#
- "WorkQueue" : {
+ "WorkQueue": {
"ampPort": 7654, # Port used for hosts in a cluster to take to each other
},
#
# Types of service provided
#
- "EnableCalDAV" : True, # Enable CalDAV service
- "EnableCardDAV" : True, # Enable CardDAV service
+ "EnableCalDAV": True, # Enable CalDAV service
+ "EnableCardDAV": True, # Enable CardDAV service
#
# Data store
#
- "ServerRoot" : "/var/db/caldavd",
- "DataRoot" : "Data",
- "DatabaseRoot" : "Database",
- "AttachmentsRoot" : "Attachments",
- "DocumentRoot" : "Documents",
- "ConfigRoot" : "Config",
- "LogRoot" : "/var/log/caldavd",
- "RunRoot" : "/var/run/caldavd",
- "WebCalendarRoot" : "/Applications/Server.app/Contents/ServerRoot/usr/share/collabd/webcal/public",
+ "ServerRoot": "/var/db/caldavd",
+ "DataRoot": "Data",
+ "DatabaseRoot": "Database",
+ "AttachmentsRoot": "Attachments",
+ "DocumentRoot": "Documents",
+ "ConfigRoot": "Config",
+ "LogRoot": "/var/log/caldavd",
+ "RunRoot": "/var/run/caldavd",
+ "WebCalendarRoot": "/Applications/Server.app/Contents/ServerRoot/usr/share/collabd/webcal/public",
#
# Quotas
#
# Attachments
- "UserQuota" : 104857600, # User attachment quota (in bytes)
+ "UserQuota": 104857600, # User attachment quota (in bytes)
# Resource data
- "MaxCollectionsPerHome" : 50, # Maximum number of calendars/address books allowed in a home
- "MaxResourcesPerCollection" : 10000, # Maximum number of resources in a calendar/address book
- "MaxResourceSize" : 1048576, # Maximum resource size (in bytes)
- "MaxAttendeesPerInstance" : 100, # Maximum number of unique attendees
- "MaxAllowedInstances" : 3000, # Maximum number of instances the server will index
+ "MaxCollectionsPerHome": 50, # Maximum number of calendars/address books allowed in a home
+ "MaxResourcesPerCollection": 10000, # Maximum number of resources in a calendar/address book
+ "MaxResourceSize": 1048576, # Maximum resource size (in bytes)
+ "MaxAttendeesPerInstance": 100, # Maximum number of unique attendees
+ "MaxAllowedInstances": 3000, # Maximum number of instances the server will index
# Set to URL path of wiki authentication service, e.g. "/auth", in order
# to use javascript authentication dialog. Empty string indicates standard
@@ -823,6 +825,11 @@
}
},
+ "DirectoryProxy": {
+ "Enabled": False,
+ "SocketPath": "directory-proxy.sock"
+ },
+
#
# Support multiple hosts within a domain
#
@@ -900,7 +907,6 @@
# processes. If blank, then an AF_INET socket is used instead.
"ControlSocket": "caldavd.sock",
-
# Support for Content-Encoding compression options as specified in
# RFC2616 Section 3.5
# Defaults off, because it weakens TLS (CRIME attack).
@@ -1167,6 +1173,7 @@
("RunRoot", "PIDFile"),
("RunRoot", ("Stats", "UnixStatsSocket",)),
("RunRoot", "ControlSocket"),
+ ("RunRoot", ("DirectoryProxy", "SocketPath",)),
]
Added: CalendarServer/trunk/txdav/dps/__init__.py
===================================================================
--- CalendarServer/trunk/txdav/dps/__init__.py (rev 0)
+++ CalendarServer/trunk/txdav/dps/__init__.py 2014-01-30 21:20:16 UTC (rev 12483)
@@ -0,0 +1,19 @@
+##
+# Copyright (c) 2014 Apple 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.
+##
+
+"""
+Directory Proxy Service
+"""
Added: CalendarServer/trunk/txdav/dps/protocol.py
===================================================================
--- CalendarServer/trunk/txdav/dps/protocol.py (rev 0)
+++ CalendarServer/trunk/txdav/dps/protocol.py 2014-01-30 21:20:16 UTC (rev 12483)
@@ -0,0 +1,91 @@
+##
+# Copyright (c) 2014 Apple 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.
+##
+
+# import twext.who
+from twisted.protocols import amp
+from twisted.internet.defer import succeed
+from twext.python.log import Logger
+
+log = Logger()
+
+
+class DirectoryProxyAMPCommand(amp.Command):
+ """
+ A DirectoryProxy command
+ """
+ arguments = [('command', amp.String())]
+ response = [('result', amp.String())]
+
+
+
+class DirectoryProxyAMPProtocol(amp.AMP):
+ """
+ """
+
+ def __init__(self):
+ """
+ """
+ amp.AMP.__init__(self)
+
+
+ @DirectoryProxyAMPCommand.responder
+ # @inlineCallbacks
+ def testCommandReceived(self, command):
+ """
+ Process a command
+
+ @param command: DirectoryProxyAMPCommand
+ @returns: a deferred returning a dict
+ """
+ # command = readPlistFromString(command)
+ log.debug("Command arrived: {cmd}", cmd=command)
+ response = {"result": "plugh", "command": command}
+ log.debug("Responding with: {response}", response=response)
+ # returnValue(dict(result=result))
+ return succeed(response)
+
+
+#
+# A test AMP client
+#
+
+command = "xyzzy"
+
+
+def makeRequest():
+ from twisted.internet import reactor
+ from twisted.internet.protocol import ClientCreator
+
+ creator = ClientCreator(reactor, amp.AMP)
+ d = creator.connectUNIX("data/Logs/state/directory-proxy.sock")
+
+ def connected(ampProto):
+ return ampProto.callRemote(DirectoryProxyAMPCommand, command=command)
+ d.addCallback(connected)
+
+ def resulted(result):
+ return result['result']
+ d.addCallback(resulted)
+
+ def done(result):
+ print('Done: %s' % (result,))
+ reactor.stop()
+ d.addCallback(done)
+ reactor.run()
+
+if __name__ == '__main__':
+ makeRequest()
+
Added: CalendarServer/trunk/txdav/dps/service.py
===================================================================
--- CalendarServer/trunk/txdav/dps/service.py (rev 0)
+++ CalendarServer/trunk/txdav/dps/service.py 2014-01-30 21:20:16 UTC (rev 12483)
@@ -0,0 +1,154 @@
+##
+# Copyright (c) 2014 Apple 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.
+##
+
+import twext.who
+from twisted.python.usage import Options, UsageError
+from twisted.plugin import IPlugin
+from twisted.application import service
+from zope.interface import implements
+from twistedcaldav.config import config
+from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
+from twisted.application.strports import service as strPortsService
+from twisted.internet.protocol import Factory
+from twext.python.log import Logger
+
+from .protocol import DirectoryProxyAMPProtocol
+
+log = Logger()
+
+
+class DirectoryProxyAMPFactory(Factory):
+ """
+ """
+ protocol = DirectoryProxyAMPProtocol
+
+
+ def buildProtocol(self, addr):
+ return DirectoryProxyAMPProtocol()
+
+
+
+class DirectoryProxyOptions(Options):
+ optParameters = [[
+ "config", "f", DEFAULT_CONFIG_FILE, "Path to configuration file."
+ ]]
+
+
+ def __init__(self, *args, **kwargs):
+ super(DirectoryProxyOptions, self).__init__(*args, **kwargs)
+
+ 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,
+ and float options are supported, as well as comma seperated lists. Only
+ one option may be given for each --option flag, however multiple
+ --option flags may be specified.
+ """
+
+ if "=" in option:
+ path, value = option.split('=')
+ self._setOverride(
+ DEFAULT_CONFIG,
+ path.split('/'),
+ value,
+ self.overrides
+ )
+ else:
+ self.opt_option('%s=True' % (option,))
+
+ opt_o = opt_option
+
+ def postOptions(self):
+ config.load(self['config'])
+ config.updateDefaults(self.overrides)
+ self.parent['pidfile'] = None
+
+
+class DirectoryProxyServiceMaker(object):
+ implements(IPlugin, service.IServiceMaker)
+
+ tapname = "caldav_directoryproxy"
+ description = "Directory Proxy Service"
+ options = DirectoryProxyOptions
+
+ def makeService(self, options):
+ """
+ Return a service
+ """
+ try:
+ from setproctitle import setproctitle
+ except ImportError:
+ pass
+ else:
+ setproctitle("CalendarServer Directory Proxy Service")
+
+ desc = "unix:{path}:mode=660".format(
+ path=config.DirectoryProxy.SocketPath
+ )
+ return strPortsService(desc, DirectoryProxyAMPFactory())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/011261bb/attachment.html>
More information about the calendarserver-changes
mailing list