From 861f35b038431f64dbc29c64a230461efa41b60e Mon Sep 17 00:00:00 2001 From: shenxindi <shenxindi@cmss.chinamobile.com> Date: Wed, 8 Apr 2020 16:07:29 +0800 Subject: [PATCH] Release reservation when stoping the ironic-conductor service If a conductor hostname is changed while reservations are issued to a conductor with one hostname, such as 'hostname' and then the process is restarted with 'new_hostname', then the queries would not match the node and effectively the nodes would become inaccessible until the reservation is cleared. This patch clears the reservation when stoping the ironic-conductor service to avoid the nodes becoming inaccessible. Ref to: https://review.opendev.org/#/c/711765/ Change-Id: Id31cd30564ff26df0bbe4976ffe3f268b0dd3d7b --- ironic/conductor/base_manager.py | 2 ++ ironic/tests/unit/conductor/test_base_manager.py | 11 +++++++++++ ...eservation-on-conductor-stop-6ebbcdf92da57ca6.yaml | 6 ++++++ 3 files changed, 19 insertions(+) create mode 100644 releasenotes/notes/release-reservation-on-conductor-stop-6ebbcdf92da57ca6.yaml diff --git a/ironic/conductor/base_manager.py b/ironic/conductor/base_manager.py index 8ef568d830..6f071246a2 100644 --- a/ironic/conductor/base_manager.py +++ b/ironic/conductor/base_manager.py @@ -296,6 +296,8 @@ class BaseConductorManager(object): return self._shutdown = True self._keepalive_evt.set() + # clear all locks held by this conductor before deregistering + self.dbapi.clear_node_reservations_for_conductor(self.host) if deregister: try: # Inform the cluster that this conductor is shutting down. diff --git a/ironic/tests/unit/conductor/test_base_manager.py b/ironic/tests/unit/conductor/test_base_manager.py index f8ba77c3fa..49cacbff5b 100644 --- a/ironic/tests/unit/conductor/test_base_manager.py +++ b/ironic/tests/unit/conductor/test_base_manager.py @@ -64,6 +64,17 @@ class StartStopTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): node.refresh() self.assertIsNone(node.reservation) + def test_stop_clears_conductor_locks(self): + node = obj_utils.create_test_node(self.context, + reservation=self.hostname) + node.save() + self._start_service() + res = objects.Conductor.get_by_hostname(self.context, self.hostname) + self.assertEqual(self.hostname, res['hostname']) + self.service.del_host() + node.refresh() + self.assertIsNone(node.reservation) + def test_stop_unregisters_conductor(self): self._start_service() res = objects.Conductor.get_by_hostname(self.context, self.hostname) diff --git a/releasenotes/notes/release-reservation-on-conductor-stop-6ebbcdf92da57ca6.yaml b/releasenotes/notes/release-reservation-on-conductor-stop-6ebbcdf92da57ca6.yaml new file mode 100644 index 0000000000..1d583a88cb --- /dev/null +++ b/releasenotes/notes/release-reservation-on-conductor-stop-6ebbcdf92da57ca6.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes an issue where a node may be locked from changes if a conductor's + hostname case is changed before restarting the conductor service. clean + up the reservation once the conductor stopped.