[AIM] Make link update/delete transactional

Also, make sure it doesn't break other networks' path update
when one fails

Change-Id: I3634f2686434697c51adf685a9373f853ba7f5ec
(cherry picked from commit 8b7206a1ad)
This commit is contained in:
Ivar Lazzaro 2018-02-27 20:06:34 -08:00
parent b5552abdba
commit 5d50c35ca5
1 changed files with 59 additions and 43 deletions

View File

@ -1965,35 +1965,43 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
', '.join([str(p) for p in ', '.join([str(p) for p in
(host, interface, mac, switch, module, port, (host, interface, mac, switch, module, port,
pod_id, port_description)])) pod_id, port_description)]))
if not switch: with context.session.begin(subtransactions=True):
self.delete_link(context, host, interface, mac, switch, module, if not switch:
port) self.delete_link(context, host, interface, mac, switch, module,
return port)
return
session = context.session session = context.session
aim_ctx = aim_context.AimContext(db_session=session) aim_ctx = aim_context.AimContext(db_session=session)
hlink = self.aim.get(aim_ctx, hlink = self.aim.get(aim_ctx,
aim_infra.HostLink(host_name=host, aim_infra.HostLink(host_name=host,
interface_name=interface)) interface_name=interface))
if not hlink or hlink.path != port_description: if not hlink or hlink.path != port_description:
attrs = dict(interface_mac=mac, attrs = dict(interface_mac=mac,
switch_id=switch, module=module, port=port, switch_id=switch, module=module, port=port,
path=port_description, pod_id=pod_id) path=port_description, pod_id=pod_id)
if hlink: if hlink:
old_path = hlink.path old_path = hlink.path
hlink = self.aim.update(aim_ctx, hlink, **attrs) hlink = self.aim.update(aim_ctx, hlink, **attrs)
else: else:
old_path = None old_path = None
hlink = aim_infra.HostLink(host_name=host, hlink = aim_infra.HostLink(host_name=host,
interface_name=interface, interface_name=interface,
**attrs) **attrs)
hlink = self.aim.create(aim_ctx, hlink) hlink = self.aim.create(aim_ctx, hlink)
# Update static paths of all EPGs with ports on the host # Update static paths of all EPGs with ports on the host
nets_segs = self._get_non_opflex_segments_on_host(context, host) nets_segs = self._get_non_opflex_segments_on_host(context,
for net, seg in nets_segs: host)
self._update_static_path_for_network(session, net, seg, for net, seg in nets_segs:
old_path=old_path, try:
new_path=hlink.path) self._update_static_path_for_network(
session, net, seg, old_path=old_path,
new_path=hlink.path)
except Exception as e:
# If one fails don't affect all the others
LOG.error("Static path update on update_link has "
"failed for network %s: %s" % (net['id'],
e.message))
# Topology RPC method handler # Topology RPC method handler
def delete_link(self, context, host, interface, mac, switch, module, port): def delete_link(self, context, host, interface, mac, switch, module, port):
@ -2003,22 +2011,30 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
session = context.session session = context.session
aim_ctx = aim_context.AimContext(db_session=session) aim_ctx = aim_context.AimContext(db_session=session)
hlink = self.aim.get(aim_ctx, with context.session.begin(subtransactions=True):
aim_infra.HostLink(host_name=host, hlink = self.aim.get(aim_ctx,
interface_name=interface)) aim_infra.HostLink(host_name=host,
if not hlink: interface_name=interface))
return if not hlink:
return
self.aim.delete(aim_ctx, hlink) self.aim.delete(aim_ctx, hlink)
# if there are no more host-links for this host (multiple links may # if there are no more host-links for this host (multiple links may
# exist with VPC), update EPGs with ports on this host to remove # exist with VPC), update EPGs with ports on this host to remove
# the static path to this host # the static path to this host
if not self.aim.find(aim_ctx, aim_infra.HostLink, host_name=host, if not self.aim.find(aim_ctx, aim_infra.HostLink, host_name=host,
path=hlink.path): path=hlink.path):
nets_segs = self._get_non_opflex_segments_on_host(context, host) nets_segs = self._get_non_opflex_segments_on_host(context,
for net, seg in nets_segs: host)
self._update_static_path_for_network(session, net, seg, for net, seg in nets_segs:
old_path=hlink.path) try:
self._update_static_path_for_network(
session, net, seg, old_path=hlink.path)
except Exception as e:
# If one fails don't affect all the others
LOG.error("Static path update on update_link has "
"failed for network %s: %s" % (net['id'],
e.message))
def _agent_bind_port(self, context, agent_type, bind_strategy): def _agent_bind_port(self, context, agent_type, bind_strategy):
current = context.current current = context.current