def SvcDoRun(self): # Start the service: self._server = log = None try: try: # Figure out the work directory and make it the current directory: workDir = self._workDir if not workDir: workDir = os.path.dirname(__file__) os.chdir(workDir) workDir = os.curdir # Switch the output to the logFile specified above: stdout, stderr = sys.stdout, sys.stderr logFile = self._logFile if logFile: # logFile has been specified if os.path.exists(logFile): log = open(logFile, "a", 1) # append line buffered log.write("\n" + "-" * 68 + "\n\n") else: log = open(logFile, "w", 1) # write line buffered else: # no logFile # Make all output go nowhere. Otherwise, print statements # cause the service to crash, believe it or not. log = open("nul", "w") # os.devnull on Windows sys.stdout = sys.stderr = log # By default, Webware is searched in the parent directory: webwareDir = self._webwareDir if not webwareDir: webwareDir = os.pardir # Remove the package component in the name of this module, # because otherwise the package path would be used for imports: global __name__ __name__ = __name__.split(".")[-1] # Check the validity of the Webware directory: sysPath = sys.path # memorize the standard Python search path sys.path = [webwareDir] # now include only the Webware directory # Check whether Webware is really located here from Properties import name as webwareName from WebKit.Properties import name as webKitName if webwareName != "Webware for Python" or webKitName != "WebKit": raise ImportError # Now assemble a new clean Python search path: path = [] # the new search path will be collected here webKitDir = os.path.abspath(os.path.join(webwareDir, "WebKit")) for p in [workDir, webwareDir] + self._libraryDirs + sysPath: if not p: continue # do not include empty ("current") directory p = os.path.abspath(p) if p == webKitDir or p in path or not os.path.exists(p): continue # do not include WebKit and duplicates path.append(p) sys.path = path # set the new search path # Import the Profiler: from WebKit import Profiler Profiler.startTime = time.time() # Import the AppServer: appServer = self._appServer appServerModule = __import__("WebKit." + appServer, None, None, appServer) if self._runProfile: print "Profiling is on.", "See docstring in Profiler.py for more info." print self._server = getattr(appServerModule, appServer)(workDir) print sys.stdout.flush() if self._runProfile: from profile import Profile profiler = Profile() Profiler.profiler = profiler sys.stdout.flush() Profiler.runCall(self._server.mainloop) else: self._server.mainloop() print sys.stdout.flush() if self._server._running: self._server.initiateShutdown() self._server._closeThread.join() if self._runProfile: print print "Writing profile stats to %s..." % Profiler.statsFilename Profiler.dumpStats() print "WARNING: Applications run much slower when profiled," print "so turn off profiling the service when you are done." except SystemExit, e: if log and logFile: print errorlevel = e[0] if errorlevel == 3: print "Please switch off AutoReloading in AppServer.Config." print "It does currently not work with AppServerSercive." print "You have to reload the service manually." else: print "The AppServer has been signaled to terminate." print except Exception, e: if log and logFile: print try: import traceback traceback.print_exc(file=sys.stderr) print "Service stopped due to above exception." except Exception: print "ERROR:", e print "Cannot print traceback." print raise
def SvcDoRun(self): # Start the service: self._server = log = None try: try: # Figure out the work directory and make it the current directory: workDir = self._workDir if not workDir: workDir = os.path.dirname(__file__) os.chdir(workDir) workDir = os.curdir # Switch the output to the logFile specified above: stdout, stderr = sys.stdout, sys.stderr logFile = self._logFile if logFile: # logFile has been specified if os.path.exists(logFile): log = open(logFile, 'a', 1) # append line buffered log.write('\n' + '-' * 68 + '\n\n') else: log = open(logFile, 'w', 1) # write line buffered else: # no logFile # Make all output go nowhere. Otherwise, print statements # cause the service to crash, believe it or not. log = open('nul', 'w') # os.devnull on Windows sys.stdout = sys.stderr = log # By default, Webware is searched in the parent directory: webwareDir = self._webwareDir if not webwareDir: webwareDir = os.pardir # Remove the package component in the name of this module, # because otherwise the package path will be used for imports: global __name__, __package__ __name__ = __name__.rsplit('.', 1)[-1] __package__ = None # Check the validity of the Webware directory: sysPath = sys.path # memorize the standard Python search path sys.path = [webwareDir] # include only the Webware directory # Check whether Webware is really located here from Properties import name as webwareName from WebKit.Properties import name as webKitName if webwareName != 'Webware for Python' or webKitName != 'WebKit': raise ImportError # Now assemble a new clean Python search path: path = [] # the new search path will be collected here webKitDir = os.path.abspath(os.path.join(webwareDir, 'WebKit')) for p in [workDir, webwareDir] + self._libraryDirs + sysPath: if not p: continue # do not include empty ("current") directory p = os.path.abspath(p) if p == webKitDir or p in path or not os.path.exists(p): continue # do not include WebKit and duplicates path.append(p) sys.path = path # set the new search path # Import the Profiler: from WebKit import Profiler Profiler.startTime = time.time() # Import the AppServer: appServer = self._appServer appServerModule = __import__('WebKit.' + appServer, None, None, appServer) if self._runProfile: print( 'Profiling is on. ' 'See docstring in Profiler.py for more info.') print self._server = getattr(appServerModule, appServer)(workDir) sys.stdout = sys.stderr = log # in case this has been reset print sys.stdout.flush() if self._runProfile: try: from cProfile import Profile except ImportError: from profile import Profile profiler = Profile() Profiler.profiler = profiler sys.stdout.flush() Profiler.runCall(self._server.mainloop) else: self._server.mainloop() sys.stdout = sys.stderr = log # in case this has been reset print sys.stdout.flush() if self._server._running: self._server.initiateShutdown() self._server._closeThread.join() if self._runProfile: print print 'Writing profile stats to %s...' % Profiler.statsFilename Profiler.dumpStats() print 'WARNING: Applications run much slower when profiled,' print 'so turn off profiling the service when you are done.' except SystemExit as e: if log and logFile: print errorlevel = e[0] if errorlevel == 3: print 'Please switch off AutoReloading in AppServer.Config.' print 'It does currently not work with AppServerSercive.' print 'You have to reload the service manually.' else: print 'The AppServer has been signaled to terminate.' print except Exception as e: if log and logFile: print try: import traceback traceback.print_exc(file=sys.stderr) print 'Service stopped due to above exception.' except Exception: print 'ERROR:', e print 'Cannot print traceback.' print raise except: raise finally: if self._server and self._server._running: self._server.initiateShutdown() self._server._closeThread.join() self._server = None if log: sys.stdout, sys.stderr = stdout, stderr log.close()
from WebKit import Profiler if Profiler.startTime is None: from time import time Profiler.startTime = time() # Now start the app server: if runProfile: print ('Profiling is on. ' 'See docstring in Profiler.py for more info.') print try: from cProfile import Profile except ImportError: from profile import Profile profiler = Profile() Profiler.profiler = profiler errorlevel = Profiler.runCall(launchWebKit, *args) print print 'Writing profile stats to %s...' % Profiler.statsFilename Profiler.dumpStats() print 'WARNING: Applications run much slower when profiled,' print 'so turn off profiling in Launch.py when you are finished.' else: errorlevel = launchWebKit(*args) finally: print # Close the log file properly: if log: sys.stdout, sys.stderr = stdout, stderr log.close() # Restore server process group and user. # Note that because we changed the real group and
def main(args=None): """Evaluate the command line arguments and call launchWebKit.""" global workDir, webwareDir, libraryDirs, runProfile, \ logFile, pidFile, user, group, appServer if args is None: args = sys.argv[1:] # Accept AppServer even if placed before StartOptions: if args and not args[0].startswith('-'): arg2 = args.pop(0) else: arg2 = None # Accept AppServerOptions that look like StartOptions: args1 = [] args2 = [] while args: arg = args.pop(0) if (arg.startswith('--') and 2 < arg.find('.', 2) < arg.find('=', 5)): args2.append(arg) else: args1.append(arg) # Get all launch options: from getopt import getopt, GetoptError try: opts, args1 = getopt(args1, 'd:w:l:po:i:u:g:', [ 'work-dir=', 'webware-dir=', 'library=', 'run-profile', 'log-file=', 'pid-file=', 'user='******'group=']) except GetoptError as error: print str(error) print usage() for opt, arg in opts: if opt in ('-d', '--work-dir'): workDir = arg elif opt in ('-w', '--webware-dir'): webwareDir = arg elif opt in ('-l', '--library'): libraryDirs.append(arg) elif opt in ('-p', '--run-profile'): runProfile = True elif opt in ('-o', '--log-file'): logFile = arg elif opt in ('-i', '--pid-file'): pidFile = arg elif opt in ('-u', '--user'): user = arg elif opt in ('-g', '--group'): group = arg if arg2: appServer = arg2 elif args1 and not args1[0].startswith('-') and '=' not in args1[0]: appServer = args1.pop(0) args = args2 + args1 # Figure out the group id: gid = group if gid is not None: try: gid = int(gid) except ValueError: try: import grp entry = grp.getgrnam(gid) except KeyError: print 'Error: Group %r does not exist.' % gid sys.exit(2) except ImportError: print 'Error: Group names are not supported.' sys.exit(2) gid = entry[2] # Figure out the user id: uid = user if uid is not None: try: uid = int(uid) except ValueError: try: import pwd entry = pwd.getpwnam(uid) except KeyError: print 'Error: User %r does not exist.' % uid sys.exit(2) except ImportError: print 'Error: User names are not supported.' sys.exit(2) if not gid: gid = entry[3] uid = entry[2] # Figure out the work directory and make it the current directory: if workDir: workDir = os.path.expanduser(workDir) else: scriptName = sys.argv and sys.argv[0] if not scriptName or scriptName == '-c': scriptName = 'Launch.py' workDir = os.path.dirname(os.path.abspath(scriptName)) try: os.chdir(workDir) except OSError as error: print 'Error: Could not set working directory.' print 'The path %r cannot be used.' % workDir print error.strerror print 'Check the --work-dir option.' sys.exit(1) workDir = os.curdir # Expand user components in directories: if webwareDir: webwareDir = os.path.expanduser(webwareDir) else: webwareDir = os.pardir if libraryDirs: libraryDirs = map(os.path.expanduser, libraryDirs) # If this module is inside a package, make it a standalone module, # because otherwise the package path will be used for imports, too: global __name__, __package__ name = __name__.rsplit('.', 1)[-1] if name != __name__: sys.modules[name] = sys.modules[__name__] del sys.modules[__name__] __name__ = name __package__ = None # Check the validity of the Webware directory: sysPath = sys.path # memorize the standard Python search path sys.path = [webwareDir] # now include only the Webware directory try: # check whether Webware is really located here from Properties import name as webwareName from WebKit.Properties import name as webKitName except ImportError: webwareName = None if webwareName != 'Webware for Python' or webKitName != 'WebKit': print 'Error: Cannot find the Webware directory.' print 'The path %r seems to be wrong.' % webwareDir print 'Check the --webware-dir option.' sys.exit(1) if not os.path.exists(os.path.join(webwareDir, 'install.log')): print 'Error: Webware has not been installed.' print 'Please run install.py in the Webware directory:' print '> cd', os.path.abspath(webwareDir) print '> python install.py' sys.exit(1) # Now assemble a new clean Python search path: path = [] # the new search path will be collected here webKitDir = os.path.abspath(os.path.join(webwareDir, 'WebKit')) for p in [workDir, webwareDir] + libraryDirs + sysPath: if not p: continue # do not include the empty ("current") directory p = os.path.abspath(p) if p == webKitDir or p in path or not os.path.exists(p): continue # do not include WebKit and duplicates path.append(p) sys.path = path # set the new search path # Prepare the arguments for launchWebKit: args = (appServer, workDir, args) # Handle special case where app server shall be stopped: if 'stop' in args[2]: print 'Stopping WebKit.%s...' % appServer errorlevel = launchWebKit(*args) if not errorlevel: if pidFile and os.path.exists(pidFile): try: os.remove(pidFile) except Exception: print 'The pid file could not be removed.' print sys.exit(errorlevel) # Handle the pid file: if pidFile: pidFile = os.path.expanduser(pidFile) # Read the old pid file: try: pid = int(open(pidFile).read()) except Exception: pid = None if pid is not None: print 'According to the pid file, the server is still running.' # Try to kill an already running server: killed = False try: from signal import SIGTERM, SIGKILL print 'Trying to terminate the server with pid %d...' % pid os.kill(pid, SIGTERM) except OSError as error: from errno import ESRCH if error.errno == ESRCH: # no such process print 'The pid file was stale, continuing with startup...' killed = True else: print 'Cannot terminate server with pid %d.' % pid print error.strerror sys.exit(1) except (ImportError, AttributeError): print 'Cannot check or terminate server with pid %d.' % pid sys.exit(1) if not killed: from time import sleep try: for i in range(100): sleep(0.1) os.kill(pid, SIGTERM) except OSError as error: from errno import ESRCH if error.errno == ESRCH: print 'Server with pid %d has been terminated.' % pid killed = True if not killed: try: for i in range(100): sleep(0.1) os.kill(pid, SIGKILL) except OSError as error: from errno import ESRCH if error.errno == ESRCH: print 'Server with pid %d has been killed by force.' % pid killed = True if not killed: print 'Server with pid %d cannot be terminated.' % pid sys.exit(1) # Write a new pid file: try: open(pidFile, 'w').write(str(os.getpid())) except Exception: print 'The pid file %r could not be written.' % pidFile sys.exit(1) olduid = oldgid = stdout = stderr = log = None errorlevel = 1 try: # Change server process group: if gid is not None: try: oldgid = os.getgid() if gid != oldgid: os.setgid(gid) if group: print 'Changed server process group to %r.' % group else: oldgid = None except Exception: if group: print 'Could not set server process group to %r.' % group oldgid = None sys.exit(1) # Change server process user: if uid is not None: try: olduid = os.getuid() if uid != olduid: os.setuid(uid) print 'Changed server process user to %r.' % user else: olduid = None except Exception: print 'Could not change server process user to %r.' % user olduid = None sys.exit(1) msg = 'WebKit.' + appServer if args[2]: msg = '%s %s' % (msg, ' '.join(args[2])) else: msg = 'Starting %s...' % msg print msg # Handle the log file: if logFile: logFile = os.path.expanduser(logFile) try: log = open(logFile, 'a', 1) # append, line buffered mode print 'Output has been redirected to %r...' % logFile stdout, stderr = sys.stdout, sys.stderr sys.stdout = sys.stderr = log except IOError as error: print 'Cannot redirect output to %r.' % logFile print error.strerror log = None sys.exit(1) else: print # Set up a reference to our profiler so apps can import and use it: from WebKit import Profiler if Profiler.startTime is None: from time import time Profiler.startTime = time() # Now start the app server: if runProfile: print ('Profiling is on. ' 'See docstring in Profiler.py for more info.') print try: from cProfile import Profile except ImportError: from profile import Profile profiler = Profile() Profiler.profiler = profiler errorlevel = Profiler.runCall(launchWebKit, *args) print print 'Writing profile stats to %s...' % Profiler.statsFilename Profiler.dumpStats() print 'WARNING: Applications run much slower when profiled,' print 'so turn off profiling in Launch.py when you are finished.' else: errorlevel = launchWebKit(*args) finally: print # Close the log file properly: if log: sys.stdout, sys.stderr = stdout, stderr log.close() # Restore server process group and user. # Note that because we changed the real group and # user id of the process (most secure thing), we # cannot change them back now, but we try anyway: if oldgid is not None: try: os.setgid(oldgid) except Exception: pass else: oldgid = None if olduid is not None: try: os.setuid(olduid) except Exception: pass else: olduid = None # Remove the pid file again. # Note that this may fail when the group or user id # has been changed, but we try anyway: if pidFile and os.path.exists(pidFile): try: os.remove(pidFile) except Exception: if oldgid is None and olduid is None: print 'The pid file could not be removed.' print sys.exit(errorlevel)
if args is None: args = sys.argv if len(args) < 2: usage() server = args[1] # the server # figure out directory locations webKitPath = os.path.dirname(os.path.join(os.getcwd(), sys.argv[0])) webwarePath = os.path.dirname(webKitPath) # go to Webware dir so that: # - importing packages like 'WebUtils' hits this Webware # - we cannot import WebKit modules without qualifying them os.chdir(webwarePath) # Go! launchWebKit(server, webKitPath, args[2:]) if __name__ == '__main__': if runProfile: print 'Profiling is on. See doc string in Profiler.py for more info.' from profile import Profile profiler = Profile() profiler.runcall(main) from WebKit import Profiler Profiler.dumpStats() else: main()