这篇文章来讲一讲如何利用hook来暂停资源的执行流程。
还记得以前讲到的environment文件吗?就是通过它来配置hook。
参考heat源码中,doc\source\template_guide\environment.rst文件的Pause stack creation or update on a given resource一节。
可以知道在resource_registry字段中,还可以对资源指定hook。
目前支持的是在资源create和update流程中插入hook,中断该流程的执行。
environment文件示例如下:
resource_registry:
resources:
myres:
hooks: pre-update
表示hook资源myres的update流程。如果create和update流程都想hook,如下:
resource_registry:
resources:
myres:
hooks: [pre-create, pre-update]
然后,在执行stack-create或stack-update命令的时候,用-e参数传入该environment文件即可。
例如:
heat stack-create -f template -e env mystack
heat stack-update -f template -e env mystack
一旦资源的hook被触发,资源的create或update流程就会被暂停。
这样相关资源以及整个stack就会一直处于IN_PROGRESS状态,可以进行一些调试测试。
这时候可以利用hook-poll命令查询stack当前触发的hook。
heat hook-poll mystack
如果要继续中断的流程,可以用hook-clear命令清除指定资源的hook。
heat hook-clear mystack myres
上面讲的是如何使用hook,下面再来看看源码中是如何实现hook中断的。
其实并不复杂,就是依赖resource.py里面的函数_break_if_required。
看看该函数的实现:
def _break_if_required(self, action, hook):
"""Block the resource until the hook is cleared if there is one."""
if self.stack.env.registry.matches_hook(self.name, hook):
self._add_event(self.action, self.status,
_("%(a)s paused until Hook %(h)s is cleared")
% {'a': action, 'h': hook})
self.trigger_hook(hook)
LOG.info(_LI('Reached hook on %s'), six.text_type(self))
while self.has_hook(hook) and self.status != self.FAILED:
try:
yield
except Exception:
self.clear_hook(hook)
self._add_event(
self.action, self.status,
"Failure occurred while waiting.")
逻辑并不复杂,主要的就是一个if,一个while。
if就是用来判断该资源是否在env中配置了hook;while就是一个循环,直到hook被清除。
再看一下_break_if_required函数调用的地方,就是在resource的create和update函数中。
这样就达到了中断相关执行流程的目的。