summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Hall <brad@nicira.com>2011-12-12 18:24:26 +0000
committerBrad Hall <brad@nicira.com>2011-12-13 05:00:45 +0000
commit724e5e7a5bc065be239b3ededf0609de386c1d6f (patch)
treea58906db8731e1805e71808fb312bf013b4d1e00
parentff753cd608973f5d72a80aef0f9fb8a646fccc3f (diff)
Fix for bug 902175
Remove the gateway port when deleting the network (if it's the only one left), and kill dnsmasq if the network is deleted. Change-Id: If6b4798ddb4d21fe6c32ac20e6237494b799ecbd
-rw-r--r--nova/network/quantum/manager.py29
-rw-r--r--nova/network/quantum/quantum_connection.py14
-rw-r--r--nova/tests/test_quantum.py9
3 files changed, 46 insertions, 6 deletions
diff --git a/nova/network/quantum/manager.py b/nova/network/quantum/manager.py
index 9b6741e92..0ea2a5a50 100644
--- a/nova/network/quantum/manager.py
+++ b/nova/network/quantum/manager.py
@@ -137,6 +137,9 @@ class QuantumManager(manager.FlatManager):
return [{'uuid': quantum_net_id}]
+ def _generate_gw_dev(self, network_id):
+ return "gw-" + str(network_id[0:11])
+
def delete_network(self, context, fixed_range, uuid):
"""Lookup network by uuid, delete both the IPAM
subnet and the corresponding Quantum network.
@@ -149,11 +152,28 @@ class QuantumManager(manager.FlatManager):
if project_id is None:
# If nothing was found we default to this
project_id = FLAGS.quantum_default_tenant_id
+ q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
+ # Check for any attached ports on the network and fail the deletion if
+ # there is anything but the gateway port attached. If it is only the
+ # gateway port, unattach and delete it.
+ ports = self.q_conn.get_attached_ports(q_tenant_id, quantum_net_id)
+ if len(ports) > 1:
+ raise Exception(_("Network %s in use, cannot delete" %
+ (quantum_net_id)))
+ LOG.debug("Ports currently on network: %s" % ports)
+ for p in ports:
+ if p["attachment"].startswith("gw-"):
+ self.q_conn.detach_and_delete_port(q_tenant_id,
+ quantum_net_id,
+ p['port-id'])
+ # Now we can delete the network
+ self.q_conn.delete_network(q_tenant_id, quantum_net_id)
LOG.debug("Deleting network for tenant: %s" % project_id)
self.ipam.delete_subnets_by_net_id(context, quantum_net_id,
project_id)
- q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
- self.q_conn.delete_network(q_tenant_id, quantum_net_id)
+ # Get rid of dnsmasq
+ dev = self._generate_gw_dev(quantum_net_id)
+ self.driver.kill_dhcp(dev)
def allocate_for_instance(self, context, **kwargs):
"""Called by compute when it is creating a new VM.
@@ -495,7 +515,7 @@ class QuantumManager(manager.FlatManager):
network_ref['dhcp_start'] = IPAddress(n.first + 2)
network_ref['broadcast'] = IPAddress(n.broadcast)
network_ref['gateway'] = IPAddress(n.first + 1)
- dev = "gw-" + str(network_ref['uuid'][0:11])
+ dev = self._generate_gw_dev(network_ref['uuid'])
# And remove the dhcp mappings for the subnet
hosts = self.get_dhcp_hosts_text(context,
subnet['network_id'], project_id)
@@ -504,9 +524,6 @@ class QuantumManager(manager.FlatManager):
self.driver.kill_dhcp(dev)
self.driver.restart_dhcp(context, dev, network_ref)
- # TODO(bgh): if this is the last instance for the network
- # then we should actually just kill the dhcp server.
-
def validate_networks(self, context, networks):
"""Validates that this tenant has quantum networks with the associated
UUIDs. This is called by the 'os-create-server-ext' API extension
diff --git a/nova/network/quantum/quantum_connection.py b/nova/network/quantum/quantum_connection.py
index 91c98797c..36c1a1986 100644
--- a/nova/network/quantum/quantum_connection.py
+++ b/nova/network/quantum/quantum_connection.py
@@ -123,3 +123,17 @@ class QuantumClientConnection(object):
if attachment_id == port_get_resdict["attachment"]["id"]:
return port_id
return None
+
+ def get_attached_ports(self, tenant_id, network_id):
+ rv = []
+ port_list = self.client.list_ports(network_id, tenant=tenant_id)
+ for p in port_list["ports"]:
+ port_id = p["id"]
+ port = self.client.show_port_attachment(network_id,
+ port_id, tenant=tenant_id)
+ # Skip ports without an attachment
+ if "id" not in port["attachment"]:
+ continue
+ rv.append({'port-id': port_id, 'attachment':
+ port["attachment"]["id"]})
+ return rv
diff --git a/nova/tests/test_quantum.py b/nova/tests/test_quantum.py
index 174c512db..37a3ea465 100644
--- a/nova/tests/test_quantum.py
+++ b/nova/tests/test_quantum.py
@@ -104,6 +104,15 @@ class FakeQuantumClientConnection(object):
return port_id
return None
+ def get_attached_ports(self, tenant_id, net_id):
+ ports = []
+ for nid, n in self.nets.items():
+ if nid == net_id and n['tenant-id'] == tenant_id:
+ for port_id, p in n['ports'].items():
+ ports.append({'port-id': port_id,
+ 'attachment': p['attachment-id']})
+ return ports
+
def get_networks(self, tenant_id):
nets = []
for nid, n in self.nets.items():