天天看点

ansible-playbook如何判断并中断执行

今天碰到一个需求,当使用ansible-playbook在执行一个脚本后,根据脚本返回的内容判断是否继续往下执行还是中断执行,查询官网发现使用register寄存器可以实现记录脚本输出,使用when+fail模块来判断是否往下继续执行或者中断,以下是一个简单例子:

ansible服务在172.16.206.128上,先执行一个脚本,脚本返回success时在172.16.206.129上创建一个目录/tmp/test,如果返回failed则中断执行。

在129服务器上配置一个脚本,内容如下:

1

2

<code>#!/bin/bash</code>

<code>echo</code> <code>"failed"</code>

在128上创建一个register.yml的yml文件

3

4

5

6

<code>---</code>

<code>- hosts: 172.16.206.129</code>

<code>  </code><code>remote_user: root</code>

<code>  </code><code>tasks:</code>

<code>    </code><code>- </code><code>command</code><code>: </code><code>/tmp/test</code><code>.sh</code>

<code>      </code><code>register: result</code>

执行register.yml这个playbook,看看输出的结果

7

8

9

<code>root@host1:</code><code>/etc/ansible/yml</code><code># ansible-playbook register.yml -v</code>

<code>Using </code><code>/etc/ansible/ansible</code><code>.cfg as config </code><code>file</code>

<code>PLAY ***************************************************************************</code>

<code>TASK [setup] *******************************************************************</code>

<code>ok: [172.16.206.129]</code>

<code>TASK [</code><code>command</code><code>] *****************************************************************</code>

<code>changed: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>true</code><code>, </code><code>"cmd"</code><code>: [</code><code>"/tmp/test.sh"</code><code>], </code><code>"delta"</code><code>: </code><code>"0:00:00.001628"</code><code>, </code><code>"end"</code><code>: </code><code>"2016-01-17 19:14:36.651356"</code><code>, </code><code>"rc"</code><code>: 0, </code><code>"start"</code><code>: </code><code>"2016-01-17 19:14:36.649728"</code><code>, </code><code>"stderr"</code><code>: </code><code>""</code><code>, </code><code>"stdout"</code><code>: </code><code>"failed"</code><code>, </code><code>"stdout_lines"</code><code>: [</code><code>"failed"</code><code>], </code><code>"warnings"</code><code>: []}</code>

<code>PLAY RECAP *********************************************************************</code>

<code>172.16.206.129             : ok=2    changed=1    unreachable=0    failed=0</code>

register保存的信息就是“=&gt;”后面的内容,这些信息保存到result这个变量中。stdout为标准输出,即/tmp/test.sh脚本输出的内容。我们就可以利用stdout的结果来结合when来做判断,是否执行后面的playbook。

现在我们修改register.yml文件,加一个任务。当脚本标准输出为failed时,创建/tmp/test目录,否则不执行

<code>    </code><code>- </code><code>file</code><code>: path=</code><code>/tmp/test</code>  <code>owner=root group=root mode=0755 state=directory</code>

<code>      </code><code>when: result.stdout == </code><code>'failed'</code>

运行修改后的playbook,看看结果:

10

11

<code>changed: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>true</code><code>, </code><code>"cmd"</code><code>: [</code><code>"/tmp/test.sh"</code><code>], </code><code>"delta"</code><code>: </code><code>"0:00:00.001865"</code><code>, </code><code>"end"</code><code>: </code><code>"2016-01-17 19:28:21.561565"</code><code>, </code><code>"rc"</code><code>: 0, </code><code>"start"</code><code>: </code><code>"2016-01-17 19:28:21.559700"</code><code>, </code><code>"stderr"</code><code>: </code><code>""</code><code>, </code><code>"stdout"</code><code>: </code><code>"failed"</code><code>, </code><code>"stdout_lines"</code><code>: [</code><code>"failed"</code><code>], </code><code>"warnings"</code><code>: []}</code>

<code>TASK [</code><code>file</code><code>] ********************************************************************</code>

<code>changed: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>true</code><code>, </code><code>"gid"</code><code>: 0, </code><code>"group"</code><code>: </code><code>"root"</code><code>, </code><code>"mode"</code><code>: </code><code>"0755"</code><code>, </code><code>"owner"</code><code>: </code><code>"root"</code><code>, </code><code>"path"</code><code>: </code><code>"/tmp/test"</code><code>, </code><code>"size"</code><code>: 4096, </code><code>"state"</code><code>: </code><code>"directory"</code><code>, </code><code>"uid"</code><code>: 0}</code>

<code>172.16.206.129             : ok=3    changed=2    unreachable=0    failed=0</code>

playbook成功执行,可以看到129服务器上的test目录创建成功

<code>[root@host2 tmp]</code><code># ls -l /tmp</code>

<code>总用量 24</code>

<code>srwxr-xr-x. 1 root root    0 1月   6 15:04 gnome-system-monitor.root.527586962</code>

<code>drwx------. 2 root root 4096 1月   6 14:02 keyring-bFV7zU</code>

<code>drwx------. 2 gdm  gdm  4096 1月   7 18:47 pulse-Kd6LKHrhRDP0</code>

<code>drwx------. 2 root root 4096 1月   7 18:47 pulse-Mkh5Mj3gpkBu</code>

<code>drwxr-xr-x  2 root root 4096 1月  17 19:28 </code><code>test</code>

<code>-rwxr-xr-x  1 root root   26 1月  17 19:14 </code><code>test</code><code>.sh</code>

<code>drwx------. 2 root root 4096 1月   7 18:47 virtual-root.aNS2ix</code>

现在我们把129服务器上的test.sh脚本中的echo输出改成success,并删除/tmp/test目录。再执行register.yml这个playbook,看看结果如何:

<code>changed: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>true</code><code>, </code><code>"cmd"</code><code>: [</code><code>"/tmp/test.sh"</code><code>], </code><code>"delta"</code><code>: </code><code>"0:00:00.001672"</code><code>, </code><code>"end"</code><code>: </code><code>"2016-01-17 19:34:11.407255"</code><code>, </code><code>"rc"</code><code>: 0, </code><code>"start"</code><code>: </code><code>"2016-01-17 19:34:11.405583"</code><code>, </code><code>"stderr"</code><code>: </code><code>""</code><code>, </code><code>"stdout"</code><code>: </code><code>"success"</code><code>, </code><code>"stdout_lines"</code><code>: [</code><code>"success"</code><code>], </code><code>"warnings"</code><code>: []}</code>

<code>skipping: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>false</code><code>, </code><code>"skip_reason"</code><code>: </code><code>"Conditional check failed"</code><code>, </code><code>"skipped"</code><code>: </code><code>true</code><code>}</code>

可以看到创建/tmp/test目录这个task跳过了,原因是Condition check failed。

129服务器上也没有test目录

<code>[root@host2 tmp]</code><code># ls -l</code>

<code>总用量 20</code>

<code>-rwxr-xr-x  1 root root   27 1月  17 19:33 </code><code>test</code><code>.sh</code>

这里存在一个问题,条件判断失败的任务被跳过了,那么后面的任务会成功执行吗?我们来测试下

修改register.yml文件,增加一个任务

<code>    </code><code>- copy: src=</code><code>/etc/fstab</code> <code>dest=</code><code>/tmp/fstab</code> <code>owner=root group=root mode=0644</code>

执行playbook,看看结果如果:

12

13

<code>changed: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>true</code><code>, </code><code>"cmd"</code><code>: [</code><code>"/tmp/test.sh"</code><code>], </code><code>"delta"</code><code>: </code><code>"0:00:00.001626"</code><code>, </code><code>"end"</code><code>: </code><code>"2016-01-17 19:57:38.439216"</code><code>, </code><code>"rc"</code><code>: 0, </code><code>"start"</code><code>: </code><code>"2016-01-17 19:57:38.437590"</code><code>, </code><code>"stderr"</code><code>: </code><code>""</code><code>, </code><code>"stdout"</code><code>: </code><code>"success"</code><code>, </code><code>"stdout_lines"</code><code>: [</code><code>"success"</code><code>], </code><code>"warnings"</code><code>: []}</code>

<code>TASK [copy] ********************************************************************</code>

<code>changed: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>true</code><code>, </code><code>"checksum"</code><code>: </code><code>"9643ddd3b4c4c13dbbc511d00853a6c08354edc9"</code><code>, </code><code>"dest"</code><code>: </code><code>"/tmp/fstab"</code><code>, </code><code>"gid"</code><code>: 0, </code><code>"group"</code><code>: </code><code>"root"</code><code>, </code><code>"md5sum"</code><code>: </code><code>"3b576bf27cf12c19374a4a3c48c65187"</code><code>, </code><code>"mode"</code><code>: </code><code>"0644"</code><code>, </code><code>"owner"</code><code>: </code><code>"root"</code><code>, </code><code>"size"</code><code>: 779, </code><code>"src"</code><code>: </code><code>"/root/.ansible/tmp/ansible-tmp-1452880713.36-170231715664842/source"</code><code>, </code><code>"state"</code><code>: </code><code>"file"</code><code>, </code><code>"uid"</code><code>: 0}</code>

 从结果可以看到,copy任务成功执行了。/tmp目录下也有fstab文件

<code>[root@host2 ~]</code><code># ls -l /tmp</code>

<code>-rw-r--r--  1 root root  779 1月  17 19:57 fstab</code>

我们的需求是当某一个任务执行失败时,应该中断后面的任务,而不是跳过。这个需要结合fail模块来实现了。

我们将/tmp/test.sh脚本输出改回"failed"。删除/tmp下的fstab文件。修改register.yml文件

<code>    </code><code>- name: </code><code>if</code> <code>stdout chekck failed,interrupt execution</code>

<code>      </code><code>fail: msg=</code><code>"check failed"</code>

<code>      </code><code>when: result.stdout == </code><code>"failed"</code>

执行register.yml文件,看看结果。

<code>changed: [172.16.206.129] =&gt; {</code><code>"changed"</code><code>: </code><code>true</code><code>, </code><code>"cmd"</code><code>: [</code><code>"/tmp/test.sh"</code><code>], </code><code>"delta"</code><code>: </code><code>"0:00:00.001776"</code><code>, </code><code>"end"</code><code>: </code><code>"2016-01-17 20:18:19.567509"</code><code>, </code><code>"rc"</code><code>: 0, </code><code>"start"</code><code>: </code><code>"2016-01-17 20:18:19.565733"</code><code>, </code><code>"stderr"</code><code>: </code><code>""</code><code>, </code><code>"stdout"</code><code>: </code><code>"failed"</code><code>, </code><code>"stdout_lines"</code><code>: [</code><code>"failed"</code><code>], </code><code>"warnings"</code><code>: []}</code>

<code>TASK [</code><code>if</code> <code>stdout chekck failed,interrupt execution] *****************************</code>

<code>fatal: [172.16.206.129]: FAILED! =&gt; {</code><code>"changed"</code><code>: </code><code>false</code><code>, </code><code>"failed"</code><code>: </code><code>true</code><code>, </code><code>"msg"</code><code>: </code><code>"check failed"</code><code>}</code>

<code>172.16.206.129             : ok=2    changed=1    unreachable=0    failed=1</code>

  当条件判断失败时,后面的任务都终止了,不再执行。/tmp目录下也没有test目录和fstab文件

<code>-rwxr-xr-x  1 root root   26 1月  17 20:11 </code><code>test</code><code>.sh</code>

本文转自 曾哥最爱 51CTO博客,原文链接:http://blog.51cto.com/zengestudy/1763261,如需转载请自行联系原作者