Merge "NEC plugin support for dhcp network and router scheduling"

This commit is contained in:
Jenkins 2013-03-03 10:22:08 +00:00 committed by Gerrit Code Review
commit efe86e7759
8 changed files with 98 additions and 12 deletions

View File

@ -59,6 +59,7 @@ TYPE_DICT = "dict"
AGENT_TYPE_DHCP = 'DHCP agent' AGENT_TYPE_DHCP = 'DHCP agent'
AGENT_TYPE_OVS = 'Open vSwitch agent' AGENT_TYPE_OVS = 'Open vSwitch agent'
AGENT_TYPE_LINUXBRIDGE = 'Linux bridge agent' AGENT_TYPE_LINUXBRIDGE = 'Linux bridge agent'
AGENT_TYPE_NEC = 'NEC plugin agent'
AGENT_TYPE_L3 = 'L3 agent' AGENT_TYPE_L3 = 'L3 agent'
L2_AGENT_TOPIC = 'N/A' L2_AGENT_TOPIC = 'N/A'

View File

@ -33,6 +33,7 @@ migration_for_plugins = [
'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2', 'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2', 'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2', 'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
'quantum.plugins.nec.nec_plugin.NECPluginV2',
] ]
from alembic import op from alembic import op

View File

@ -33,6 +33,7 @@ migration_for_plugins = [
'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2', 'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2', 'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2', 'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
'quantum.plugins.nec.nec_plugin.NECPluginV2',
] ]
from alembic import op from alembic import op

View File

@ -32,10 +32,12 @@ from quantum.agent.linux import ovs_lib
from quantum.agent import rpc as agent_rpc from quantum.agent import rpc as agent_rpc
from quantum.agent import securitygroups_rpc as sg_rpc from quantum.agent import securitygroups_rpc as sg_rpc
from quantum.common import config as logging_config from quantum.common import config as logging_config
from quantum.common import constants as q_const
from quantum.common import topics from quantum.common import topics
from quantum import context as q_context from quantum import context as q_context
from quantum.extensions import securitygroup as ext_sg from quantum.extensions import securitygroup as ext_sg
from quantum.openstack.common import log as logging 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 dispatcher
from quantum.openstack.common.rpc import proxy from quantum.openstack.common.rpc import proxy
from quantum.plugins.nec.common import config 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.int_br = ovs_lib.OVSBridge(integ_br, root_helper)
self.polling_interval = polling_interval self.polling_interval = polling_interval
self.cur_ports = []
self.datapath_id = "0x%s" % self.int_br.get_datapath_id() 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() self.setup_rpc()
def setup_rpc(self): def setup_rpc(self):
@ -137,6 +149,7 @@ class NECQuantumAgent(object):
self.context = q_context.get_admin_context_without_session() self.context = q_context.get_admin_context_without_session()
self.plugin_rpc = NECPluginApi(topics.PLUGIN) self.plugin_rpc = NECPluginApi(topics.PLUGIN)
self.state_rpc = agent_rpc.PluginReportStateAPI(topics.PLUGIN)
self.sg_agent = SecurityGroupAgentRpc(self.context) self.sg_agent = SecurityGroupAgentRpc(self.context)
# RPC network init # RPC network init
@ -154,6 +167,22 @@ class NECQuantumAgent(object):
self.topic, self.topic,
consumers) 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): def _vif_port_to_port_info(self, vif_port):
return dict(id=vif_port.vif_id, port_no=vif_port.ofport, return dict(id=vif_port.vif_id, port_no=vif_port.ofport,
mac=vif_port.vif_mac) mac=vif_port.vif_mac)
@ -167,7 +196,6 @@ class NECQuantumAgent(object):
def daemon_loop(self): def daemon_loop(self):
"""Main processing loop for NEC Plugin Agent.""" """Main processing loop for NEC Plugin Agent."""
old_ports = []
while True: while True:
new_ports = [] new_ports = []
@ -175,12 +203,12 @@ class NECQuantumAgent(object):
for vif_port in self.int_br.get_vif_ports(): for vif_port in self.int_br.get_vif_ports():
port_id = vif_port.vif_id port_id = vif_port.vif_id
new_ports.append(port_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_info = self._vif_port_to_port_info(vif_port)
port_added.append(port_info) port_added.append(port_info)
port_removed = [] port_removed = []
for port_id in old_ports: for port_id in self.cur_ports:
if port_id not in new_ports: if port_id not in new_ports:
port_removed.append(port_id) port_removed.append(port_id)
@ -192,7 +220,7 @@ class NECQuantumAgent(object):
else: else:
LOG.debug(_("No port changed.")) LOG.debug(_("No port changed."))
old_ports = new_ports self.cur_ports = new_ports
time.sleep(self.polling_interval) time.sleep(self.polling_interval)

View File

@ -20,6 +20,7 @@ from oslo.config import cfg
from quantum.agent.common import config from quantum.agent.common import config
# import rpc config options # import rpc config options
from quantum.openstack.common import rpc from quantum.openstack.common import rpc
from quantum import scheduler
ovs_opts = [ ovs_opts = [
@ -54,7 +55,9 @@ ofc_opts = [
cfg.CONF.register_opts(ovs_opts, "OVS") cfg.CONF.register_opts(ovs_opts, "OVS")
cfg.CONF.register_opts(agent_opts, "AGENT") cfg.CONF.register_opts(agent_opts, "AGENT")
cfg.CONF.register_opts(ofc_opts, "OFC") cfg.CONF.register_opts(ofc_opts, "OFC")
config.register_agent_state_opts_helper(cfg.CONF)
config.register_root_helper(cfg.CONF) config.register_root_helper(cfg.CONF)
cfg.CONF.register_opts(scheduler.AGENTS_SCHEDULER_OPTS)
# shortcuts # shortcuts
CONF = cfg.CONF CONF = cfg.CONF

View File

@ -17,11 +17,15 @@
# @author: Akihiro MOTOKI # @author: Akihiro MOTOKI
from quantum.agent import securitygroups_rpc as sg_rpc 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 constants as q_const
from quantum.common import exceptions as q_exc from quantum.common import exceptions as q_exc
from quantum.common import rpc as q_rpc from quantum.common import rpc as q_rpc
from quantum.common import topics from quantum.common import topics
from quantum import context 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 dhcp_rpc_base
from quantum.db import extraroute_db from quantum.db import extraroute_db
from quantum.db import l3_rpc_base 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.db import securitygroups_rpc_base as sg_db_rpc
from quantum.extensions import portbindings from quantum.extensions import portbindings
from quantum.extensions import securitygroup as ext_sg 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 log as logging
from quantum.openstack.common import rpc from quantum.openstack.common import rpc
from quantum.openstack.common.rpc import proxy from quantum.openstack.common.rpc import proxy
@ -60,7 +65,8 @@ class OperationalStatus:
class NECPluginV2(nec_plugin_base.NECPluginV2Base, class NECPluginV2(nec_plugin_base.NECPluginV2Base,
extraroute_db.ExtraRoute_db_mixin, extraroute_db.ExtraRoute_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin): sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.AgentSchedulerDbMixin):
"""NECPluginV2 controls an OpenFlow Controller. """NECPluginV2 controls an OpenFlow Controller.
The Quantum NECPluginV2 maps L2 logical networks to L2 virtualized networks 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", supported_extension_aliases = ["router", "quotas", "binding",
"security-group", "extraroute"] "security-group", "extraroute",
"agent", "agent_scheduler",
]
binding_view = "extension:port_binding:view" binding_view = "extension:port_binding:view"
binding_set = "extension:port_binding:set" binding_set = "extension:port_binding:set"
@ -97,17 +105,24 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
self.setup_rpc() 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): def setup_rpc(self):
self.topic = topics.PLUGIN self.topic = topics.PLUGIN
self.conn = rpc.create_connection(new=True) self.conn = rpc.create_connection(new=True)
self.notifier = NECPluginV2AgentNotifierApi(topics.AGENT) 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) # NOTE: callback_sg is referred to from the sg unit test.
self.callback_dhcp = DhcpRpcCallback()
self.callback_l3 = L3RpcCallback()
self.callback_sg = SecurityGroupServerRpcCallback() self.callback_sg = SecurityGroupServerRpcCallback()
callbacks = [self.callback_nec, self.callback_dhcp, callbacks = [NECPluginV2RPCCallbacks(self),
self.callback_l3, self.callback_sg] DhcpRpcCallback(), L3RpcCallback(),
self.callback_sg,
agents_db.AgentExtRpcCallback()]
self.dispatcher = q_rpc.PluginRpcDispatcher(callbacks) self.dispatcher = q_rpc.PluginRpcDispatcher(callbacks)
self.conn.create_consumer(self.topic, self.dispatcher, fanout=False) self.conn.create_consumer(self.topic, self.dispatcher, fanout=False)
# Consume from all consumers in a thread # Consume from all consumers in a thread

View File

@ -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

View 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 from quantum.tests.unit import test_db_plugin as test_plugin
PLUGIN_NAME = 'quantum.plugins.nec.nec_plugin.NECPluginV2'
class NecPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase): class NecPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase):
_plugin_name = 'quantum.plugins.nec.nec_plugin.NECPluginV2' _plugin_name = PLUGIN_NAME
def setUp(self): def setUp(self):
super(NecPluginV2TestCase, self).setUp(self._plugin_name) super(NecPluginV2TestCase, self).setUp(self._plugin_name)