Merge "Release port if failed to connect network"

This commit is contained in:
Zuul 2018-08-10 02:00:59 +00:00 committed by Gerrit Code Review
commit aebab59ec0
2 changed files with 56 additions and 3 deletions

View File

@ -272,7 +272,7 @@ class KuryrNetwork(network.Network):
if not container_id:
container_id = container.container_id
addresses, _ = self.create_or_update_port(
addresses, original_port = self.create_or_update_port(
container, network_name, requested_network, security_groups)
ipv4_address = None
@ -288,10 +288,42 @@ class KuryrNetwork(network.Network):
kwargs['ipv4_address'] = ipv4_address
if ipv6_address:
kwargs['ipv6_address'] = ipv6_address
self.docker.connect_container_to_network(
container_id, network_name, **kwargs)
try:
self.docker.connect_container_to_network(
container_id, network_name, **kwargs)
except exception.DockerError:
with excutils.save_and_reraise_exception():
self.do_port_cleanup(addresses, original_port)
return addresses
def do_port_cleanup(self, addresses, port):
preserve_flag = addresses[0].get('preserve_on_delete')
port_id = port.get('id')
if preserve_flag:
port_req_body = {'port': {'device_id': '', 'device_owner': ''}}
port_req_body['port'][BINDING_HOST_ID] = None
port_req_body['port']['mac_address'] = port.get('mac_address')
port_req_body['port'][BINDING_PROFILE] = \
port.get(BINDING_PROFILE, {})
try:
# Requires admin creds to set port bindings
admin_context = zun_context.get_admin_context()
neutron_api = neutron.NeutronAPI(admin_context)
neutron_api.update_port(port_id, port_req_body)
except exception.PortNotFound:
LOG.debug('Unable to unbind port %s as it no longer '
'exists.', port_id)
except Exception:
LOG.exception("Unable to clear device ID for port '%s'",
port_id)
else:
try:
self.neutron_api.delete_port(port_id)
except exception.PortNotFound:
LOG.debug('Unable to delete port %s as it no longer '
'exists.', port_id)
def disconnect_container_from_network(self, container, network_name,
neutron_network_id=None):
container_id = container.get_sandbox_id()

View File

@ -236,6 +236,27 @@ class KuryrNetworkTestCase(base.TestCase):
id='fake-port-id')['ports'][0]
self.assertEqual(container.uuid, new_port['device_id'])
@mock.patch('zun.network.neutron.NeutronAPI')
def test_connect_container_to_network_failed(self, mock_neutron_api_cls):
container = Container(self.context, **utils.get_test_container())
network_name = 'c02afe4e-8350-4263-8078'
requested_net = {'ipv4_address': '10.5.0.22',
'port': 'fake-port-id',
'preserve_on_delete': True}
mock_neutron_api_cls.return_value = self.network_api.neutron_api
old_port = self.network_api.neutron_api.list_ports(
id='fake-port-id')['ports'][0]
self.assertEqual('', old_port['device_id'])
self.network_api.docker = mock.MagicMock()
self.network_api.docker.connect_container_to_network = \
mock.Mock(side_effect=exception.DockerError)
self.assertRaises(exception.DockerError,
self.network_api.connect_container_to_network,
container, network_name, requested_net)
new_port = self.network_api.neutron_api.list_ports(
id='fake-port-id')['ports'][0]
self.assertEqual('', new_port['device_id'])
def test_disconnect_container_from_network(self):
addresses = {'fake-net-id': [{'port': 'fake-port-id',
'preserve_on_delete': False}]}