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.3 by eulisse, Fri Mar 30 16:23:29 2007 UTC vs.
Revision 1.6 by eulisse, Thu Jan 31 18:08:33 2008 UTC

# Line 3 | Line 3 | 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 < if __name__ == '__main__':
18 <    context = Context ()
19 <    context.addService (OptionParser ())
20 <    context.OptionParser ().add_option ("--profile",
21 <                                        help="start server in profiler mode",
22 <                                        default=False,
23 <                                        action="store_true",
19 <                                        dest="profile")
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 <    context.OptionParser ().add_option ("--base-url",
26 <                                        help="Base URL for the server (for usage behind a proxy).",
27 <                                        default="http://localhost:8030",
28 <                                        dest="baseUrl")
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 <    app = BonsaiServer (context)
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 <    opts, args = context.OptionParser ().parse_args ()
150 <    context.addService (CmdLineArgs (context.OptionParser ()))
151 <    context.addService (Cfg ())
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 opts.profile:
156 <        import pstats
157 <        try:
158 <            import cProfile as profile
159 <        except ImportError:
160 <            import profile
161 <        profile.run ('app.start ()', 'bonsaiProfiler')
155 > if __name__ == '__main__':
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 <        p = pstats.Stats('bonsaiProfiler')
168 <        p.strip_dirs().sort_stats(-1).print_stats()        
169 <    else:
170 <        app.start ()
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