4 # Copyright (C) 2006, 2007 Google Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 """ Ganeti Remote API master script.
30 import ganeti.rapi.RESTHTTPServer
32 RELEASE_VERSION = 0.01
37 """Parse the command line options.
40 (options, args) as from OptionParser.parse_args()
43 parser = optparse.OptionParser(description="Ganeti Remote API",
44 usage="%prog [-d] [-p port]",
45 version="%%prog (ganeti) %s" % RELEASE_VERSION)
47 parser.add_option("-d", "--debug", dest="debug",
48 help="Enable some debug messages",
49 default=False, action="store_true")
50 parser.add_option("-p", "--port", dest="port",
51 help="Port to run API",
52 default=API_PORT, type="int")
53 parser.add_option("-S", "--https", dest="ssl",
54 help="Secure HTTP protocol with SSL",
55 default=False, action="store_true")
56 parser.add_option("-K", "--ssl-key", dest="ssl_key",
58 default=None, type="string")
59 parser.add_option("-C", "--ssl-cert", dest="ssl_cert",
60 help="SSL certificate",
61 default=None, type="string")
62 options, args = parser.parse_args()
64 if len(args) != 1 or args[0] not in ("start", "stop"):
65 print >> sys.stderr, "Usage: %s [-d] [-p port] start|stop\n" % sys.argv[0]
69 if not (options.ssl_cert and options.ssl_key):
70 print >> sys.stderr, "For secure mode please provide " \
71 "--ssl-key and --ssl-cert arguments"
78 """Map network port to PID.
81 port: A port number to map.
87 _NET_STAT = ['/proc/net/tcp','/proc/net/udp']
92 for file in _NET_STAT:
96 for line in f.readlines()[1:]:
98 inode2port[long(d[9])] = int(d[1].split(':')[1], 16)
101 except EnvironmentError:
102 # Nothing can be done
105 fdlist = glob.glob('/proc/[0-9]*/fd/*')
108 pid = int(fd.split('/')[2])
109 inode = long(os.stat(fd)[1])
110 if inode in inode2port:
111 port2pid[inode2port[inode]] = pid
112 except EnvironmentError:
113 # Nothing can be done
117 return port2pid[port]
122 def StartAPI(options):
131 # do the UNIX double-fork magic
138 print >> sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
141 # decouple from parent environment
150 # exit from second parent, print eventual PID before
151 print "Ganeti-RAPI PID: %d port: %d" % (pid, options.port)
154 print >> sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
157 # start the daemon main loop
158 ganeti.rapi.RESTHTTPServer.start(options)
161 def StopAPI(options):
164 pid = Port2PID(options.port)
166 print "Stopping Ganeti-RAPI PID: %d, port: %d... " \
167 % (pid, options.port),
171 print >> sys.stderr, "Unable to locate running Ganeti-RAPI on port: %d" \
174 except Exception, ex:
175 print >> sys.stderr, ex
185 options, args = ParseOptions()
186 if args[0] == "start":
187 result = StartAPI(options)
189 result = StopAPI(options)
193 if __name__ == '__main__':