Merge "Cache openstacksdk Connections to avoid leaking memory"

This commit is contained in:
Zuul 2024-06-13 09:02:31 +00:00 committed by Gerrit Code Review
commit 5092b4ada7
3 changed files with 35 additions and 10 deletions

View File

@ -18,6 +18,7 @@ import netaddr
import openstack import openstack
from openstack import exceptions as os_exc from openstack import exceptions as os_exc
from oslo_config import cfg from oslo_config import cfg
from oslo_utils import excutils
import tenacity import tenacity
from ironic_inspector.common.i18n import _ from ironic_inspector.common.i18n import _
@ -35,6 +36,7 @@ VALID_STATES = frozenset(['enroll', 'manageable', 'inspecting', 'inspect wait',
VALID_ACTIVE_STATES = frozenset(['active', 'rescue']) VALID_ACTIVE_STATES = frozenset(['active', 'rescue'])
_IRONIC_SESSION = None _IRONIC_SESSION = None
_CONNECTION = None
class NotFound(utils.Error): class NotFound(utils.Error):
@ -55,15 +57,29 @@ def _get_ironic_session():
def get_client(token=None): def get_client(token=None):
"""Get an ironic client connection.""" """Get an ironic client connection."""
global _CONNECTION
if _CONNECTION is None:
try:
session = _get_ironic_session() session = _get_ironic_session()
_CONNECTION = openstack.connection.Connection(
session=session, oslo_conf=CONF)
except Exception as exc:
LOG.error('Failed to create an openstack connection: %s', exc)
raise
try: try:
return openstack.connection.Connection( return _CONNECTION.baremetal
session=session, oslo_conf=CONF).baremetal
except Exception as exc: except Exception as exc:
LOG.error('Failed to establish a connection with ironic, ' with excutils.save_and_reraise_exception():
'reason: %s', exc) LOG.error('Failed to connect to Ironic: %s', exc)
raise # Force creating a new connection on the next retry
try:
_CONNECTION.close()
except Exception as exc2:
LOG.error('Unable to close an openstack connection, '
'a memory leak is possible. Error: %s', exc2)
_CONNECTION = None
def reset_ironic_session(): def reset_ironic_session():
@ -71,8 +87,8 @@ def reset_ironic_session():
Mostly useful for unit tests. Mostly useful for unit tests.
""" """
global _IRONIC_SESSION global _IRONIC_SESSION, _CONNECTION
_IRONIC_SESSION = None _CONNECTION = _IRONIC_SESSION = None
def get_ipmi_address(node): def get_ipmi_address(node):

View File

@ -32,8 +32,12 @@ class TestGetClientBase(base.BaseTest):
ir_utils.reset_ironic_session() ir_utils.reset_ironic_session()
def test_get_client(self, mock_connection, mock_session): def test_get_client(self, mock_connection, mock_session):
ir_utils.get_client() for i in range(3):
self.assertEqual(1, mock_session.call_count) cli = ir_utils.get_client()
self.assertIs(mock_connection.return_value.baremetal, cli)
mock_session.assert_called_once_with('ironic')
mock_connection.assert_called_once_with(
session=mock_session.return_value, oslo_conf=ir_utils.CONF)
class TestGetIpmiAddress(base.BaseTest): class TestGetIpmiAddress(base.BaseTest):

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fixes memory leak with openstacksdk 2.0 and newer. This version requires
connections to be explicitly closed, otherwise they stay in memory forever.