当我遇到某种情况时,我想退出而没有错误(我知道assert和fail模块)。以下代码退出但失败:
tasks:
- name: Check if there is something to upgrade
shell: if apt-get --dry-run upgrade | grep -q "0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded"; then echo "no"; else echo "yes"; fi
register: upgrading
- name: Exit if nothing to upgrade
fail: msg="Nothing to upgrade"
when: upgrading.stdout == "no"
答案 0 :(得分:43)
在Ansible 2.2中,您可以将end_play
与meta模块一起使用:
- meta: end_play
您还可以指定when
有条件地结束播放:
- meta: end_play
when: upgrading.stdout == "no"
但请注意,无论播放是否实际结束,任务都未列在ansible-playbook的输出中。此外,该任务不计入回顾中。所以,你可以这样做:
- block:
- name: "end play if nothing to upgrade"
debug:
msg: "nothing to upgrade, ending play"
- meta: end_play
when: upgrading.stdout == "no"
只有在满足条件时才会在结束之前宣布播放结束。如果不满足条件,您将看到名为end play if nothing to upgrade
的任务被适当跳过,这将为用户提供更多关于游戏结束或不结束的信息。
当然,这只会结束当前的播放,而不是剧本中所有剩余的播放。
答案 1 :(得分:3)
更好,更合乎逻辑的解决方法可能是反过来而不是失败,如果没有任何升级(这是一个单独的步骤只做那个)你可以附加条件依赖的所有升级任务在upgrade
变量上。实质上只需添加
when: upgrading.changed
应该只在升级期间执行的任务。
这是一项更多的工作,但它也带来了清晰度和自我包含影响其内部任务的逻辑,而不是取决于某些方式可能会或可能不会提前终止它。
答案 2 :(得分:3)
让我们使用Tymoteusz建议的角色:
将你的游戏分成两个roles,其中第一个角色将执行检查(并设置一些变量保持检查的结果),第二个角色将根据检查结果进行操作。
我已使用以下内容创建aaa.yaml
:
---
- hosts: all
remote_user: root
roles:
- check
- { role: doit, when: "check.stdout == '0'" }
...
然后check
中的角色roles/check/tasks/main.yaml
:
---
- name: "Check if we should continue"
shell:
echo $(( $RANDOM % 2 ))
register: check
- debug:
var: check.stdout
...
然后doit
中的角色roles/doit/tasks/main.yaml
:
---
- name: "Do it only on systems where check returned 0"
command:
date
...
这就是输出:
TASK [check : Check if we should continue] *************************************
Thursday 06 October 2016 21:49:49 +0200 (0:00:09.800) 0:00:09.832 ******
changed: [capsule.example.com]
changed: [monitoring.example.com]
changed: [satellite.example.com]
changed: [docker.example.com]
TASK [check : debug] ***********************************************************
Thursday 06 October 2016 21:49:55 +0200 (0:00:05.171) 0:00:15.004 ******
ok: [monitoring.example.com] => {
"check.stdout": "0"
}
ok: [satellite.example.com] => {
"check.stdout": "1"
}
ok: [capsule.example.com] => {
"check.stdout": "0"
}
ok: [docker.example.com] => {
"check.stdout": "0"
}
TASK [doit : Do it only on systems where check returned 0] *********************
Thursday 06 October 2016 21:49:55 +0200 (0:00:00.072) 0:00:15.076 ******
skipping: [satellite.example.com]
changed: [capsule.example.com]
changed: [docker.example.com]
changed: [monitoring.example.com]
它并不完美:看起来你会继续看到跳过系统的所有任务的跳过状态,但可能会有所帮助。
答案 3 :(得分:1)
以下内容对我的情况很有帮助,因为meta: end_play
似乎停止了所有主机的执行,而不仅仅是匹配的主机。
首先确定一个事实:
- name: Determine current version
become: yes
slurp:
src: /opt/app/CHECKSUM
register: version_check
ignore_errors: yes
- set_fact:
is_update_needed: "{{ ( version_check['checksum'] | b64decode != installer_file.stat.checksum) }}"
现在包括那个只应在这种情况下执行的部分:
# update-app.yml can be placed in the same role folder
- import_tasks: update-app.yml
when: is_update_needed
答案 4 :(得分:1)
只需注意一点:meta: end_play
仅结束剧本,而不结束剧本。所以这本剧本:
---
- name: 1st play with end play
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: I'll always be printed
debug:
msg: next task terminates first play
- name: Ending the 1st play now
meta: end_play
- name: I want to be printed!
debug:
msg: However I'm unreachable so this message won't appear in the output
- name: 2nd play
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: I will also be printed always
debug:
msg: "meta: end_play ended just the 1st play. This is 2nd one."
将产生以下输出:
$ ansible-playbook -i localhost, playbooks/end_play.yml
PLAY [1st play with end play] **************************************************
TASK [I'll always be printed] **************************************************
ok: [localhost] => {
"msg": "next task terminates first play"
}
PLAY [2nd play] ****************************************************************
TASK [I will also be printed always] *******************************************
ok: [localhost] => {
"msg": "meta: end_play ended just the 1st play. This is 2nd one."
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
答案 5 :(得分:0)
您可以这样做,使断言条件为假
- name: WE ARE DONE. EXITING
assert:
that:
- "'test' in 'stop'