]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
NEC plugin support for dhcp network and router scheduling
authorAkihiro MOTOKI <motoki@da.jp.nec.com>
Thu, 28 Feb 2013 05:58:20 +0000 (14:58 +0900)
committerAkihiro MOTOKI <motoki@da.jp.nec.com>
Sat, 2 Mar 2013 10:39:28 +0000 (19:39 +0900)
blueprint quantum-scheduler

Change-Id: Icc1e4213cb6109ec82f4d438e277bd870c02729e

quantum/common/constants.py
quantum/db/migration/alembic_migrations/versions/4692d074d587_agent_scheduler.py
quantum/db/migration/alembic_migrations/versions/511471cc46b_agent_ext_model_supp.py
quantum/plugins/nec/agent/nec_quantum_agent.py
quantum/plugins/nec/common/config.py
quantum/plugins/nec/nec_plugin.py
quantum/tests/unit/nec/test_agent_scheduler.py [new file with mode: 0644]
quantum/tests/unit/nec/test_nec_plugin.py

index e1bc25f18c662fe66093dbe90405d3bad2916b58..966a3fd54c9a5300fc4d65d85deaad40d3a369c7 100644 (file)
@@ -59,6 +59,7 @@ TYPE_DICT = "dict"
 AGENT_TYPE_DHCP = 'DHCP agent'
 AGENT_TYPE_OVS = 'Open vSwitch agent'
 AGENT_TYPE_LINUXBRIDGE = 'Linux bridge agent'
+AGENT_TYPE_NEC = 'NEC plugin agent'
 AGENT_TYPE_L3 = 'L3 agent'
 L2_AGENT_TOPIC = 'N/A'
 
index 6594fc672351bd94dd0c98cd803d9670dd9e2312..0cfd44641d705c72fc00cb9883774e21d0c7436a 100644 (file)
@@ -33,6 +33,7 @@ migration_for_plugins = [
     'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
     'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
     'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
+    'quantum.plugins.nec.nec_plugin.NECPluginV2',
 ]
 
 from alembic import op
index 7410b42010cbbdcdc90c1131ba21c6da37929dfb..0ee357066ed9fe8ec9f79bb05f33ea85c99e283e 100644 (file)
@@ -33,6 +33,7 @@ migration_for_plugins = [
     'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
     'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
     'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
+    'quantum.plugins.nec.nec_plugin.NECPluginV2',
 ]
 
 from alembic import op
index a170e0db6cb4e986dfb037602c5350fed976a0b9..0559be46ad79bfd700288cb36d0ad10728ca272b 100755 (executable)
@@ -32,10 +32,12 @@ from quantum.agent.linux import ovs_lib
 from quantum.agent import rpc as agent_rpc
 from quantum.agent import securitygroups_rpc as sg_rpc
 from quantum.common import config as logging_config
+from quantum.common import constants as q_const
 from quantum.common import topics
 from quantum import context as q_context
 from quantum.extensions import securitygroup as ext_sg
 from quantum.openstack.common import log as logging
+from quantum.openstack.common import loopingcall
 from quantum.openstack.common.rpc import dispatcher
 from quantum.openstack.common.rpc import proxy
 from quantum.plugins.nec.common import config
@@ -124,8 +126,18 @@ class NECQuantumAgent(object):
         '''
         self.int_br = ovs_lib.OVSBridge(integ_br, root_helper)
         self.polling_interval = polling_interval
+        self.cur_ports = []
 
         self.datapath_id = "0x%s" % self.int_br.get_datapath_id()
+
+        self.agent_state = {
+            'binary': 'quantum-nec-agent',
+            'host': config.CONF.host,
+            'topic': q_const.L2_AGENT_TOPIC,
+            'configurations': {},
+            'agent_type': q_const.AGENT_TYPE_NEC,
+            'start_flag': True}
+
         self.setup_rpc()
 
     def setup_rpc(self):
@@ -137,6 +149,7 @@ class NECQuantumAgent(object):
         self.context = q_context.get_admin_context_without_session()
 
         self.plugin_rpc = NECPluginApi(topics.PLUGIN)
+        self.state_rpc = agent_rpc.PluginReportStateAPI(topics.PLUGIN)
         self.sg_agent = SecurityGroupAgentRpc(self.context)
 
         # RPC network init
@@ -154,6 +167,22 @@ class NECQuantumAgent(object):
                                                      self.topic,
                                                      consumers)
 
+        report_interval = config.CONF.AGENT.report_interval
+        if report_interval:
+            heartbeat = loopingcall.LoopingCall(self._report_state)
+            heartbeat.start(interval=report_interval)
+
+    def _report_state(self):
+        try:
+            # How many devices are likely used by a VM
+            num_devices = len(self.cur_ports)
+            self.agent_state['configurations']['devices'] = num_devices
+            self.state_rpc.report_state(self.context,
+                                        self.agent_state)
+            self.agent_state.pop('start_flag', None)
+        except Exception:
+            LOG.exception(_("Failed reporting state!"))
+
     def _vif_port_to_port_info(self, vif_port):
         return dict(id=vif_port.vif_id, port_no=vif_port.ofport,
                     mac=vif_port.vif_mac)
@@ -167,7 +196,6 @@ class NECQuantumAgent(object):
 
     def daemon_loop(self):
         """Main processing loop for NEC Plugin Agent."""
-        old_ports = []
         while True:
             new_ports = []
 
@@ -175,12 +203,12 @@ class NECQuantumAgent(object):
             for vif_port in self.int_br.get_vif_ports():
                 port_id = vif_port.vif_id
                 new_ports.append(port_id)
-                if port_id not in old_ports:
+                if port_id not in self.cur_ports:
                     port_info = self._vif_port_to_port_info(vif_port)
                     port_added.append(port_info)
 
             port_removed = []
-            for port_id in old_ports:
+            for port_id in self.cur_ports:
                 if port_id not in new_ports:
                     port_removed.append(port_id)
 
@@ -192,7 +220,7 @@ class NECQuantumAgent(object):
             else:
                 LOG.debug(_("No port changed."))
 
-            old_ports = new_ports
+            self.cur_ports = new_ports
             time.sleep(self.polling_interval)
 
 
index d2de49866b5aef51cfb0e37e230df72341b7deb2..f6fa30c6d2a0f7c630830ec644ce58f274e741a1 100644 (file)
@@ -20,6 +20,7 @@ from oslo.config import cfg
 from quantum.agent.common import config
 # import rpc config options
 from quantum.openstack.common import rpc
+from quantum import scheduler
 
 
 ovs_opts = [
@@ -54,7 +55,9 @@ ofc_opts = [
 cfg.CONF.register_opts(ovs_opts, "OVS")
 cfg.CONF.register_opts(agent_opts, "AGENT")
 cfg.CONF.register_opts(ofc_opts, "OFC")
+config.register_agent_state_opts_helper(cfg.CONF)
 config.register_root_helper(cfg.CONF)
+cfg.CONF.register_opts(scheduler.AGENTS_SCHEDULER_OPTS)
 
 # shortcuts
 CONF = cfg.CONF
index 518b1ee27ef36c3846d83dfcb980e87ac0b974a1..e662f80c5c43d424af04a98cbd00f3870bdfaac5 100644 (file)
 # @author: Akihiro MOTOKI
 
 from quantum.agent import securitygroups_rpc as sg_rpc
+from quantum.api.rpc.agentnotifiers import dhcp_rpc_agent_api
+from quantum.api.rpc.agentnotifiers import l3_rpc_agent_api
 from quantum.common import constants as q_const
 from quantum.common import exceptions as q_exc
 from quantum.common import rpc as q_rpc
 from quantum.common import topics
 from quantum import context
+from quantum.db import agents_db
+from quantum.db import agentschedulers_db
 from quantum.db import dhcp_rpc_base
 from quantum.db import extraroute_db
 from quantum.db import l3_rpc_base
@@ -30,6 +34,7 @@ from quantum.db import quota_db
 from quantum.db import securitygroups_rpc_base as sg_db_rpc
 from quantum.extensions import portbindings
 from quantum.extensions import securitygroup as ext_sg
+from quantum.openstack.common import importutils
 from quantum.openstack.common import log as logging
 from quantum.openstack.common import rpc
 from quantum.openstack.common.rpc import proxy
@@ -60,7 +65,8 @@ class OperationalStatus:
 
 class NECPluginV2(nec_plugin_base.NECPluginV2Base,
                   extraroute_db.ExtraRoute_db_mixin,
-                  sg_db_rpc.SecurityGroupServerRpcMixin):
+                  sg_db_rpc.SecurityGroupServerRpcMixin,
+                  agentschedulers_db.AgentSchedulerDbMixin):
     """NECPluginV2 controls an OpenFlow Controller.
 
     The Quantum NECPluginV2 maps L2 logical networks to L2 virtualized networks
@@ -75,7 +81,9 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
     """
 
     supported_extension_aliases = ["router", "quotas", "binding",
-                                   "security-group", "extraroute"]
+                                   "security-group", "extraroute",
+                                   "agent", "agent_scheduler",
+                                   ]
 
     binding_view = "extension:port_binding:view"
     binding_set = "extension:port_binding:set"
@@ -97,17 +105,24 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
 
         self.setup_rpc()
 
+        self.network_scheduler = importutils.import_object(
+            config.CONF.network_scheduler_driver)
+        self.router_scheduler = importutils.import_object(
+            config.CONF.router_scheduler_driver)
+
     def setup_rpc(self):
         self.topic = topics.PLUGIN
         self.conn = rpc.create_connection(new=True)
         self.notifier = NECPluginV2AgentNotifierApi(topics.AGENT)
+        self.dhcp_agent_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
+        self.l3_agent_notifier = l3_rpc_agent_api.L3AgentNotify
 
-        self.callback_nec = NECPluginV2RPCCallbacks(self)
-        self.callback_dhcp = DhcpRpcCallback()
-        self.callback_l3 = L3RpcCallback()
+        # NOTE: callback_sg is referred to from the sg unit test.
         self.callback_sg = SecurityGroupServerRpcCallback()
-        callbacks = [self.callback_nec, self.callback_dhcp,
-                     self.callback_l3, self.callback_sg]
+        callbacks = [NECPluginV2RPCCallbacks(self),
+                     DhcpRpcCallback(), L3RpcCallback(),
+                     self.callback_sg,
+                     agents_db.AgentExtRpcCallback()]
         self.dispatcher = q_rpc.PluginRpcDispatcher(callbacks)
         self.conn.create_consumer(self.topic, self.dispatcher, fanout=False)
         # Consume from all consumers in a thread
diff --git a/quantum/tests/unit/nec/test_agent_scheduler.py b/quantum/tests/unit/nec/test_agent_scheduler.py
new file mode 100644 (file)
index 0000000..9356cb0
--- /dev/null
@@ -0,0 +1,34 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 NEC Corporation.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from quantum.tests.unit.openvswitch import test_agent_scheduler
+from quantum.tests.unit.nec import test_nec_plugin
+
+
+class NecAgentSchedulerTestCase(
+    test_agent_scheduler.OvsAgentSchedulerTestCase):
+    plugin_str = test_nec_plugin.PLUGIN_NAME
+
+
+class NecDhcpAgentNotifierTestCase(
+    test_agent_scheduler.OvsDhcpAgentNotifierTestCase):
+    plugin_str = test_nec_plugin.PLUGIN_NAME
+
+
+class NecL3AgentNotifierTestCase(
+    test_agent_scheduler.OvsL3AgentNotifierTestCase):
+    plugin_str = test_nec_plugin.PLUGIN_NAME
index 747583ad354f42b1922d8eeee785d3732ac9616e..080a5cc814a73a5adc54c39f7fe445dc1da8abd6 100644 (file)
@@ -18,9 +18,12 @@ from quantum.tests.unit import _test_extension_portbindings as test_bindings
 from quantum.tests.unit import test_db_plugin as test_plugin
 
 
+PLUGIN_NAME = 'quantum.plugins.nec.nec_plugin.NECPluginV2'
+
+
 class NecPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase):
 
-    _plugin_name = 'quantum.plugins.nec.nec_plugin.NECPluginV2'
+    _plugin_name = PLUGIN_NAME
 
     def setUp(self):
         super(NecPluginV2TestCase, self).setUp(self._plugin_name)