创建资源后如何通知agent

当一个subnet创建后,需要通知dhcp-agent等,比如subnet_delete,subnet_create等,这个notify是什么时候发的呢,原来在API的Controller里

[python]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def delete(self, request, id, **kwargs):
"""Deletes the specified entity."""
notifier_api.notify(request.context,
self._publisher_id,
self._resource + '.delete.start',
notifier_api.CONF.default_notification_level,
{self._resource + '_id': id})
action = self._plugin_handlers[self.DELETE]

# Check authz
parent_id = kwargs.get(self._parent_id_name)
obj = self._item(request, id, parent_id=parent_id)
try:
policy.enforce(request.context,
action,
obj,
resource=id)
except exceptions.PolicyNotAuthorized as err:
# To avoid giving away information, pretend that it
# doesn't exist
raise webob.exc.HTTPForbidden(explanation=err.msg)

obj_deleter = getattr(self._plugin, action)
obj_deleter(request.context, id, **kwargs)
notifier_method = self._resource + '.delete.end'
notifier_api.notify(request.context,
self._publisher_id,
notifier_method,
notifier_api.CONF.default_notification_level,
{self._resource + '_id': id})
result = {self._resource: self._view(request.context, obj)}
self._nova_notifier.send_network_change(action, {}, result)
self._send_dhcp_notification(request.context,
result,
notifier_method) <----------

代码里经常看到
create_XXX_precommit
create_XXX_postcommit
这样的函数,我以为是通知agent的呢,但看了子网的这2个家伙,发现只是通知driver而已,通知agent是由上面的notifyer完成的,可以看下面的log

<% codeblock %>
2016-06-27 12:00:55.725 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######3:<stevedore.extension.Extension object at 0x4b85c90>
2016-06-27 12:00:55.736 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######4:
2016-06-27 12:00:55.736 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######5:(<bound method BareMetalMechanismDriver.delete_subnet_postc
ommit of <neutron.plugins.ml2.drivers.mech_baremetal.BareMetalMechanismDriver object at 0x3a42610>>,)
2016-06-27 12:00:55.737 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######6:
2016-06-27 12:00:55.738 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######3:<stevedore.extension.Extension object at 0x492fc50>
2016-06-27 12:00:55.749 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######4:
2016-06-27 12:00:55.750 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######5:(<bound method OpenvswitchMechanismDriver.delete_subnet_pos
tcommit of <neutron.plugins.ml2.drivers.mech_openvswitch.OpenvswitchMechanismDriver object at 0x3a42d50>>,)
2016-06-27 12:00:55.750 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######6:
2016-06-27 12:00:55.751 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######3:<stevedore.extension.Extension object at 0x492fc50>
2016-06-27 12:00:55.762 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######4:
2016-06-27 12:00:55.763 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######5:(<bound method L2populationMechanismDriver.delete_subnet_po
stcommit of <neutron.plugins.ml2.drivers.l2pop.mech_driver.L2populationMechanismDriver object at 0x3a429d0>>,)
2016-06-27 12:00:55.763 14997 ERROR neutron.plugins.ml2.managers [req-1df986e6-3df2-4125-b555-e29ab7df384c None] #######6:

<% endcodeblock %>

另外一个有意思的细节是network什么时候schedule的呢,就是第一个create_port的时候,
Controller在收到发送port_create_end消息的时候,会调用DhcpAgentNotifyAPI的notify
这里的notify就很特殊处理了,不会傻乎乎的直接notify
如果是port_create_end消息,先做schedule,然后才发送消息。
也就是之前虽然有network_create_end, subnet_create_end之类的消息,基本没啥用

<% codeblock %>

# schedule the network first, if needed
schedule_required = method == 'port_create_end'
if schedule_required:
    agents = self._schedule_network(admin_ctx, network, agents)

enabled_agents = self._get_enabled_agents(
    context, network, agents, method, payload)
for agent in enabled_agents:
    self._cast_message(
        context, method, payload, agent.host, agent.topic)

<% endcodeblock %>