Merge "Network: enable instance deletion when dhcp release fails"

This commit is contained in:
Jenkins 2014-09-18 00:49:35 +00:00 committed by Gerrit Code Review
commit 5becdc168a
4 changed files with 63 additions and 3 deletions

View File

@ -586,6 +586,10 @@ class NetworkDuplicated(Invalid):
msg_fmt = _("Network %(network_id)s is duplicated.")
class NetworkDhcpReleaseFailed(NovaException):
msg_fmt = _("Failed to release IP %(address)s with MAC %(mac_address)s")
class NetworkInUse(NovaException):
msg_fmt = _("Network %(network_id)s is still in use.")

View File

@ -992,7 +992,12 @@ def get_dhcp_opts(context, network_ref, fixedips):
def release_dhcp(dev, address, mac_address):
utils.execute('dhcp_release', dev, address, mac_address, run_as_root=True)
try:
utils.execute('dhcp_release', dev, address, mac_address,
run_as_root=True)
except processutils.ProcessExecutionError:
raise exception.NetworkDhcpReleaseFailed(address=address,
mac_address=mac_address)
def update_dhcp(context, dev, network_ref):

View File

@ -39,7 +39,7 @@ from oslo import messaging
from nova import conductor
from nova import context
from nova import exception
from nova.i18n import _
from nova.i18n import _, _LE
from nova import ipv6
from nova import manager
from nova.network import api as network_api
@ -1026,7 +1026,14 @@ class NetworkManager(manager.Manager):
self._teardown_network_on_host(context, network)
# NOTE(vish): This forces a packet so that the release_fixed_ip
# callback will get called by nova-dhcpbridge.
self.driver.release_dhcp(dev, address, vif.address)
try:
self.driver.release_dhcp(dev, address, vif.address)
except exception.NetworkDhcpReleaseFailed:
LOG.error(_LE("Error releasing DHCP for IP %(address)s "
"with MAC %(mac_address)s"),
{'address': address,
'mac_address': vif.address},
instance=instance)
# NOTE(yufang521247): This is probably a failed dhcp fixed ip.
# DHCPRELEASE packet sent to dnsmasq would not trigger

View File

@ -1668,6 +1668,50 @@ class VlanNetworkTestCase(test.TestCase):
fixed_update.assert_called_once_with(context1, fix_addr.address,
{'allocated': False})
@mock.patch('nova.db.fixed_ip_get_by_address')
@mock.patch('nova.db.network_get')
@mock.patch('nova.db.fixed_ip_update')
def test_deallocate_fixed_with_dhcp_exception(self, fixed_update, net_get,
fixed_get):
net_get.return_value = dict(test_network.fake_network,
**networks[1])
def vif_get(_context, _vif_id):
return vifs[0]
with contextlib.nested(
mock.patch.object(db, 'virtual_interface_get', vif_get),
mock.patch.object(
utils, 'execute',
side_effect=processutils.ProcessExecutionError()),
) as (_vif_get, _execute):
context1 = context.RequestContext('user', 'project1')
instance = db.instance_create(context1,
{'project_id': 'project1'})
elevated = context1.elevated()
fix_addr = db.fixed_ip_associate_pool(elevated, 1,
instance['uuid'])
fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
address=fix_addr.address,
instance_uuid=instance.uuid,
allocated=True,
virtual_interface_id=3,
network=dict(
test_network.fake_network,
**networks[1]))
self.flags(force_dhcp_release=True)
self.network.deallocate_fixed_ip(context1, fix_addr.address,
'fake')
fixed_update.assert_called_once_with(context1, fix_addr.address,
{'allocated': False})
_execute.assert_called_once_with('dhcp_release',
networks[1]['bridge'],
fix_addr.address,
'DE:AD:BE:EF:00:00',
run_as_root=True)
def test_deallocate_fixed_deleted(self):
# Verify doesn't deallocate deleted fixed_ip from deleted network.