[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