34
40
from cinder.openstack.common import log as logging
35
41
from cinder import utils
46
help="Number of backlog requests to configure the socket with"),
47
cfg.IntOpt('tcp_keepidle',
49
help="Sets the value of TCP_KEEPIDLE in seconds for each "
50
"server socket. Not supported on OS X."),
51
cfg.StrOpt('ssl_ca_file',
53
help="CA certificate file to use to verify "
54
"connecting clients"),
55
cfg.StrOpt('ssl_cert_file',
57
help="Certificate file to use when starting "
58
"the server securely"),
59
cfg.StrOpt('ssl_key_file',
61
help="Private key file to use when starting "
62
"the server securely"),
66
CONF.register_opts(socket_opts)
38
68
FLAGS = flags.FLAGS
39
69
LOG = logging.getLogger(__name__)
67
97
self._logger = logging.getLogger("eventlet.wsgi.server")
68
98
self._wsgi_logger = logging.WritableLogger(self._logger)
100
def _get_socket(self, host, port, backlog):
101
bind_addr = (host, port)
102
# TODO(dims): eventlet's green dns/socket module does not actually
103
# support IPv6 in getaddrinfo(). We need to get around this in the
104
# future or monitor upstream for a fix
106
info = socket.getaddrinfo(bind_addr[0],
109
socket.SOCK_STREAM)[0]
113
family = socket.AF_INET
115
cert_file = CONF.ssl_cert_file
116
key_file = CONF.ssl_key_file
117
ca_file = CONF.ssl_ca_file
118
use_ssl = cert_file or key_file
120
if cert_file and not os.path.exists(cert_file):
121
raise RuntimeError(_("Unable to find cert_file : %s") % cert_file)
123
if ca_file and not os.path.exists(ca_file):
124
raise RuntimeError(_("Unable to find ca_file : %s") % ca_file)
126
if key_file and not os.path.exists(key_file):
127
raise RuntimeError(_("Unable to find key_file : %s") % key_file)
129
if use_ssl and (not cert_file or not key_file):
130
raise RuntimeError(_("When running server in SSL mode, you must "
131
"specify both a cert_file and key_file "
132
"option value in your configuration file"))
137
'certfile': cert_file,
139
'cert_reqs': ssl.CERT_NONE,
143
ssl_kwargs['ca_certs'] = ca_file
144
ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED
146
return ssl.wrap_socket(sock, **ssl_kwargs)
149
retry_until = time.time() + 30
150
while not sock and time.time() < retry_until:
152
sock = eventlet.listen(bind_addr,
156
sock = wrap_ssl(sock)
158
except socket.error, err:
159
if err.args[0] != errno.EADDRINUSE:
163
raise RuntimeError(_("Could not bind to %(host)s:%(port)s "
164
"after trying for 30 seconds") %
165
{'host': host, 'port': port})
166
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
167
# sockets can hang around forever without keepalive
168
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
170
# This option isn't available in the OS X version of eventlet
171
if hasattr(socket, 'TCP_KEEPIDLE'):
172
sock.setsockopt(socket.IPPROTO_TCP,
71
179
"""Run the blocking eventlet WSGI server.
91
199
raise exception.InvalidInput(
92
200
reason='The backlog must be more than 1')
93
self._socket = eventlet.listen((self.host, self.port), backlog=backlog)
202
self._socket = self._get_socket(self._host,
94
205
self._server = eventlet.spawn(self._start)
95
(self.host, self.port) = self._socket.getsockname()
96
LOG.info(_("Started %(name)s on %(host)s:%(port)s") % self.__dict__)
206
(self._host, self._port) = self._socket.getsockname()[0:2]
207
LOG.info(_("Started %(name)s on %(_host)s:%(_port)s") % self.__dict__)
99
218
"""Stop this server.