ovs: bubble up failures into main thread in native ofctl mode

When native ofctl interface is used (the default), the agent main() is
running in a separate gevent thread. Unless we explicitly request from
ryu to raise errors that may have happened in the agent app, it will
ignore them (only logging a warning message). This may interfere with
service management software like systemd that may use the return code to
decide whether to restart the dead service.

This patch makes ryu raise any uncaught errors happening inside the
agent. It also makes the agent 'wrapper' helper function not to swallow
raised exceptions on logging the error. Those two changes combined make
the agent exit with rc=1 if an exception happens inside the main()
function when in native mode.

This patch doesn't include any unit tests because those would be very
silly (like checking that we indeed pass the needed arguments to ryu).

Change-Id: Ic86b5eeae25a916c3c51f21e6820f5b0212dd5f8
Closes-Bug: #1694505
(cherry picked from commit f79ce2d272)
This commit is contained in:
Ihar Hrachyshka 2017-05-30 19:42:16 +00:00
parent 66073fa1f5
commit d54fc45d3e
1 changed files with 4 additions and 2 deletions

View File

@ -17,6 +17,7 @@
import functools
from oslo_log import log as logging
from oslo_utils import excutils
import ryu.app.ofctl.api # noqa
from ryu.base import app_manager
from ryu.lib import hub
@ -41,7 +42,8 @@ def agent_main_wrapper(bridge_classes):
try:
ovs_agent.main(bridge_classes)
except Exception:
LOG.exception(_LE("Agent main thread died of an exception"))
with excutils.save_and_reraise_exception():
LOG.exception(_LE("Agent main thread died of an exception"))
finally:
# The following call terminates Ryu's AppManager.run_apps(),
# which is needed for clean shutdown of an agent process.
@ -71,4 +73,4 @@ class OVSNeutronAgentRyuApp(app_manager.RyuApp):
'br_phys': _make_br_cls(br_phys.OVSPhysicalBridge),
'br_tun': _make_br_cls(br_tun.OVSTunnelBridge),
}
return hub.spawn(agent_main_wrapper, bridge_classes)
return hub.spawn(agent_main_wrapper, bridge_classes, raise_error=True)