diff --git a/nova/console/websocketproxy.py b/nova/console/websocketproxy.py index 6b692394942b..954b9b1ecfb9 100644 --- a/nova/console/websocketproxy.py +++ b/nova/console/websocketproxy.py @@ -304,12 +304,18 @@ class NovaProxyRequestHandlerBase(object): class NovaProxyRequestHandler(NovaProxyRequestHandlerBase, websockify.ProxyRequestHandler): def __init__(self, *args, **kwargs): - # Order matters here. ProxyRequestHandler.__init__() will eventually - # call new_websocket_client() and we need self.compute_rpcapi set - # before then. - self.compute_rpcapi = compute_rpcapi.ComputeAPI() + self._compute_rpcapi = None websockify.ProxyRequestHandler.__init__(self, *args, **kwargs) + @property + def compute_rpcapi(self): + # Lazy load the rpcapi/ComputeAPI upon first use for this connection. + # This way, if we receive a TCP RST, we will not create a ComputeAPI + # object we won't use. + if not self._compute_rpcapi: + self._compute_rpcapi = compute_rpcapi.ComputeAPI() + return self._compute_rpcapi + def socket(self, *args, **kwargs): return websockify.WebSocketServer.socket(*args, **kwargs) diff --git a/nova/tests/unit/console/test_websocketproxy.py b/nova/tests/unit/console/test_websocketproxy.py index 539f5c5f556c..f4cac090144c 100644 --- a/nova/tests/unit/console/test_websocketproxy.py +++ b/nova/tests/unit/console/test_websocketproxy.py @@ -706,6 +706,16 @@ class NovaProxyRequestHandlerBaseTestCase(test.NoDBTestCase): self.wh.socket.assert_called_with('node1', 10000, connect=True) self.wh.do_proxy.assert_called_with('') + def test_tcp_rst_no_compute_rpcapi(self): + # Tests that we don't create a ComputeAPI object if we receive a + # TCP RST message. Simulate by raising the socket.err upon recv. + err = socket.error('[Errno 104] Connection reset by peer') + self.wh.socket.recv.side_effect = err + conn = mock.MagicMock() + address = mock.MagicMock() + self.wh.server.top_new_client(conn, address) + self.assertIsNone(self.wh._compute_rpcapi) + class NovaWebsocketSecurityProxyTestCase(test.NoDBTestCase):