[Checkins] SVN: Zope/trunk/src/Zope2/Startup/zopectl.py merge changes from Zope 2.12 branch:

Chris Withers chris at simplistix.co.uk
Fri Oct 30 14:35:26 EDT 2009


Log message for revision 105396:
  merge changes from Zope 2.12 branch:
  - fix LP #461446: zopectl in interactive mode exited when the start/stop/etc commands were used
  - zopectl status now works on Windows
  - zopectl fg doesn't bomb if you hit Ctrl-C in Windows anymore.

Changed:
  U   Zope/trunk/src/Zope2/Startup/zopectl.py

-=-
Modified: Zope/trunk/src/Zope2/Startup/zopectl.py
===================================================================
--- Zope/trunk/src/Zope2/Startup/zopectl.py	2009-10-30 18:29:22 UTC (rev 105395)
+++ Zope/trunk/src/Zope2/Startup/zopectl.py	2009-10-30 18:35:26 UTC (rev 105396)
@@ -51,15 +51,16 @@
 WIN = False
 if sys.platform[:3].lower() == "win":
     WIN = True
+    import pywintypes
+    import win32service
     import win32serviceutil
     from nt_svcutils import service
     
     def do_windows(command):
         def inner(self,arg):
 
-            INSTANCE_HOME = self.options.directory
-            name = 'Zope'+str(hash(INSTANCE_HOME.lower()))
-            display_name = 'Zope instance at '+INSTANCE_HOME
+            name = self.get_service_name()
+            display_name = 'Zope instance at '+self.options.directory
 
             # This class exists only so we can take advantage of
             # win32serviceutil.HandleCommandLine, it is never
@@ -83,7 +84,8 @@
                 argv=argv,
                 )
 
-            return err,InstanceService
+            self.InstanceClass = InstanceService
+            return err
             
         return inner
 
@@ -220,16 +222,26 @@
     ## START OF WINDOWS ONLY STUFF
     
     if WIN:
+
+        def get_service_name(self):
+            return 'Zope'+str(hash(self.options.directory.lower()))
+            
         def get_status(self):
-            # get_status from zdaemon relies on *nix specific socket handling.
-            # We just don't support getting the status and sending actions to
-            # the control server on Windows. This could be extended to ask for
-            # the status of the Windows service though
-            self.zd_up = 0
-            self.zd_pid = 0
-            self.zd_status = None
-            return
+            sn = self.get_service_name()
+            try:
+                stat = win32serviceutil.QueryServiceStatus(sn)[1]
+                self.zd_up = 1
+            except pywintypes.error, err:
+                if err[0] == 1060:
+                    # Service not installed
+                    stat = win32service.SERVICE_STOPPED
+                    self.zd_up = 0
+                else:
+                    raise
 
+            self.zd_pid = (stat == win32service.SERVICE_RUNNING) and -1 or 0
+            self.zd_status = "args=%s" % self.options.program
+            
         do_start = do_windows('start')
         do_stop = do_windows('stop')
         do_restart = do_windows('restart')
@@ -237,7 +249,7 @@
         # Add extra commands to install and remove the Windows service
 
         def do_install(self,arg):
-            err,InstanceClass = do_windows('install')(self,arg)
+            err = do_windows('install')(self,arg)
             if not err:
                 # If we installed successfully, put info in registry for the
                 # real Service class to use:
@@ -247,12 +259,13 @@
                     os.path.join(os.path.split(sys.argv[0])[0],'runzope'),
                     self.options.configfile
                     )
-                InstanceClass.setReg('command',command)
+                self.InstanceClass.setReg('command',command)
                 
                 # This is unfortunately needed because runzope.exe is a setuptools
                 # generated .exe that spawns off a sub process, so pid would give us
                 # the wrong event name.
-                InstanceClass.setReg('pid_filename',self.options.configroot.pid_filename)
+                self.InstanceClass.setReg('pid_filename',self.options.configroot.pid_filename)
+            return err
 
         def help_install(self):
             print "install -- Installs Zope as a Windows service."
@@ -294,6 +307,8 @@
         command = quote_command(program)
         try:
             return os.system(command)
+        except KeyboardInterrupt:
+            pass
         finally:
             for addition in local_additions: program.remove(addition)
             



More information about the checkins mailing list