18416129 neutron-l3-agent should include dependency on ipfilter service
18407503 neutron net-delete doesn't delete subnets/ports with no VM associated
--- a/components/openstack/neutron/files/evs/plugin.py Wed Mar 26 11:47:09 2014 -0700
+++ b/components/openstack/neutron/files/evs/plugin.py Wed Mar 26 23:18:55 2014 -0700
@@ -487,16 +487,26 @@
def get_subnets_count(self, context, filters=None):
return len(self.get_ipnets(context, filters))
- def _release_subnet_dhcp_port(self, context, subnet):
+ def _release_subnet_dhcp_port(self, context, subnet, delete_network):
"""Release any dhcp port associated with the subnet"""
filters = dict(evs=subnet['network_id'])
portlist = self.get_ports(context, filters)
- if len(portlist) == 1:
+
+ if delete_network:
+ # One can delete a network if there is only one port that has a
+ # VNIC attached to it and that port happens to be a DHCP port.
+ ports_with_deviceid = [port for port in portlist
+ if port['device_id'] != '']
+ update_subnet = len(ports_with_deviceid) == 1
+ else:
+ # One can delete a subnet if there is only one port and that
+ # port happens to be a DHCP port.
+ update_subnet = len(portlist) == 1
+ if update_subnet:
# the lone port is a dhcp port created by dhcp agent
# it must be released before we can delete the subnet
- assert portlist[0]['device_owner'] == 'network:dhcp'
subnet_update = {'subnet': {'enable_dhcp': False},
- 'evs_rpccall_sync': True}
+ 'evs_rpccall_sync': True}
self.update_subnet(context, subnet['id'], subnet_update)
def delete_subnet(self, context, id):
@@ -515,7 +525,7 @@
# False that in turn sends a subnet.udpate notification. This
# results in DHCP agent releasing the port.
if subnet['enable_dhcp']:
- self._release_subnet_dhcp_port(context, subnet)
+ self._release_subnet_dhcp_port(context, subnet, False)
evs.removeIPnet(id)
except radcli.ObjectError as oe:
raise EVSControllerError(oe.get_payload().errmsg)
@@ -649,7 +659,7 @@
subnets = self.get_subnets(context, filters=filters)
dhcp_subnets = [s for s in subnets if s['enable_dhcp']]
for subnet in dhcp_subnets:
- self._release_subnet_dhcp_port(context, subnet)
+ self._release_subnet_dhcp_port(context, subnet, True)
self._evsc.deleteEVS(id, context.tenant_id)
except radcli.ObjectError as oe:
raise EVSControllerError(oe.get_payload().errmsg)
--- a/components/openstack/neutron/files/neutron-l3-agent Wed Mar 26 11:47:09 2014 -0700
+++ b/components/openstack/neutron/files/neutron-l3-agent Wed Mar 26 23:18:55 2014 -0700
@@ -19,6 +19,8 @@
import smf_include
+from subprocess import Popen, PIPE
+
def start():
# verify paths are valid
@@ -27,6 +29,31 @@
print '%s does not exist or is not readable' % f
return smf_include.SMF_EXIT_ERR_CONFIG
+ # System-wide forwarding (either ipv4 or ipv6 or both) must be enabled
+ # before neutron-l3-agent can be started.
+ cmd = ["/usr/sbin/ipadm", "show-prop", "-c", "-p", "forwarding",
+ "-o", "current", "ipv4"]
+ p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+ output, error = p.communicate()
+ if p.returncode != 0:
+ print "failed to determine if IPv4 forwarding is enabled or not"
+ return smf_include.SMF_EXIT_ERR_FATAL
+ v4fwding = "on" in output
+
+ cmd = ["/usr/sbin/ipadm", "show-prop", "-c", "-p", "forwarding",
+ "-o", "current", "ipv6"]
+ p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+ output, error = p.communicate()
+ if p.returncode != 0:
+ print "failed to determine if IPv6 forwarding is enabled or not"
+ return smf_include.SMF_EXIT_ERR_FATAL
+ v6fwding = "on" in output
+
+ if not any((v4fwding, v6fwding)):
+ print "System-wide IPv4 or IPv6 (or both) forwarding must be enabled " \
+ "before enabling %s" % os.getenv("SMF_FMRI")
+ return smf_include.SMF_EXIT_ERR_CONFIG
+
cmd = "/usr/lib/neutron/neutron-l3-agent --config-file %s " \
"--config-file %s" % tuple(sys.argv[2:4])
smf_include.smf_subprocess(cmd)
--- a/components/openstack/neutron/files/neutron-l3-agent.xml Wed Mar 26 11:47:09 2014 -0700
+++ b/components/openstack/neutron/files/neutron-l3-agent.xml Wed Mar 26 23:18:55 2014 -0700
@@ -30,6 +30,11 @@
<service_fmri value='svc:/milestone/multi-user:default' />
</dependency>
+ <dependency name='ipfilter' grouping='require_all' restart_on='error'
+ type='service'>
+ <service_fmri value='svc:/network/ipfilter:default' />
+ </dependency>
+
<exec_method timeout_seconds="60" type="method" name="start"
exec="/lib/svc/method/neutron-l3-agent %m %{config/config_path} %{config/l3_config_path}">
<method_context>