From 222bd1030910876554adbeca0e1c614f8b74d24b Mon Sep 17 00:00:00 2001 From: Vladyslav Drok Date: Thu, 28 Jul 2016 17:24:39 +0300 Subject: [PATCH] Clean up provision ports when reattempting deploy If the provisioning fails at boot.prepare_ramdisk stage, as after that provision ports are not cleaned up, when retrying, neutron network driver won't be able to create ports, complaining about duplicated MAC addresses. The only way out of this is doing set-provision-state deleted and then active again, but then instance_info will be lost, which is inconvenient in case of standalone usage. Closes-bug: #1607394 Change-Id: Ifacbeb307619a9a7883ab1ac8fce3ff07e46787c --- ironic/drivers/modules/network/neutron.py | 3 +++ ironic/tests/unit/drivers/modules/network/test_neutron.py | 7 ++++++- ...anup-provision-ports-before-retry-ec3c89c193766d70.yaml | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/cleanup-provision-ports-before-retry-ec3c89c193766d70.yaml diff --git a/ironic/drivers/modules/network/neutron.py b/ironic/drivers/modules/network/neutron.py index 5b8daaf5d5..ba14565a56 100644 --- a/ironic/drivers/modules/network/neutron.py +++ b/ironic/drivers/modules/network/neutron.py @@ -58,6 +58,9 @@ class NeutronNetwork(base.NetworkInterface): :param task: A TaskManager instance. :raises: NetworkError """ + # If we have left over ports from a previous provision attempt, remove + # them + neutron.rollback_ports(task, CONF.neutron.provisioning_network_uuid) LOG.info(_LI('Adding provisioning network to node %s'), task.node.uuid) vifs = neutron.add_ports_to_network( diff --git a/ironic/tests/unit/drivers/modules/network/test_neutron.py b/ironic/tests/unit/drivers/modules/network/test_neutron.py index 08d89c24d3..801df52feb 100644 --- a/ironic/tests/unit/drivers/modules/network/test_neutron.py +++ b/ironic/tests/unit/drivers/modules/network/test_neutron.py @@ -52,11 +52,16 @@ class NeutronInterfaceTestCase(db_base.DbTestCase): self.config(cleaning_network_uuid='asdf', group='neutron') self.assertRaises(exception.DriverLoadError, neutron.NeutronNetwork) + @mock.patch.object(neutron_common, 'rollback_ports') @mock.patch.object(neutron_common, 'add_ports_to_network') - def test_add_provisioning_network(self, add_ports_mock): + def test_add_provisioning_network(self, add_ports_mock, rollback_mock): + self.port.internal_info = {'provisioning_vif_port_id': 'vif-port-id'} + self.port.save() add_ports_mock.return_value = {self.port.uuid: self.neutron_port['id']} with task_manager.acquire(self.context, self.node.id) as task: self.interface.add_provisioning_network(task) + rollback_mock.assert_called_once_with( + task, CONF.neutron.provisioning_network_uuid) add_ports_mock.assert_called_once_with( task, CONF.neutron.provisioning_network_uuid) self.port.refresh() diff --git a/releasenotes/notes/cleanup-provision-ports-before-retry-ec3c89c193766d70.yaml b/releasenotes/notes/cleanup-provision-ports-before-retry-ec3c89c193766d70.yaml new file mode 100644 index 0000000000..0c20ed0c2b --- /dev/null +++ b/releasenotes/notes/cleanup-provision-ports-before-retry-ec3c89c193766d70.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - Fixes an issue with neutron network interface, that could lead + to inability to retry the deployment in case of failure on + boot interface's prepare_ramdisk stage. +