ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/WEBTOOLS/cmsWeb.py
Revision: 1.6
Committed: Thu Jan 31 18:08:33 2008 UTC (17 years, 3 months ago) by eulisse
Content type: text/x-python
Branch: MAIN
CVS Tags: SiteDB_080227, V01-03-01, V01-03-00, SiteDB_SM_Nightly_150208
Changes since 1.5: +109 -17 lines
Log Message:
start, stop and status commands now somewhat work.

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     def __init__ (self, context):
19     self.context = context
20 eulisse 1.6 self.registry = {"start": StartCommand,
21     "status": StatusCommand,
22     "stop": StopCommand}
23     self.opts, self.args = self.context.OptionParser ().parse_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     username = getpass.getuser()
77    
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.6 filename = abspath (self.opts.pidFile)
102     try:
103     pid = getPidFromFile (filename)
104     if checkIfPidRunning (pid):
105     print "A process %s is alredy running using lock file %s. Nothing is done." % (pid, filename)
106     sys.exit (0)
107     else:
108     print "Process %s died unexpectedly. Removing lockfile %s." % (pid, filename)
109     os.unlink (filename)
110     except IOError:
111     # TODO: this should be a warning.
112     print "File %s does not exists. Will be created." % filename
113    
114     open (filename, 'w').write (str (os.getpid ()))
115     self.context.addService (CmdLineArgs (context.OptionParser ()))
116     self.context.addService (Cfg ())
117 eulisse 1.5 if opts.profile:
118     import pstats
119     try:
120     import cProfile as profile
121     except ImportError:
122     import profile
123     profile.run ('app.start ()', 'bonsaiProfiler')
124    
125 eulisse 1.6 p = pstats.Stats ('bonsaiProfiler')
126     p.strip_dirs().sort_stats (-1).print_stats()
127 eulisse 1.5 else:
128     app.start ()
129 eulisse 1.6
130     def finish (self):
131     filename = abspath (self.opts.pidFile)
132     try:
133     os.unlink (filename)
134     except IOError:
135     print "Unable to remove lock file %s" % filename
136 eulisse 1.5
137     def getValidOptions (args):
138     validArguments = ["start",
139     "stop",
140     "restart"]
141     validOptions = ["--cfg"]
142    
143     result = []
144     for i in range (0, len (args)):
145     arg = sys.argv[i]
146     if arg in validArguments:
147     result.append (args[i])
148    
149     for i in range (0, len (args)):
150     option = args[i]
151     if option in validOptions:
152     result.append (option)
153     result.append (args[i+1])
154    
155 eulisse 1.1 if __name__ == '__main__':
156 eulisse 1.2 context = Context ()
157     context.addService (OptionParser ())
158 eulisse 1.5 parser = context.OptionParser ()
159     parser.add_option ("--profile",
160     help="start server in profiler mode",
161     default=False,
162     action="store_true",
163     dest="profile")
164 eulisse 1.4 def stripTrailingSlash (option, opt_str, value, parser, *args, **kwargs):
165     setattr(parser.values, option.dest, value.rstrip ("/"))
166    
167 eulisse 1.5 parser.add_option ("--base-url",
168     help="Base URL for the server (for usage behind a proxy).",
169     default="http://localhost:8030",
170     dest="baseUrl",
171     action="callback",
172     callback=stripTrailingSlash,
173     type="str",
174     nargs=1)
175 eulisse 1.6
176     parser.add_option ("--pid-file",
177     help="File in which it is specified the pid of wanted instance",
178     default="pid.txt",
179     dest="pidFile",
180     metavar="FILE")
181    
182     parser.add_option ("--force-kill",
183     help="Uses SIGKILL rather than SIGTERM",
184     default=False,
185     action="store_true",
186     dest="forceKill",
187     metavar="FILE")
188    
189 eulisse 1.5
190     validOptions = getValidOptions (sys.argv)
191 eulisse 1.2
192 eulisse 1.5 opts, args = parser.parse_args (args=validOptions)
193     if not len (args):
194     args = ["start"]
195     factory = CommandFactory (context)
196     startCommand = factory.createByName (args[0])
197     if not startCommand:
198     print "Command %s not known." % args[0]
199     sys.exit (1)
200 eulisse 1.6 startCommand.run ()
201     startCommand.finish ()