#############################################################################
#
# $Id: NS_NtService.py,v 1.4.4.2 2008/05/17 09:56:01 irmen Exp $
# An NT service that runs the Pyro Name Server
# Author: Syver Enstad syver-en@online.no
#
# This is part of "Pyro" - Python Remote Objects
# Which is (c) Irmen de Jong - irmen@users.sourceforge.net
#
#############################################################################
import win32serviceutil
import threading
import win32service
import win32api
from BasicNTService import BasicNTService,getRegistryParameters
def setConfig():
Pyro.config.PYRO_TRACELEVEL=3
Pyro.config.PYRO_STORAGE = os.path.splitdrive(win32api.GetSystemDirectory())[0]+os.sep
Pyro.config.PYRO_LOGFILE = "Pyro_NS_svc.log"
Pyro.config.PYRO_NS_URIFILE = os.path.join(Pyro.config.PYRO_STORAGE, "Pyro_NS_URI.txt")
import os,sys
import Pyro.util
setConfig()
Log=Pyro.util.Log
import Pyro.core
import Pyro.constants
import Pyro.naming
from Pyro.naming import NameServer,PersistentNameServer,BroadcastServer,bcRequestHandler
BcServerObject = None
def startServer(hstn='', nsport=0, bcport=0, keep=0, persistent=0, dbdir=None, Guards=(None,None)):
global BcServerObject
if not nsport:
nsport=Pyro.config.PYRO_NS_PORT
if not bcport:
bcport=Pyro.config.PYRO_NS_BC_PORT
Pyro.core.initServer()
PyroDaemon = Pyro.core.Daemon(host=hstn, port=nsport,norange=1)
if Guards[0]:
PyroDaemon.setNewConnectionValidator(Guards[0])
if persistent:
ns=PersistentNameServer(dbdir)
PyroDaemon.useNameServer(ns)
NS_URI=PyroDaemon.connectPersistent(ns,Pyro.constants.NAMESERVER_NAME)
else:
ns=NameServer()
PyroDaemon.useNameServer(ns)
NS_URI=PyroDaemon.connect(ns,Pyro.constants.NAMESERVER_NAME)
BcServerObject = BroadcastServer((hstn or '',bcport),bcRequestHandler)
if Guards[1]:
BcServerObject.setRequestValidator(Guards[1])
BcServerObject.keepRunning(keep)
if keep:
Log.msg("NS", 'Will ignore shutdown requests.')
ns.ignoreShutdown=True
else:
Log.msg("NS", 'Will accept shutdown requests.')
ns.ignoreShutdown=False
if Guards[0] or Guards[1]:
print 'Using security plugins:'
if Guards[0]:
print ' NS new conn validator =',Guards[0].__class__.__name__,'from', Guards[0].__class__.__module__
else: print ' default NS new conn validator'
if Guards[1]:
print ' BC request validator =',Guards[1].__class__.__name__,'from', Guards[1].__class__.__module__
else: print ' default BC request validator'
ns.publishURI(NS_URI)
BcServerObject.setNS_URI(NS_URI)
Log.msg('NS daemon','This is the Pyro Name Server.')
if persistent:
Log.msg('NS daemon','Persistent mode, database is in',ns.getDBDir())
print 'Persistent mode, database is in',ns.getDBDir()
Log.msg('NS daemon','Starting on',PyroDaemon.hostname,'port', PyroDaemon.port, ' broadcast server on port',bcport)
# I use a timeout here otherwise you can't break gracefully on Windoze
while not BcServerObject.shutdown:
try:
PyroDaemon.handleRequests(BcServerObject.preferredTimeOut,[BcServerObject],BcServerObject.bcCallback)
except KeyboardInterrupt:
Log.warn('NS daemon','shutdown on user break signal')
BcServerObject.shutdown=1
except:
import traceback
(exc_type, exc_value, exc_trb) = sys.exc_info()
out = ''.join(traceback.format_exception(exc_type, exc_value, exc_trb)[-5:])
Log.error('NS daemon', 'Unexpected exception, type',exc_type,
'\n--- partial traceback of this exception follows:\n',
out,'\n--- end of traceback')
Log.msg('NS daemon','Shut down gracefully.')
class PyroNSThread(threading.Thread):
""" The Pyro Naming Service will run in this thread
"""
def __init__(self, args, stopcallback):
threading.Thread.__init__(self)
Log.msg("PyroNSsvc", "initializing")
self._args = list(args)
Log.msg("PyroNSsvc", "args are:",self._args)
self._stopcallback = stopcallback
def run(self):
self.startPyroNS()
self._stopcallback()
def startPyroNS(self):
try:
""" ripped out of Pyro.naming and slightly changed to
accomodate not using sys.argv, but self._args instead
"""
Args = Pyro.util.ArgParser()
Args.parse(self._args,'hkn:p:b:d:s:')
try:
Args.getOpt('h')
Log.error("PyroNS_svc","""
Usage: ns [-h] [-n hostname] [-p port] [-b port]
[-d [databasefile]] [-s securitymodule]
where -p = NS server port
-b = NS broadcast port
-n = non-default server hostname
-d = use persistent database, provide optional storage directory
-s = use given python module with security code
-h = print this help
""")
raise SystemExit
except KeyError:
pass
host = Args.getOpt('n','')
port = int(Args.getOpt('p',Pyro.config.PYRO_NS_PORT))
bcport = int(Args.getOpt('b',Pyro.config.PYRO_NS_BC_PORT))
try:
dbdir = Args.getOpt('d')
persistent = 1
except KeyError:
persistent = 0
dbdir = None
# we're running as a service, always ignore remote shutdown requests
keep=1
try:
secmod = __import__(Args.getOpt('s'),locals(),globals())
Guards = (secmod.NSGuard(), secmod.BCGuard())
except ImportError,x:
Log.msg("NS", 'Error loading security module:',x)
raise SystemExit
except KeyError:
secmod = None
Guards = (None,None)
if Args.ignored:
Log.warn("PyroNS_svc",'Ignored options:',Args.ignored)
if Args.args:
Log.warn("PyroNS_svc",'Ignored arguments:',Args.args)
Log.msg("PyroNS_svc","Starting the Name Server.")
startServer(host,port,bcport,keep,persistent,dbdir,Guards)
except Exception,x :
Log.error("NS daemon","COULD NOT START!!!",x)
raise SystemExit
class PyroNS_NTService(BasicNTService):
_svc_name_ = 'PyroNS'
_svc_display_name_ = "Pyro Naming Service"
_svc_description_ = 'Provides name resolution services for Pyro objects'
def __init__(self, args):
super(PyroNS_NTService, self).__init__(args)
setConfig()
try:
args = getRegistryParameters(self._svc_name_).split()
except Exception,x:
Log.error("PyroNS_svc","PROBLEM GETTING ARGS FROM REGISTRY:",x)
self._nsThread = PyroNSThread(args, self.SvcStop)
def _doRun(self):
""" Overriden """
self._nsThread.start()
def _doStop(self):
""" Overridden """
global BcServerObject
BcServerObject.shutdown = 1
self._nsThread.join()
def SvcStop(self):
"""Overriden """
super(PyroNS_NTService, self).SvcStop()
if __name__ == '__main__':
PyroNS_NTService.HandleCommandLine()
|