ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/WEBTOOLS/cmsWeb.py
Revision: 1.7
Committed: Mon Mar 3 11:52:39 2008 UTC (17 years, 1 month ago) by eulisse
Content type: text/x-python
Branch: MAIN
Changes since 1.6: +52 -48 lines
Log Message:
Misc fixes:
* Reworked logic for argument passing. Now --port and other server specific
  options work again.
* Constructor of BonsaiServer refactored in multiple functions.
* The main loop is now contained in a CmsWebApplication class.

File Contents

# User Rev Content
1 eulisse 1.1 #!/usr/bin/env python
2     from Framework import BonsaiServer
3 eulisse 1.2 from Framework import Context
4     from optparse import OptionParser
5     from Framework import CmdLineArgs
6 eulisse 1.5 import sys
7 eulisse 1.6 import os
8     import getpass
9     from os.path import abspath
10     import errno
11 eulisse 1.1
12 eulisse 1.3 class Cfg:
13     def __init__ (self):
14     # TODO: make it a property.
15     self.installRoot = __file__.rsplit ("/", 1)[0]
16    
17 eulisse 1.5 class CommandFactory (object):
18 eulisse 1.7 def __init__ (self, context, opts, args):
19 eulisse 1.5 self.context = context
20 eulisse 1.6 self.registry = {"start": StartCommand,
21     "status": StatusCommand,
22     "stop": StopCommand}
23 eulisse 1.7 self.opts, self.args = opts, args
24 eulisse 1.5
25     def createByName (self, name):
26     try:
27     obj = self.registry[name] ()
28     except KeyError:
29     return None
30     obj.context = self.context
31 eulisse 1.6 obj.opts = self.opts
32     obj.args = self.args
33 eulisse 1.5 return obj
34    
35     class Command (object):
36     def __init__ (self):
37     self.context = None
38 eulisse 1.6 self.opts = None
39     self.args = None
40 eulisse 1.5
41 eulisse 1.6 def finish (self):
42 eulisse 1.5 pass
43    
44 eulisse 1.6 def checkIfPidRunning (pid):
45     try:
46     os.kill(pid, 0)
47     return True
48     except OSError, err:
49     return err.errno == errno.EPERM
50    
51     def getPidFromFile (filename):
52     try:
53     return int (open (filename).read ().strip ())
54     except ValueError:
55     print "Invalid lockfile format for %s." % filename
56     print "Cannot detect status."
57     sys.exit (2)
58    
59     class StatusCommand (Command):
60     def run (self):
61     filename = abspath (self.opts.pidFile)
62     try:
63     pid = getPidFromFile (filename)
64     if checkIfPidRunning (pid):
65     print "cmsWeb is running as pid %s" % pid
66     sys.exit (0)
67     print "cmsWeb not running."
68     except IOError:
69     print "File %s does not exists." % opts.pidFile
70     print "Cannot detect status."
71     sys.exit (2)
72    
73     class StopCommand (Command):
74     def run (self):
75     filename = abspath (self.opts.pidFile)
76 eulisse 1.7 username = getpass.getuser ()
77 eulisse 1.6
78     try:
79     pid = getPidFromFile (filename)
80     if self.opts.forceKill == True:
81     print "Sending SIGKILL to pid %s" % pid
82     os.kill (pid, 9)
83     sys.exit (0)
84     print "Sending SIGTERM to pid %s" % pid
85     os.kill (pid, 15)
86     except OSError, err:
87     if err.errno == errno.EPERM:
88     print "Pid %s is not owned by user %s. Cannot stop it." % (pid, username)
89     sys.exit (2)
90     else:
91     print "Pid %s does not exists. Please remove the lock file %s." % (pid, filename)
92     except IOError:
93     print "File %s does not exists." % opts.pidFile
94     print "Cannot detect status."
95     sys.exit (2)
96    
97    
98     class StartCommand (Command):
99 eulisse 1.5 def run (self):
100     app = BonsaiServer (self.context)
101 eulisse 1.7 opts, args = self.context.OptionParser ().parse_args ()
102 eulisse 1.6 filename = abspath (self.opts.pidFile)
103     try:
104     pid = getPidFromFile (filename)
105     if checkIfPidRunning (pid):
106     print "A process %s is alredy running using lock file %s. Nothing is done." % (pid, filename)
107     sys.exit (0)
108     else:
109     print "Process %s died unexpectedly. Removing lockfile %s." % (pid, filename)
110     os.unlink (filename)
111     except IOError:
112     # TODO: this should be a warning.
113     print "File %s does not exists. Will be created." % filename
114    
115     open (filename, 'w').write (str (os.getpid ()))
116 eulisse 1.7 self.context.addService (CmdLineArgs (self.context.OptionParser ()))
117 eulisse 1.6 self.context.addService (Cfg ())
118 eulisse 1.5 if opts.profile:
119     import pstats
120     try:
121     import cProfile as profile
122     except ImportError:
123     import profile
124     profile.run ('app.start ()', 'bonsaiProfiler')
125    
126 eulisse 1.6 p = pstats.Stats ('bonsaiProfiler')
127     p.strip_dirs().sort_stats (-1).print_stats()
128 eulisse 1.5 else:
129     app.start ()
130 eulisse 1.6
131     def finish (self):
132     filename = abspath (self.opts.pidFile)
133     try:
134     os.unlink (filename)
135     except IOError:
136     print "Unable to remove lock file %s" % filename
137 eulisse 1.5
138     def getValidOptions (args):
139     validArguments = ["start",
140     "stop",
141     "restart"]
142 eulisse 1.7 validOptions = ["--cfg", "--force-kill", "--pid-file"]
143 eulisse 1.5
144     result = []
145     for i in range (0, len (args)):
146     arg = sys.argv[i]
147     if arg in validArguments:
148     result.append (args[i])
149    
150     for i in range (0, len (args)):
151     option = args[i]
152     if option in validOptions:
153     result.append (option)
154     result.append (args[i+1])
155 eulisse 1.7 return result
156 eulisse 1.5
157 eulisse 1.7 class CmsWebApplication (object):
158     def __init__ (self):
159     self.context = Context ()
160     self.context.addService (OptionParser ())
161     self.parser = self.context.OptionParser ()
162     self.__addOptions ()
163 eulisse 1.4
164 eulisse 1.7 def __addOptions (self):
165     self.parser.add_option ("--profile",
166     help="start server in profiler mode",
167     default=False,
168     action="store_true",
169     dest="profile")
170    
171     self.parser.add_option ("--pid-file",
172     help="File in which it is specified the pid of wanted instance",
173     default="pid.txt",
174     dest="pidFile",
175     metavar="FILE")
176    
177     self.parser.add_option ("--force-kill",
178     help="Uses SIGKILL rather than SIGTERM",
179     default=False,
180     action="store_true",
181     dest="forceKill",
182     metavar="FILE")
183 eulisse 1.6
184 eulisse 1.7 def run (self):
185     validOptions = getValidOptions (sys.argv)
186 eulisse 1.6
187 eulisse 1.7 print "parse"
188     opts, args = self.parser.parse_args (args=validOptions)
189     print opts, args
190     print "parsed"
191 eulisse 1.5
192 eulisse 1.7 if not len (args):
193     args = ["start"]
194    
195     factory = CommandFactory (self.context, opts, args)
196     startCommand = factory.createByName (args[0])
197     if not startCommand:
198     print "Command %s not known." % args[0]
199     sys.exit (1)
200     startCommand.run ()
201     startCommand.finish ()
202    
203     if __name__ == '__main__':
204     app = CmsWebApplication ()
205     app.run ()