[CalendarServer-changes] [15757] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Jul 11 17:06:01 PDT 2016


Revision: 15757
          http://trac.calendarserver.org//changeset/15757
Author:   dre at apple.com
Date:     2016-07-11 17:06:01 -0700 (Mon, 11 Jul 2016)
Log Message:
-----------
Use SSH for Manhole by default; add Manhole.UseSSH boolean to configure this. Slight refactoring, and added some Multiservice names and pre-populated some context to make it easier to debug with manhole.

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/tap/caldav.py
    CalendarServer/trunk/conf/caldavd-stdconfig.plist
    CalendarServer/trunk/twistedcaldav/stdconfig.py
    CalendarServer/trunk/txdav/dps/server.py

Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py	2016-07-07 21:51:51 UTC (rev 15756)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py	2016-07-12 00:06:01 UTC (rev 15757)
@@ -245,6 +245,7 @@
         self.logRotateLength = logRotateLength
         self.logMaxFiles = logMaxFiles
         self.logRotateOnStart = logRotateOnStart
+        self.name = "elms"
 
 
     def setServiceParent(self, app):
@@ -280,7 +281,7 @@
     # The ConnectionService is a MultiService which bundles all the connection
     # services together for the purposes of being able to stop them and wait
     # for all of their connections to close before shutting down.
-    connectionServiceName = "ConnectionService"
+    connectionServiceName = "cs"
 
     def __init__(self, logObserver):
         self.logObserver = logObserver  # accesslog observer
@@ -292,6 +293,7 @@
             config.ErrorLogMaxRotatedFiles,
             config.ErrorLogRotateOnStart,
         )
+        self.name = "cds"
 
 
     def privilegedStartService(self):
@@ -862,6 +864,11 @@
                         frame=frame
                     )
 
+            if config.Manhole.Enabled:
+                namespace= dict({service.name: service})
+                for n, s in service.namedServices.iteritems():
+                    namespace[n] = s
+                self._makeManhole(namespace=namespace, parent=service)
             return service
 
 
@@ -898,6 +905,7 @@
         result = self.requestProcessingService(options, store, logObserver)
 
         if pool is not None:
+            pool.setName("db")
             pool.setServiceParent(result)
 
         if config.ControlSocket:
@@ -937,6 +945,7 @@
         controlClient = ControlSocketConnectingService(
             endpointFactory, controlSocketClient
         )
+        controlClient.setName("control")
         controlClient.setServiceParent(result)
 
         # Optionally set up push notifications
@@ -947,6 +956,7 @@
                 pushSubService = ApplePushNotifierService.makeService(
                     config.Notifications.Services.APNS, store)
                 observers.append(pushSubService)
+                pushSubService.setName("APNS")
                 pushSubService.setServiceParent(result)
             if config.Notifications.Services.AMP.Enabled:
                 pushSubService = AMPPushForwarder(controlSocketClient)
@@ -959,6 +969,7 @@
             mailRetriever = MailRetriever(
                 store, directory, config.Scheduling.iMIP.Receiving
             )
+            mailRetriever.setName("MailRetriever")
             mailRetriever.setServiceParent(result)
         else:
             mailRetriever = None
@@ -988,37 +999,6 @@
             txn._groupCacher = groupCacher
 
         store.callWithNewTransactions(decorateTransaction)
-
-        # Optionally enable Manhole access
-        if config.Manhole.Enabled:
-            try:
-                from twisted.conch.manhole_tap import (
-                    makeService as manholeMakeService
-                )
-                portString = "tcp:{:d}:interface=127.0.0.1".format(
-                    config.Manhole.StartingPortNumber + int(config.LogID) + 1
-                )
-                manholeService = manholeMakeService({
-                    "sshPort": None,
-                    "telnetPort": portString,
-                    "namespace": {
-                        "config": config,
-                        "service": result,
-                        "store": store,
-                        "directory": directory,
-                    },
-                    "passwd": config.Manhole.PasswordFilePath,
-                })
-                manholeService.setServiceParent(result)
-                # Using print(because logging isn't ready at this point)
-                print("Manhole access enabled:", portString)
-
-            except ImportError:
-                print(
-                    "Manhole access could not enabled because "
-                    "manhole_tap could not be imported"
-                )
-
         return result
 
 
@@ -1181,10 +1161,12 @@
                     # 'SSL' tag on it, since that's the only time it's used.
                     contextFactory = None
 
-            ReportingHTTPService(
+            reportingService = ReportingHTTPService(
                 requestFactory, int(config.MetaFD), contextFactory,
-                usingSocketFile=config.SocketFiles.Enabled
-            ).setServiceParent(connectionService)
+                usingSocketFile=config.SocketFiles.Enabled,
+            )
+            reportingService.setName("http-{}".format(int(config.MetaFD)))
+            reportingService.setServiceParent(connectionService)
 
         else:  # Not inheriting, therefore we open our own:
             for bindAddress in self._allBindAddresses():
@@ -1211,6 +1193,8 @@
                                 backlog=config.ListenBacklog,
                                 inherit=False
                             )
+                            httpsService.setName(
+                                "https-{}:{}".format(bindAddress,int(port)))
                             httpsService.setServiceParent(connectionService)
 
                 for port in config.BindHTTPPorts:
@@ -1311,6 +1295,59 @@
                     Popen(memcachedArgv)
 
 
+    def _makeManhole(self, namespace=None, parent=None):
+        try:
+            import inspect
+            import objgraph
+        except ImportError:
+            pass
+        try:
+            if 'inspect' in locals():
+                namespace['ins'] = inspect
+            if 'objgraph' in locals():
+                namespace['og'] = objgraph
+            from pprint import pprint
+            namespace.update({
+                'pp': pprint,
+                'cfg': config,
+            })
+            from twisted.conch.manhole_tap import (
+                makeService as manholeMakeService
+            )
+            portOffset = 0 if config.LogID == '' else int(config.LogID) + 1
+            portString = "tcp:{:d}:interface=127.0.0.1".format(
+                config.Manhole.StartingPortNumber + portOffset
+            )
+            manholeService = manholeMakeService({
+                "passwd": config.Manhole.PasswordFilePath,
+                "telnetPort":
+                    portString if config.Manhole.UseSSH is False else None,
+                "sshPort":
+                    portString if config.Manhole.UseSSH is True else None,
+                "sshKeyDir": config.DataRoot,
+                "sshKeyName": config.Manhole.sshKeyName,
+                "sshKeySize": config.Manhole.sshKeySize,
+                "namespace": namespace,
+            })
+            manholeService.setName("manhole")
+            if parent is not None:
+                manholeService.setServiceParent(parent)
+            # Using print(because logging isn't ready at this point)
+            print("Manhole access enabled:", portString)
+        except ImportError:
+            print(
+                "Manhole access could not enabled because "
+                "manhole_tap could not be imported."
+            )
+            import platform
+            if platform.system() == "Darwin":
+                if config.Manhole.UseSSH:
+                    print(
+                        "Set Manhole.UseSSH to false or rebuild CS with the "
+                        "USE_OPENSSL environment variable set."
+                    )
+            
+
     def makeService_Single(self, options):
         """
         Create a service to be used in a single-process, stand-alone
@@ -1332,6 +1369,7 @@
                         config.Notifications.Services.APNS, store
                     )
                     observers.append(pushSubService)
+                    pushSubService.setName("APNS")
                     pushSubService.setServiceParent(result)
                 if config.Notifications.Services.AMP.Enabled:
                     pushSubService = AMPPushMaster(
@@ -1362,6 +1400,7 @@
                 mailRetriever = MailRetriever(
                     store, directory, config.Scheduling.iMIP.Receiving
                 )
+                mailRetriever.setName("mailRetriever")
                 mailRetriever.setServiceParent(result)
             else:
                 mailRetriever = None
@@ -1401,35 +1440,6 @@
             else:
                 groupCacher = None
 
-            # Optionally enable Manhole access
-            if config.Manhole.Enabled:
-                try:
-                    from twisted.conch.manhole_tap import (
-                        makeService as manholeMakeService
-                    )
-                    portString = "tcp:{:d}:interface=127.0.0.1".format(
-                        config.Manhole.StartingPortNumber
-                    )
-                    manholeService = manholeMakeService({
-                        "sshPort": None,
-                        "telnetPort": portString,
-                        "namespace": {
-                            "config": config,
-                            "service": result,
-                            "store": store,
-                            "directory": directory,
-                        },
-                        "passwd": config.Manhole.PasswordFilePath,
-                    })
-                    manholeService.setServiceParent(result)
-                    # Using print(because logging isn't ready at this point)
-                    print("Manhole access enabled:", portString)
-                except ImportError:
-                    print(
-                        "Manhole access could not enabled because "
-                        "manhole_tap could not be imported"
-                    )
-
             def decorateTransaction(txn):
                 txn._pushDistributor = pushDistributor
                 txn._rootResource = result.rootResource
@@ -1526,6 +1536,7 @@
             config.ErrorLogMaxRotatedFiles,
             config.ErrorLogRotateOnStart,
         )
+        svc.setName("agent")
         svc.setServiceParent(agentLoggingService)
         return agentLoggingService
 
@@ -1582,6 +1593,7 @@
                     dbtype=DatabaseType(dialect, paramstyle, dbfeatures),
                     maxConnections=config.MaxDBConnectionsPerPool
                 )
+                cp.setName("db")
                 cp.setServiceParent(ms)
                 store = storeFromConfigWithoutDPS(config, cp.connection)
 
@@ -1655,6 +1667,7 @@
                     UpgradeReleaseLockStep(store)
                 )
 
+                pps.setName("pre")
                 pps.setServiceParent(ms)
                 return ms
 
@@ -1784,6 +1797,7 @@
 
         monitor = DelayedStartupProcessMonitor()
         s.processMonitor = monitor
+        monitor.setName("pm")
         monitor.setServiceParent(s)
 
         if config.MemoryLimiter.Enabled:
@@ -1791,6 +1805,7 @@
                 monitor, config.MemoryLimiter.Seconds,
                 config.MemoryLimiter.Bytes, config.MemoryLimiter.ResidentOnly
             )
+            memoryLimiter.setName("ml")
             memoryLimiter.setServiceParent(s)
 
         # Maybe spawn memcached through a ProcessMonitor
@@ -1877,32 +1892,6 @@
             statsService.setName("tcp-stats")
             statsService.setServiceParent(s)
 
-        # Optionally enable Manhole access
-        if config.Manhole.Enabled:
-            try:
-                from twisted.conch.manhole_tap import (
-                    makeService as manholeMakeService
-                )
-                portString = "tcp:{:d}:interface=127.0.0.1".format(
-                    config.Manhole.StartingPortNumber
-                )
-                manholeService = manholeMakeService({
-                    "sshPort": None,
-                    "telnetPort": portString,
-                    "namespace": {
-                        "config": config,
-                        "service": s,
-                    },
-                    "passwd": config.Manhole.PasswordFilePath,
-                })
-                manholeService.setServiceParent(s)
-                # Using print(because logging isn't ready at this point)
-                print("Manhole access enabled:", portString)
-            except ImportError:
-                print(
-                    "Manhole access could not enabled because "
-                    "manhole_tap could not be imported"
-                )
 
 
         # Finally, let's get the real show on the road.  Create a service that
@@ -1944,11 +1933,13 @@
             else:
                 dispenser = None
             multi = MultiService()
+            multi.setName("multi")
             pool.setServiceParent(multi)
             spawner = SlaveSpawnerService(
                 self, monitor, dispenser, dispatcher, stats, options["config"],
                 inheritFDs=inheritFDs, inheritSSLFDs=inheritSSLFDs
             )
+            spawner.setName("spawner")
             spawner.setServiceParent(multi)
             if config.UseMetaFD:
                 cl.setServiceParent(multi)
@@ -1961,6 +1952,7 @@
                 mailRetriever = MailRetriever(
                     store, directory, config.Scheduling.iMIP.Receiving
                 )
+                mailRetriever.setName("MailRetriever")
                 mailRetriever.setServiceParent(multi)
             else:
                 mailRetriever = None
@@ -1993,6 +1985,7 @@
         ssvc = self.storageService(
             spawnerSvcCreator, None, uid, gid
         )
+        ssvc.setName("ssvc")
         ssvc.setServiceParent(s)
         return s
 

Modified: CalendarServer/trunk/conf/caldavd-stdconfig.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-stdconfig.plist	2016-07-07 21:51:51 UTC (rev 15756)
+++ CalendarServer/trunk/conf/caldavd-stdconfig.plist	2016-07-12 00:06:01 UTC (rev 15757)
@@ -2116,14 +2116,28 @@
 		<key>Enabled</key>
 		<false/>
 
+		<!-- Set to False for telnet -->
+		<key>UseSSH</key>
+		<true/>
+
+		<!-- Master listens here, children increment -->
 		<key>StartingPortNumber</key>
 		<integer>5000</integer>
 
+		<!-- Directory Proxy listens here -->
 		<key>DPSPortNumber</key>
 		<integer>4999</integer>
 
+		<!-- Path to password file with lines of user:pass -->
 		<key>PasswordFilePath</key>
 		<string></string>
+
+		<!-- Relative to DataRoot -->
+		<key>sshKeyName</key>
+		<string>manhole.key</string>
+
+		<key>sshKeySize</key>
+		<integer>4096</integer>
 	</dict>
 
 	<key>EnableKeepAlive</key>

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2016-07-07 21:51:51 UTC (rev 15756)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2016-07-12 00:06:01 UTC (rev 15757)
@@ -1103,9 +1103,12 @@
 
     "Manhole": {
         "Enabled": False,
-        "StartingPortNumber": 5000,
-        "DPSPortNumber": 4999,
-        "PasswordFilePath": "",
+        "UseSSH": True, # Set to False for telnet
+        "StartingPortNumber": 5000, # Master listens here, children increment
+        "DPSPortNumber": 4999, # Directory Proxy listens here
+        "PasswordFilePath": "", # Path to password file with lines of user:pass
+        "sshKeyName": "manhole.key", # Relative to DataRoot
+        "sshKeySize": 4096,
     },
 
     "EnableKeepAlive": False,

Modified: CalendarServer/trunk/txdav/dps/server.py
===================================================================
--- CalendarServer/trunk/txdav/dps/server.py	2016-07-07 21:51:51 UTC (rev 15756)
+++ CalendarServer/trunk/txdav/dps/server.py	2016-07-12 00:06:01 UTC (rev 15757)
@@ -868,8 +868,12 @@
                     config.Manhole.DPSPortNumber
                 )
                 manholeService = manholeMakeService({
-                    "sshPort": None,
-                    "telnetPort": portString,
+                    "sshPort": portString if config.Manhole.UseSSH is True else None,
+                    "telnetPort": portString if config.Manhole.UseSSH is False else None,
+                    "sshKeyDir": config.DataRoot,
+                    "sshKeyName": "manhole.key",
+                    "sshKeySize": 4096,
+                    "passwd": config.Manhole.PasswordFilePath,
                     "namespace": {
                         "config": config,
                         "service": dpsService,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20160711/fceda694/attachment-0001.html>


More information about the calendarserver-changes mailing list