Loading... <blockquote>在本博客中,ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。 ansible系列博文直达链接:<a href="https://www.zsythink.net/archives/tag/ansible/" target="_blank" rel="noopener">ansible轻松入门系列</a> “ansible系列”中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。 </blockquote> 在前文中,我们总结了条件判断的语法,以及一些tests的使用方法,这篇文章我们再来总结一些与条件判断有关的知识点 前文中,我们使用”when”关键字对条件进行判断,如果条件成立,则执行对应的任务,但是,细心如你一定已经发现了,当条件成立时,我们只能执行一个任务,如果我们想要在条件成立时,执行三个任务,该怎么办呢?难道我们要在这三个任务的每个任务中都加入相同的条件判断么?这种方法也太麻烦了,显然应该有更好的方法,没错,我们可以借助”block”解决这个小问题。 在ansible中,可以使用”block”关键字将多个任务整合成一个”块”,这个”块”将被当做一个整体,我们可以对这个”块”添加判断条件,当条件成立时,则执行这个块中的所有任务,我们来看一个小示例,如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task1 not in block"</span></div> </div> <div class=""> <div><span class="enlighter-text"> - block:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task2 in block1"</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task3 in block1"</span></div> </div> <div class=""> <div><span class="enlighter-text"> when: </span><span class="enlighter-n1">2</span> <span class="enlighter-g1">></span> <span class="enlighter-n1">1</span></div> </div> </div> </div> 上例中一共包含三个任务,第一个任务使用debug模块输出了 “task1 not in block”这句话,在第一个任务之后,我们定义了一个block,这个block中包含两个任务,两个debug任务分别输出各自的信息,上例的when关键字与block关键字对齐,表示when关键字的条件是针对block的,当when对应的条件成立,则执行block中的两个任务。 很容易理解对吧,其实,block除了能够与when结合在一起使用,还有一个很有用的功能,就是”错误处理”功能。 “错误处理”功能就是当某任务出错时,执行指定的其他任务,打个比方,我们想要在A任务执行失败时执行B任务,如果A任务执行成功,则无需执行B任务,实现这个功能,就能够使用block,当然,我们还有一些别的方法,也可以实现类似的功能,比如前文中提到的jinja2的tests,有个一名为failed的test,借助failed也可以实现类似的功能,此处我们先回顾一下failed的用法,然后对比着failed的示例,介绍block的用法,使用failed完成上述错误处理的示例代码如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - shell: </span><span class="enlighter-s0">'ls /ooo'</span></div> </div> <div class=""> <div><span class="enlighter-text"> register: return_value</span></div> </div> <div class=""> <div><span class="enlighter-text"> ignore_errors: </span><span class="enlighter-k1">true</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"I cought an error"</span></div> </div> <div class=""> <div><span class="enlighter-text"> when: return_value is failed</span></div> </div> </div> </div> 如上例所示,我在shell任务中执行了’ls /ooo’命令,而test70主机中并不存在/ooo这个路径,所以shell模块执行时一定会出错,我将shell任务执行的返回值注册到了return_value变量中,然后使用”is failed”进行判断,如果条件成立,代表shell任务执行出错,则执行debug任务,输出对应的信息,上述示例就能实现我们刚才所要求的功能,如果用block来实现,该怎样编写playbook呢?来看一个小示例,如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - block:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - shell: </span><span class="enlighter-s0">'ls /ooo'</span></div> </div> <div class=""> <div><span class="enlighter-text"> rescue:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">'I caught an error'</span></div> </div> </div> </div> 如上例所示,我定义了一个block,这个block中有一个任务,这个任务在目标主机中执行了’ls /ooo’命令,除了block关键字,还有另外一个关键字rescue,rescue关键字与block关键字对齐,rescue的字面意思为”救援”,表示当block中的任务执行失败时,会执行rescue中的任务进行补救,当然,在rescue中定义什么任务,是由你决定的,上述示例主要是为了说明,当block中的任务出错时,会执行rescue中的任务,当block中的任务顺利执行时,则不会执行rescue中的任务。 你可能会问,使用block的方法完成”错误处理”的功能,似乎与使用failed的方法并没有什么不同,除了代码似乎”精简”了一点,block还有其他优势么?其实,使用block的方式还是有一定优势的,当block中有多个任务时,这种优势就比较明显了,我们来看一个小示例,如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - block:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - shell: </span><span class="enlighter-s0">'ls /opt'</span></div> </div> <div class=""> <div><span class="enlighter-text"> - shell: </span><span class="enlighter-s0">'ls /testdir'</span></div> </div> <div class=""> <div><span class="enlighter-text"> - shell: </span><span class="enlighter-s0">'ls /c'</span></div> </div> <div class=""> <div><span class="enlighter-text"> rescue:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">'I caught an error'</span></div> </div> </div> </div> 如上例所示,block中有三个任务,这三个任务中的任何一个任务出错,都会执行rescue中的任务,所以通常,我们会使用block和rescue结合,完成”错误捕捉,报出异常”的功能,其实,不仅block中可以有多个任务,rescue中也可以定义多个任务,当block中的任何一个任务出错时,会按照顺序执行rescue中的任务。 你一定已经理解了,我们来扩展一下,上例中只使用到了block与rescue关键字,其实,我们还能够再加入always关键字,加入always关键字以后,无论block中的任务执行成功还是失败,always中的任务都会被执行,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - block:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">'I execute normally'</span></div> </div> <div class=""> <div><span class="enlighter-text"> - command: /bin/</span><span class="enlighter-k1">false</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">'I never execute, due to the above task failing'</span></div> </div> <div class=""> <div><span class="enlighter-text"> rescue:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">'I caught an error'</span></div> </div> <div class=""> <div><span class="enlighter-text"> - command: /bin/</span><span class="enlighter-k1">false</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">'I also never execute'</span></div> </div> <div class=""> <div><span class="enlighter-text"> always:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"This always executes"</span></div> </div> </div> </div> 如上例所示,block中有多个任务,rescue中也有多个任务,上例中故意执行”/bin/false”命令,模拟任务出错的情况,当block中的’/bin/false’执行后,其后的debug任务将不会被执行,因为’/bin/false’模拟出错,出错后直接执行rescue中的任务,在执行rescue中的任务时,会先输出 ‘I caught an error’,然后又在rescue中使用’/bin/false’模拟出错的情况,出错后之后的debug任务不会被执行,直接执行always中的任务,always中的任务一定会被执行,无论block中的任务是否出错,快动手测试一下实际的执行效果吧。 这篇文章就总结到这里,希望能够对你有所帮助~~ 转载自朱双印日志https://www.zsythink.net/archives/2836 Last modification:May 29, 2024 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏