On Tue, May 14, 2013 at 11:25:20AM +0900, FUJITA Tomonori wrote: > On Tue, 14 May 2013 11:13:33 +0900 > Isaku Yamahata <[email protected]> wrote: > > > This patch fixes the following exception. > > > > ryu/controller/ofp_event.py: update > > cd /opt/stack/ryu && /opt/stack/ryu/bin/ryu-mana ^Mger --config-file > > /etc/ryu/ryu.conf || touch "/opt/stack/status/stack/ryu.failur ^Me" > >> Traceback (most recent call last): > >> File "/opt/stack/ryu/bin/ryu-manager", line 41, in <module> > >> from ryu.base.app_manager import AppManager > >> File "/opt/stack/ryu/ryu/base/app_manager.py", line 22, in <module> > >> from ryu.controller.handler import register_instance > >> File "/opt/stack/ryu/ryu/controller/handler.py", line 20, in <module> > >> from ryu.controller import ofp_event > >> File "/opt/stack/ryu/ryu/controller/ofp_event.py", line 69, in <module> > >> for ofp_mods in ofproto.get_ofp_module(): > >> TypeError: get_ofp_module() takes exactly 1 argument (0 given) > > > > Reported-by: YAMAMOTO Takashi <[email protected]> > > Signed-off-by: Isaku Yamahata <[email protected]> > > --- > > ryu/controller/ofp_event.py | 7 +++---- > > ryu/ofproto/__init__.py | 7 +++++++ > > 2 files changed, 10 insertions(+), 4 deletions(-) > > Tried our jeknins testings this time?
Right now I'm tracking down upstream issue. Here is the WIP patches, but jenkins doesn't finish yet. commit cf63eb177174a0f84f55e1c47350fadf2a4f5b44 Author: Isaku Yamahata <[email protected]> Date: Tue May 14 14:39:49 2013 +0900 plugin/ryu: support AgentExtRpcCallback This patch fixes the following exception. > 2013-05-14 03:39:53 ERROR [quantum.openstack.common.rpc.amqp] Exception during message handling > Traceback (most recent call last): > File "/opt/stack/quantum/quantum/openstack/common/rpc/amqp.py", line 433, in _process_data > **args) > File "/opt/stack/quantum/quantum/common/rpc.py", line 44, in dispatch > quantum_ctxt, version, method, namespace, **kwargs) > File "/opt/stack/quantum/quantum/openstack/common/rpc/dispatcher.py", line 151, in dispatch > raise AttributeError("No such RPC function '%s'" % method) > AttributeError: No such RPC function 'report_state' Signed-off-by: Isaku Yamahata <[email protected]> diff --git a/quantum/common/constants.py b/quantum/common/constants.py index 9557b97..d7e1590 100644 --- a/quantum/common/constants.py +++ b/quantum/common/constants.py @@ -60,6 +60,7 @@ 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_RYU = 'Ryu plugin agent' AGENT_TYPE_L3 = 'L3 agent' L2_AGENT_TOPIC = 'N/A' diff --git a/quantum/db/migration/alembic_migrations/versions/4692d074d587_agent_scheduler.py b/quantum/db/migration/alembic_migrations/versions/4692d074d587_agent_scheduler.py index 0685872..1f55533 100644 --- a/quantum/db/migration/alembic_migrations/versions/4692d074d587_agent_scheduler.py +++ b/quantum/db/migration/alembic_migrations/versions/4692d074d587_agent_scheduler.py @@ -35,6 +35,7 @@ migration_for_plugins = [ 'quantum.plugins.nicira.QuantumPlugin.NvpPluginV2', 'quantum.plugins.nec.nec_plugin.NECPluginV2', 'quantum.plugins.brocade.QuantumPlugin.BrocadePluginV2', + 'quantum.plugins.ryu.ryu_quantum_plugin.RyuQuantumPluginV2', ] from alembic import op diff --git a/quantum/db/migration/alembic_migrations/versions/511471cc46b_agent_ext_model_supp.py b/quantum/db/migration/alembic_migrations/versions/511471cc46b_agent_ext_model_supp.py index 1968690..0d55c12 100644 --- a/quantum/db/migration/alembic_migrations/versions/511471cc46b_agent_ext_model_supp.py +++ b/quantum/db/migration/alembic_migrations/versions/511471cc46b_agent_ext_model_supp.py @@ -35,6 +35,7 @@ migration_for_plugins = [ 'quantum.plugins.nicira.QuantumPlugin.NvpPluginV2', 'quantum.plugins.nec.nec_plugin.NECPluginV2', 'quantum.plugins.brocade.QuantumPlugin.BrocadePluginV2', + 'quantum.plugins.ryu.ryu_quantum_plugin.RyuQuantumPluginV2', ] from alembic import op diff --git a/quantum/plugins/ryu/agent/ryu_quantum_agent.py b/quantum/plugins/ryu/agent/ryu_quantum_agent.py index 7b5a5a4..902b558 100755 --- a/quantum/plugins/ryu/agent/ryu_quantum_agent.py +++ b/quantum/plugins/ryu/agent/ryu_quantum_agent.py @@ -37,11 +37,13 @@ from quantum.agent.linux.ovs_lib import VifPort 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 exceptions as q_exc 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 +from quantum.openstack.common import loopingcall from quantum.openstack.common.rpc import dispatcher from quantum.plugins.ryu.common import config # noqa @@ -177,6 +179,13 @@ class OVSQuantumOFPRyuAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin): polling_interval, root_helper): super(OVSQuantumOFPRyuAgent, self).__init__() self.polling_interval = polling_interval + self.agent_state = { + 'binary': 'quantum-ryu-agent', + 'host': cfg.CONF.host, + 'topic': q_const.L2_AGENT_TOPIC, + 'configurations': {}, + 'agent_type': q_const.AGENT_TYPE_RYU, + 'start_flag': True} self._setup_rpc() self.sg_agent = RyuSecurityGroupAgent(self.context, self.plugin_rpc, @@ -184,9 +193,22 @@ class OVSQuantumOFPRyuAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin): self._setup_integration_br(root_helper, integ_br, tunnel_ip, ovsdb_port, ovsdb_ip) + def _report_state(self): + try: + # How many devices are likely used by a VM + ports = self.int_br.get_vif_port_set() + num_devices = len(ports) + self.agent_state.get('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 _setup_rpc(self): self.topic = topics.AGENT self.plugin_rpc = RyuPluginApi(topics.PLUGIN) + self.state_rpc = agent_rpc.PluginReportStateAPI(topics.PLUGIN) self.context = q_context.get_admin_context_without_session() self.dispatcher = self._create_rpc_dispatcher() consumers = [[topics.PORT, topics.UPDATE], @@ -195,6 +217,12 @@ class OVSQuantumOFPRyuAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin): self.topic, consumers) + report_interval = cfg.CONF.AGENT.report_interval + if report_interval: + heartbeat = loopingcall.FixedIntervalLoopingCall( + self._report_state) + heartbeat.start(interval=report_interval) + def _create_rpc_dispatcher(self): return dispatcher.RpcDispatcher([self]) diff --git a/quantum/plugins/ryu/common/config.py b/quantum/plugins/ryu/common/config.py index fec0ead..fa5c703 100644 --- a/quantum/plugins/ryu/common/config.py +++ b/quantum/plugins/ryu/common/config.py @@ -17,6 +17,7 @@ from oslo.config import cfg from quantum.agent.common import config +from quantum import scheduler ovs_opts = [ @@ -49,4 +50,6 @@ agent_opts = [ cfg.CONF.register_opts(ovs_opts, "OVS") cfg.CONF.register_opts(agent_opts, "AGENT") +cfg.CONF.register_opts(scheduler.AGENTS_SCHEDULER_OPTS) +config.register_agent_state_opts_helper(cfg.CONF) config.register_root_helper(cfg.CONF) diff --git a/quantum/plugins/ryu/ryu_quantum_plugin.py b/quantum/plugins/ryu/ryu_quantum_plugin.py index 74468cf..cc544c3 100644 --- a/quantum/plugins/ryu/ryu_quantum_plugin.py +++ b/quantum/plugins/ryu/ryu_quantum_plugin.py @@ -21,10 +21,14 @@ from ryu.app import client from ryu.app import rest_nw_id 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.db import agents_db +from quantum.db import agentschedulers_db from quantum.db import api as db from quantum.db import db_base_plugin_v2 from quantum.db import dhcp_rpc_base @@ -32,6 +36,7 @@ from quantum.db import extraroute_db from quantum.db import l3_rpc_base from quantum.db import models_v2 from quantum.db import securitygroups_rpc_base as sg_db_rpc +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 @@ -52,7 +57,8 @@ class RyuRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin, self.ofp_rest_api_addr = ofp_rest_api_addr def create_rpc_dispatcher(self): - return q_rpc.PluginRpcDispatcher([self]) + return q_rpc.PluginRpcDispatcher([self, + agents_db.AgentExtRpcCallback()]) def get_ofp_rest_api(self, context, **kwargs): LOG.debug(_("get_ofp_rest_api: %s"), self.ofp_rest_api_addr) @@ -86,9 +92,11 @@ class AgentNotifierApi(proxy.RpcProxy, class RyuQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2, extraroute_db.ExtraRoute_db_mixin, - sg_db_rpc.SecurityGroupServerRpcMixin): + sg_db_rpc.SecurityGroupServerRpcMixin, + agentschedulers_db.AgentSchedulerDbMixin): - _supported_extension_aliases = ["router", "extraroute", "security-group"] + _supported_extension_aliases = ["router", "extraroute", "security-group", + "agent", "agent_scheduler"] @property def supported_extension_aliases(self): @@ -113,6 +121,10 @@ class RyuQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2, if nw_id != rest_nw_id.NW_ID_UNKNOWN: self.client.update_network(nw_id) self._setup_rpc() + self.network_scheduler = importutils.import_object( + cfg.CONF.network_scheduler_driver) + self.router_scheduler = importutils.import_object( + cfg.CONF.router_scheduler_driver) # register known all network list on startup self._create_all_tenant_network() @@ -120,6 +132,9 @@ class RyuQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2, def _setup_rpc(self): self.conn = rpc.create_connection(new=True) self.notifier = AgentNotifierApi(topics.AGENT) + self.dhcp_agent_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI() + self.l3_agent_notifier = l3_rpc_agent_api.L3AgentNotify + self.callbacks = RyuRpcCallbacks(self.ofp_api_host) self.dispatcher = self.callbacks.create_rpc_dispatcher() self.conn.create_consumer(topics.PLUGIN, self.dispatcher, fanout=False) diff --git a/quantum/tests/unit/ryu/test_agent_scheduler.py b/quantum/tests/unit/ryu/test_agent_scheduler.py new file mode 100644 index 0000000..a27546f --- /dev/null +++ b/quantum/tests/unit/ryu/test_agent_scheduler.py @@ -0,0 +1,39 @@ +# Copyright 2013 Isaku Yamahata <yamahata at private email ne jp> +# +# 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.ryu import test_ryu_plugin +from quantum.tests.unit.openvswitch import test_agent_scheduler +from quantum.tests.unit.ryu import fake_ryu + + +class FakeRyu(object): + def setUp(self): + self.fake_ryu = fake_ryu.patch_fake_ryu_client().start() + super(FakeRyu, self).setUp() + + +class RyuAgentSchedulerTestCase( + FakeRyu, test_agent_scheduler.OvsAgentSchedulerTestCase): + plugin_str = test_ryu_plugin.PLUGIN_NAME + + +class RyuDhcpAgentNotifierTestCase( + FakeRyu, test_agent_scheduler.OvsDhcpAgentNotifierTestCase): + plugin_str = test_ryu_plugin.PLUGIN_NAME + + +class RyuL3AgentNotifierTestCase( + FakeRyu, test_agent_scheduler.OvsL3AgentNotifierTestCase): + plugin_str = test_ryu_plugin.PLUGIN_NAME diff --git a/quantum/tests/unit/ryu/test_ryu_plugin.py b/quantum/tests/unit/ryu/test_ryu_plugin.py index f93f096..894f051 100644 --- a/quantum/tests/unit/ryu/test_ryu_plugin.py +++ b/quantum/tests/unit/ryu/test_ryu_plugin.py @@ -18,9 +18,12 @@ from quantum.tests.unit.ryu import fake_ryu from quantum.tests.unit import test_db_plugin as test_plugin +PLUGIN_NAME = 'quantum.plugins.ryu.ryu_quantum_plugin.RyuQuantumPluginV2' + + class RyuPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase): - _plugin_name = 'quantum.plugins.ryu.ryu_quantum_plugin.RyuQuantumPluginV2' + _plugin_name = PLUGIN_NAME def setUp(self): self.ryu_patcher = fake_ryu.patch_fake_ryu_client() -- yamahata ------------------------------------------------------------------------------ AlienVault Unified Security Management (USM) platform delivers complete security visibility with the essential security capabilities. Easily and efficiently configure, manage, and operate all of your security controls from a single console and one unified framework. Download a free trial. http://p.sf.net/sfu/alienvault_d2d _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
