Merge "Release port if failed to connect network"
This commit is contained in:
commit
aebab59ec0
|
@ -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()
|
||||
|
|
|
@ -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}]}
|
||||
|
|
Loading…
Reference in New Issue