Commit 4b3678be authored by Chris Withers's avatar Chris Withers

- Fix #443005 by using the pid from the pidfile rather than that of runzope.exe

- correct capitalisation of "command" reg value name, not that it matters ;-)
- add a windebug command to help when debugging windows service behaviour
- refactor do_start: nt_svcutils.service.Service sets ZMANAGED, so its not needed on Windows.
parent 1b154700
...@@ -212,6 +212,11 @@ class ZopeCmd(ZDCmd): ...@@ -212,6 +212,11 @@ class ZopeCmd(ZDCmd):
args = [opt, svalue] args = [opt, svalue]
return args return args
def do_start(self, arg):
# signal to Zope that it is being managed
# (to indicate it's web-restartable)
os.putenv('ZMANAGED', '1')
## START OF WINDOWS ONLY STUFF ## START OF WINDOWS ONLY STUFF
if WIN: if WIN:
...@@ -225,6 +230,7 @@ class ZopeCmd(ZDCmd): ...@@ -225,6 +230,7 @@ class ZopeCmd(ZDCmd):
self.zd_status = None self.zd_status = None
return return
do_start = do_windows('start')
do_stop = do_windows('stop') do_stop = do_windows('stop')
do_restart = do_windows('restart') do_restart = do_windows('restart')
...@@ -243,6 +249,11 @@ class ZopeCmd(ZDCmd): ...@@ -243,6 +249,11 @@ class ZopeCmd(ZDCmd):
) )
InstanceClass.setReg('command',command) 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)
def help_install(self): def help_install(self):
print "install -- Installs Zope as a Windows service." print "install -- Installs Zope as a Windows service."
...@@ -251,16 +262,12 @@ class ZopeCmd(ZDCmd): ...@@ -251,16 +262,12 @@ class ZopeCmd(ZDCmd):
def help_remove(self): def help_remove(self):
print "remove -- Removes the Zope Windows service." print "remove -- Removes the Zope Windows service."
## END OF WINDOWS ONLY STUFF do_windebug = do_windows('debug')
def do_start(self, arg): def help_windebug(self):
# signal to Zope that it is being managed print "windebug -- Runs the Zope Windows service in the foreground, in debug mode."
# (to indicate it's web-restartable)
os.putenv('ZMANAGED', '1') ## END OF WINDOWS ONLY STUFF
if WIN:
do_windows('start')(self,arg)
else:
ZDCmd.do_start(self, arg)
def get_startup_cmd(self, python, more): def get_startup_cmd(self, python, more):
cmdline = ( '%s -c "from Zope2 import configure;' cmdline = ( '%s -c "from Zope2 import configure;'
......
...@@ -60,7 +60,7 @@ class Service(win32serviceutil.ServiceFramework): ...@@ -60,7 +60,7 @@ class Service(win32serviceutil.ServiceFramework):
# ...and from that, we can look up the other needed bits # ...and from that, we can look up the other needed bits
# from the registry: # from the registry:
self._svc_display_name_ = self.getReg('DisplayName') self._svc_display_name_ = self.getReg('DisplayName')
self._svc_command_ = self.getReg('Command',keyname='PythonClass') self._svc_command_ = self.getReg('command',keyname='PythonClass')
win32serviceutil.ServiceFramework.__init__(self, args) win32serviceutil.ServiceFramework.__init__(self, args)
...@@ -268,26 +268,29 @@ class Service(win32serviceutil.ServiceFramework): ...@@ -268,26 +268,29 @@ class Service(win32serviceutil.ServiceFramework):
def stop(self,pid): def stop(self,pid):
# call the method that any subclasses out there may implement: # call the method that any subclasses out there may implement:
self.onStop() self.onStop()
# Stop the child process by sending signals to the special named event.
winver = sys.getwindowsversion() winver = sys.getwindowsversion()
# 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.
child_pid = int(
open(self.getReg('pid_filename',keyname='PythonClass')).read()
)
# Stop the child process by sending signals to the special named event.
for sig, timeout in ( for sig, timeout in (
(signal.SIGINT, 30), # We give it 90 seconds to shutdown normally. (signal.SIGINT, 30), # We give it 90 seconds to shutdown normally.
(signal.SIGTERM, 10) # If that doesn't stop things, we give it 30 (signal.SIGTERM, 10) # If that doesn't stop things, we give it 30
# seconds to do a "fast" shutdown. # seconds to do a "fast" shutdown.
): ):
event_name = "Zope-%d-%d" % (pid, sig) # See the Signals.WinSignalHandler module for
# the source of this event name
event_name = "Zope-%d-%d" % (child_pid,sig)
# sys.getwindowsversion() -> major, minor, build, platform_id, ver_string # sys.getwindowsversion() -> major, minor, build, platform_id, ver_string
# for platform_id, 2==VER_PLATFORM_WIN32_NT # for platform_id, 2==VER_PLATFORM_WIN32_NT
if winver[0] >= 5 and winver[3] == 2: if winver[0] >= 5 and winver[3] == 2:
event_name = "Global\\" + event_name event_name = "Global\\" + event_name
try: try:
# XXX This no longer works, see bug #443005 on Launchpad
# This is likely because cmd in now a setuptools-generated .exe
# Any ideas?
he = win32event.OpenEvent(win32event.EVENT_MODIFY_STATE, 0, he = win32event.OpenEvent(win32event.EVENT_MODIFY_STATE, 0,
event_name) event_name)
except win32event.error, details: except win32event.error, details:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment