18416129 neutron-l3-agent should include dependency on ipfilter service
authorGirish Moodalbail <Girish.Moodalbail@oracle.COM>
Wed, 26 Mar 2014 23:18:55 -0700
changeset 1792 5cea652172c6
parent 1791 53d056cbdb63
child 1793 b253729db1c0
18416129 neutron-l3-agent should include dependency on ipfilter service 18407503 neutron net-delete doesn't delete subnets/ports with no VM associated
components/openstack/neutron/files/evs/plugin.py
components/openstack/neutron/files/neutron-l3-agent
components/openstack/neutron/files/neutron-l3-agent.xml
--- 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>