Revision 16a8967d daemons/ganeti-rapi
b/daemons/ganeti-rapi | ||
---|---|---|
32 | 32 |
from ganeti import constants |
33 | 33 |
from ganeti import errors |
34 | 34 |
from ganeti import http |
35 |
from ganeti import daemon |
|
35 | 36 |
from ganeti import ssconf |
36 | 37 |
from ganeti import utils |
37 | 38 |
from ganeti.rapi import connector |
38 | 39 |
|
39 | 40 |
|
40 |
class RESTRequestHandler(http.HTTPRequestHandler):
|
|
41 |
class RemoteApiHttpServer(http.HttpServer):
|
|
41 | 42 |
"""REST Request Handler Class. |
42 | 43 |
|
43 | 44 |
""" |
44 |
def setup(self):
|
|
45 |
super(RESTRequestHandler, self).setup()
|
|
45 |
def __init__(self, *args, **kwargs):
|
|
46 |
http.HttpServer.__init__(self, *args, **kwargs)
|
|
46 | 47 |
self._resmap = connector.Mapper() |
47 | 48 |
|
48 |
def HandleRequest(self): |
|
49 |
""" Handels a request.
|
|
49 |
def HandleRequest(self, req):
|
|
50 |
"""Handles a request.
|
|
50 | 51 |
|
51 | 52 |
""" |
52 |
(HandlerClass, items, args) = self._resmap.getController(self.path)
|
|
53 |
handler = HandlerClass(self, items, args, self.post_data)
|
|
53 |
(HandlerClass, items, args) = self._resmap.getController(req.request_path)
|
|
54 |
handler = HandlerClass(items, args, req.request_post_data)
|
|
54 | 55 |
|
55 |
command = self.command.upper()
|
|
56 |
method = req.request_method.upper()
|
|
56 | 57 |
try: |
57 |
fn = getattr(handler, command)
|
|
58 |
fn = getattr(handler, method)
|
|
58 | 59 |
except AttributeError, err: |
59 | 60 |
raise http.HTTPBadRequest() |
60 | 61 |
|
61 | 62 |
try: |
62 |
try: |
|
63 |
result = fn() |
|
64 |
except: |
|
65 |
logging.exception("Error while handling the %s request", command) |
|
66 |
raise |
|
67 |
|
|
68 |
except errors.OpPrereqError, err: |
|
69 |
# TODO: "Not found" is not always the correct error. Ganeti's core must |
|
70 |
# differentiate between different error types. |
|
71 |
raise http.HTTPNotFound(message=str(err)) |
|
63 |
result = fn() |
|
64 |
except: |
|
65 |
logging.exception("Error while handling the %s request", method) |
|
66 |
raise |
|
72 | 67 |
|
73 | 68 |
return result |
74 | 69 |
|
75 | 70 |
|
76 |
class RESTHttpServer(http.HTTPServer): |
|
77 |
def serve_forever(self): |
|
78 |
"""Handle one request at a time until told to quit.""" |
|
79 |
sighandler = utils.SignalHandler([signal.SIGINT, signal.SIGTERM]) |
|
80 |
try: |
|
81 |
while not sighandler.called: |
|
82 |
self.handle_request() |
|
83 |
finally: |
|
84 |
sighandler.Reset() |
|
85 |
|
|
86 |
|
|
87 | 71 |
def ParseOptions(): |
88 | 72 |
"""Parse the command line options. |
89 | 73 |
|
... | ... | |
144 | 128 |
stderr_logging=not options.fork) |
145 | 129 |
|
146 | 130 |
utils.WritePidFile(constants.RAPI_PID) |
147 |
|
|
148 |
log_fd = open(constants.LOG_RAPIACCESS, 'a') |
|
149 | 131 |
try: |
150 |
apache_log = http.ApacheLogfile(log_fd)
|
|
151 |
httpd = RESTHttpServer(("", options.port), RESTRequestHandler,
|
|
152 |
httplog=apache_log)
|
|
132 |
mainloop = daemon.Mainloop()
|
|
133 |
server = RemoteApiHttpServer(mainloop, ("", options.port))
|
|
134 |
server.Start()
|
|
153 | 135 |
try: |
154 |
httpd.serve_forever()
|
|
136 |
mainloop.Run()
|
|
155 | 137 |
finally: |
156 |
httpd.server_close() |
|
157 |
utils.RemovePidFile(constants.RAPI_PID) |
|
158 |
|
|
138 |
server.Stop() |
|
159 | 139 |
finally: |
160 |
log_fd.close() |
|
161 |
|
|
162 |
sys.exit(0) |
|
140 |
utils.RemovePidFile(constants.RAPI_PID) |
|
163 | 141 |
|
164 | 142 |
|
165 | 143 |
if __name__ == '__main__': |
Also available in: Unified diff