def _get_socket(host, port, backlog): info = socket.getaddrinfo( host, port, socket.AF_UNSPEC, socket.SOCK_STREAM )[0] family = info[0] bind_addr = info[-1] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=backlog, family=family) if sslutils.is_enabled(CONF): sock = sslutils.wrap(CONF, sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise if not sock: raise RuntimeError(_( "Could not bind to %(host)s:%(port)s " "after trying for 30 seconds") % {'host': host, 'port': port}) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def _get_socket(self, host, port, backlog): # TODO(dims): eventlet's green dns/socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix info = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM)[0] family = info[0] bind_addr = info[-1] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=backlog, family=family) if sslutils.is_enabled(CONF): sock = sslutils.wrap(CONF, sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(host)s:%(port)s " "after trying for 30 seconds") % {"host": host, "port": port} ) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, "TCP_KEEPIDLE"): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def start(self): """Start serving a WSGI application. :returns: None """ # The server socket object will be closed after server exits, # but the underlying file descriptor will remain open, and will # give bad file descriptor error. So duplicating the socket object, # to keep file descriptor usable. self.dup_socket = self._socket.dup() self.dup_socket = self._set_socket_opts(self.dup_socket) if self._use_ssl: self.dup_socket = sslutils.wrap(self.conf, self.dup_socket) wsgi_kwargs = { 'func': eventlet.wsgi.server, 'sock': self.dup_socket, 'site': self.app, 'protocol': self._protocol, 'custom_pool': self._pool, 'log': self._logger, 'log_format': self.conf.wsgi_log_format, 'debug': False, 'keepalive': self.conf.wsgi_keep_alive, 'socket_timeout': self.client_socket_timeout } if self._max_url_len: wsgi_kwargs['url_length_limit'] = self._max_url_len self._server = eventlet.spawn(**wsgi_kwargs)
def start(self): """Start serving a WSGI application. :returns: None """ # The server socket object will be closed after server exits, # but the underlying file descriptor will remain open, and will # give bad file descriptor error. So duplicating the socket object, # to keep file descriptor usable. self.dup_socket = self.socket.dup() if self._use_ssl: self.dup_socket = sslutils.wrap(self.conf, self.dup_socket) wsgi_kwargs = { "func": eventlet.wsgi.server, "sock": self.dup_socket, "site": self.app, "protocol": self._protocol, "custom_pool": self._pool, "log": self._logger, "log_format": self.conf.wsgi_log_format, "debug": False, "keepalive": self.conf.wsgi_keep_alive, "socket_timeout": self.client_socket_timeout, } if self._max_url_len: wsgi_kwargs["url_length_limit"] = self._max_url_len self._server = eventlet.spawn(**wsgi_kwargs)
def _test_wrap(self, exists_mock, wrap_socket_mock, **kwargs): exists_mock.return_value = True sock = mock.Mock() self.conf.set_default("cert_file", self.cert_file_name, group=sslutils.config_section) self.conf.set_default("key_file", self.key_file_name, group=sslutils.config_section) ssl_kwargs = {'server_side': True, 'certfile': self.conf.ssl.cert_file, 'keyfile': self.conf.ssl.key_file, 'cert_reqs': ssl.CERT_NONE, } if kwargs: ssl_kwargs.update(**kwargs) sslutils.wrap(self.conf, sock) wrap_socket_mock.assert_called_once_with(sock, **ssl_kwargs)
def _start(self, host, port): wsgi_sock = utils.bind_tcp(host, port, CONF.backlog, CONF.tcp_keepidle) if sslutils.is_enabled(CONF): wsgi_sock = sslutils.wrap(CONF, wsgi_sock) self._wsgi_socks.append(wsgi_sock) self.tg.add_thread(self._wsgi_handle, wsgi_sock)
def _start(self, host, port): wsgi_sock = utils.bind_tcp( host, port, CONF.backlog, CONF.tcp_keepidle) if self._use_ssl: wsgi_sock = sslutils.wrap(CONF, wsgi_sock) self._wsgi_socks.append(wsgi_sock) self.tg.add_thread(self._wsgi_handle, wsgi_sock)
def start(self): super(WSGIService, self).start() self._wsgi_sock = utils.bind_tcp(self._service_config.api_host, self._service_config.api_port, CONF.backlog, CONF.tcp_keepidle) if sslutils.is_enabled(CONF): self._wsgi_sock = sslutils.wrap(CONF, self._wsgi_sock) self.tg.add_thread(self._wsgi_handle)
def start(self): super(WorkerService, self).start() # When api worker is stopped it kills the eventlet wsgi server which # internally closes the wsgi server socket object. This server socket # object becomes not usable which leads to "Bad file descriptor" # errors on service restart. # Duplicate a socket object to keep a file descriptor usable. dup_sock = self._service._socket.dup() if CONF.use_ssl and not self._disable_ssl: dup_sock = sslutils.wrap(CONF, dup_sock) self._server = self._service.pool.spawn(self._service._run, self._application, dup_sock)
def start(self): super(WSGIService, self).start() self._wsgi_sock = utils.bind_tcp( self._service_config.api_host, self._service_config.api_port, CONF.backlog, CONF.tcp_keepidle) if sslutils.is_enabled(CONF): self._wsgi_sock = sslutils.wrap(CONF, self._wsgi_sock) self.tg.add_thread(self._wsgi_handle)
def _wsgi_get_socket(self): # TODO(dims): eventlet's green dns/socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix info = socket.getaddrinfo(self._service_config.api_host, self._service_config.api_port, socket.AF_UNSPEC, socket.SOCK_STREAM)[0] family = info[0] bind_addr = info[-1] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: # TODO(kiall): Backlog should be a service specific setting, # rather than a global sock = eventlet.listen(bind_addr, backlog=cfg.CONF.backlog, family=family) if sslutils.is_enabled(CONF): sock = sslutils.wrap(CONF, sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(host)s:%(port)s " "after trying for 30 seconds") % { 'host': self._service_config.api_host, 'port': self._service_config.api_port }) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def start(self, application): """Run a WSGI server with the given application. :param application: The application to run in the WSGI server """ def kill_children(*args): """Kills the entire process group.""" LOG.error(_LE('SIGTERM received')) signal.signal(signal.SIGTERM, signal.SIG_IGN) self.running = False os.killpg(0, signal.SIGTERM) def hup(*args): """Shuts down the server(s). Shuts down the server(s), but allows running requests to complete """ LOG.error(_LE('SIGHUP received')) signal.signal(signal.SIGHUP, signal.SIG_IGN) os.killpg(0, signal.SIGHUP) signal.signal(signal.SIGHUP, hup) self.application = application self.sock = eventlet.listen((CONF.host, CONF.port), backlog=500) if sslutils.is_enabled(CONF): LOG.info(_LI("Using HTTPS for port %s"), CONF.port) self.sock = sslutils.wrap(CONF, self.sock) if CONF.api_workers == 0: # Useful for profiling, test, debug etc. self.pool = eventlet.GreenPool(size=self.threads) self.pool.spawn_n(self._single_run, application, self.sock) return LOG.debug("Starting %d workers", CONF.api_workers) signal.signal(signal.SIGTERM, kill_children) signal.signal(signal.SIGHUP, hup) while len(self.children) < CONF.api_workers: self.run_child()