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)
downloadnova-724e5e7a5bc065be239b3ededf0609de386c1d6f.tar.gz
nova-724e5e7a5bc065be239b3ededf0609de386c1d6f.tar.xz
nova-724e5e7a5bc065be239b3ededf0609de386c1d6f.zip
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():