ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/WEBTOOLS/cmsWeb.py
(Generate patch)

Comparing COMP/WEBTOOLS/cmsWeb.py (file contents):
Revision 1.1 by eulisse, Mon Mar 12 10:39:07 2007 UTC vs.
Revision 1.6 by eulisse, Thu Jan 31 18:08:33 2008 UTC

# Line 1 | Line 1
1   #!/usr/bin/env python
2   from Framework import BonsaiServer
3 + from Framework import Context
4 + from optparse import OptionParser
5 + from Framework import CmdLineArgs
6 + import sys
7 + import os
8 + import getpass
9 + from os.path import abspath
10 + import errno
11 +
12 + class Cfg:
13 +    def __init__ (self):
14 +        # TODO: make it a property.
15 +        self.installRoot = __file__.rsplit ("/", 1)[0]
16 +
17 + class CommandFactory (object):
18 +    def __init__ (self, context):
19 +        self.context = context
20 +        self.registry = {"start": StartCommand,
21 +                         "status": StatusCommand,
22 +                         "stop": StopCommand}
23 +        self.opts, self.args = self.context.OptionParser ().parse_args ()
24 +    
25 +    def createByName (self, name):
26 +        try:
27 +            obj = self.registry[name] ()
28 +        except KeyError:
29 +            return None
30 +        obj.context = self.context
31 +        obj.opts = self.opts
32 +        obj.args = self.args
33 +        return obj
34 +
35 + class Command (object):
36 +    def __init__ (self):
37 +        self.context = None
38 +        self.opts = None
39 +        self.args = None
40 +
41 +    def finish (self):
42 +        pass
43 +
44 + 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 +    def run (self):
100 +        app = BonsaiServer (self.context)
101 +        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 +        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 +            p = pstats.Stats ('bonsaiProfiler')
126 +            p.strip_dirs().sort_stats (-1).print_stats()        
127 +        else:
128 +            app.start ()
129 +    
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 +
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   if __name__ == '__main__':
156 <    app = BonsaiServer (socket_port=8030)
157 <    app.start ()
156 >    context = Context ()
157 >    context.addService (OptionParser ())
158 >    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 >    def stripTrailingSlash (option, opt_str, value, parser, *args, **kwargs):
165 >        setattr(parser.values, option.dest, value.rstrip ("/"))
166 >        
167 >    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 >    
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 >
190 >    validOptions = getValidOptions (sys.argv)
191 >    
192 >    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 >    startCommand.run ()
201 >    startCommand.finish ()

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines