我希望能够保证在给定主机上成功执行长时间运行的 shell 命令后,它不会在该主机上的后续 playbook 运行中执行。
我很高兴得知 creates
Ansible shell 任务的选项(参见 http://docs.ansible.com/ansible/shell_module.html);使用它,我可以在 shell 命令成功后创建一个文件,并且在以后的运行中不执行该命令:
- name: Install Jupiter theme
shell: wp theme install ~/downloads/jupiter-theme.zip --activate
&& touch ~/ansible-flags/install-jupiter-theme
args:
creates: ~/ansible-flags/install-jupiter-theme
如您所见,我有一个目录
ansible-flags
对于我的事件用户( deploy
)的主目录中的这些控制文件。然而,这真是一团糟。有一个更好的方法吗?
此外,当我需要以不同的用户身份运行一个步骤时,情况会变得更加复杂;在这种情况下,我无权访问
deploy
主目录及其子目录。当然,我可以授予访问权限,但这会增加更多的复杂性。你会建议我如何处理这个问题?
最佳答案
你的剧本应该是幂等的!
因此,任何一个任务都应该可以安全地执行多次(例如 echo ok
),或者您应该检查是否应该执行它。
您的任务可能如下所示:
- name: Install Jupiter theme
shell: wp theme is-installed jupiter || wp theme install ~/downloads/jupiter-theme.zip --activate
它将检查是否安装了 jupiter 主题并运行
wp theme install
仅当未安装主题时。但这会将任务的结果标记为
changed
任何状况之下。为了让它更好,你可以这样做:
- name: Install Jupiter theme
shell: wp theme is-installed jupiter && echo ThemeAlreadyInstalled || wp theme install ~/downloads/jupiter-theme.zip --activate
register: cmd_result
changed_when: cmd_result.stdout != "ThemeAlreadyInstalled"
首先,它会检查是否已经安装了 jupiter 主题。
如果是这种情况,它将输出
ThemeAlreadyInstalled
并退出。否则它会调用
wp theme install
.任务的结果被注册到
cmd_result
.我们用户
changed_when
参数来说明如果 ThemeAlreadyInstalled
ansible 不应将任务视为已更改,因此它在您的剧本输出中保持绿色。如果你之前做一些准备工作
wp theme install
(例如下载主题),您可能希望将测试作为单独的任务运行以注册结果并使用 when
后续任务中的条款:- name: Check Jupiter theme is installed
shell: wp theme is-installed jupiter && echo Present || echo Absent
register: wp_theme
changed_when: false
- name: Download theme
get_url: url=...
when: wp_theme.stdout == "Absent"
- name: Install Jupiter theme
shell: wp theme install ~/downloads/jupiter-theme.zip --activate
when: wp_theme.stdout == "Absent"
关于shell - 如何确保每个主机只执行一次 Ansible shell 命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38244985/