Delete ports when nova fails to boot VM
This patch adds some code to the exception handler in the instance
manager's boot method to cleanup any created ports if nova fails to boot
the instance.
Change-Id: I459ccd82a367fcd41d4a894b7231c797dc5100e9
Closes-Bug: #1516152
(cherry picked from commit 7de346fd49
)
This commit is contained in:
parent
7211574959
commit
53e0266387
|
@ -110,6 +110,13 @@ class BaseDriver(object):
|
|||
|
||||
return _make_ports
|
||||
|
||||
def delete_ports(self, worker_context):
|
||||
"""Delete all created ports.
|
||||
|
||||
:param worker_context:
|
||||
:returns: None
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def pre_populate_hook():
|
||||
"""called in populate.py durring driver loading loop.
|
||||
|
@ -120,7 +127,7 @@ class BaseDriver(object):
|
|||
"""pre-plug hook
|
||||
|
||||
:param worker_context:
|
||||
:returs: None
|
||||
:returns: None
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -202,6 +202,16 @@ class Router(BaseDriver):
|
|||
|
||||
return _make_ports
|
||||
|
||||
def delete_ports(self, worker_context):
|
||||
"""Delete all ports.
|
||||
|
||||
:param worker_context:
|
||||
:returns: None
|
||||
|
||||
"""
|
||||
worker_context.neutron.delete_vrrp_port(self.id)
|
||||
worker_context.neutron.delete_vrrp_port(self.id, label='MGT')
|
||||
|
||||
@staticmethod
|
||||
def pre_populate_hook():
|
||||
"""Fetch the existing routers from neutrom then and returns list back
|
||||
|
|
|
@ -246,7 +246,7 @@ class InstanceManager(object):
|
|||
return
|
||||
except:
|
||||
self.log.exception(_LE('Instance failed to start boot'))
|
||||
return
|
||||
self.driver.delete_ports(worker_context)
|
||||
else:
|
||||
# We have successfully started a (re)boot attempt so
|
||||
# record the timestamp so we can report how long it takes.
|
||||
|
|
|
@ -151,6 +151,15 @@ class RouterDriverTest(base.RugTestBase):
|
|||
]
|
||||
self.assertEqual(res, ('fake_mgt_port', expected_instance_ports))
|
||||
|
||||
def test_delete_ports(self):
|
||||
rtr = self._init_driver()
|
||||
fake_router_obj = fakes.fake_router()
|
||||
rtr._router = fake_router_obj
|
||||
rtr.delete_ports(self.ctx)
|
||||
expected_ports = [mock.call(rtr.id),
|
||||
mock.call(rtr.id, label='MGT')]
|
||||
self.ctx.neutron.delete_vrrp_port.assert_has_calls(expected_ports)
|
||||
|
||||
@mock.patch('akanda.rug.api.neutron.Neutron')
|
||||
def test_pre_populate_retry_loop(self, mocked_neutron_api):
|
||||
neutron_client = mock.Mock()
|
||||
|
|
|
@ -119,6 +119,7 @@ def fake_driver(resource_id=None):
|
|||
fake_driver.name = 'ak-FakeDriver-fake_resource_id'
|
||||
fake_driver.image_uuid = 'fake_image_uuid'
|
||||
fake_driver.make_ports.return_value = 'fake_ports_callback'
|
||||
fake_driver.delete_ports.return_value = 'fake_delete_ports_callback'
|
||||
return fake_driver
|
||||
|
||||
|
||||
|
|
|
@ -360,6 +360,7 @@ class TestInstanceManager(base.RugTestBase):
|
|||
instance = mock.sentinel.instance
|
||||
self.ctx.neutron.get_router_detail.return_value = rtr
|
||||
self.ctx.nova_client.get_instance.return_value = instance
|
||||
self.ctx.nova_client.boot_instance.side_effect = RuntimeError
|
||||
rtr.id = 'ROUTER1'
|
||||
instance.id = 'INSTANCE1'
|
||||
rtr.management_port = management_port
|
||||
|
@ -368,7 +369,6 @@ class TestInstanceManager(base.RugTestBase):
|
|||
rtr.ports.__iter__.return_value = [management_port, external_port,
|
||||
internal_port]
|
||||
self.instance_mgr.boot(self.ctx)
|
||||
self.assertEqual(self.instance_mgr.state, states.BOOTING)
|
||||
self.ctx.nova_client.boot_instance.assert_called_once_with(
|
||||
resource_type=self.fake_driver.RESOURCE_NAME,
|
||||
prev_instance_info=self.INSTANCE_INFO,
|
||||
|
@ -376,6 +376,7 @@ class TestInstanceManager(base.RugTestBase):
|
|||
image_uuid=self.fake_driver.image_uuid,
|
||||
flavor=self.fake_driver.flavor,
|
||||
make_ports_callback='fake_ports_callback')
|
||||
self.instance_mgr.driver.delete_ports.assert_called_once_with(self.ctx)
|
||||
|
||||
def test_boot_check_up(self):
|
||||
with mock.patch.object(
|
||||
|
|
Loading…
Reference in New Issue