我正在为我们的网络服务创建部署手册。每个Web服务都在其自己的目录中,例如:
/webapps/service-one/
/webapps/service-two/
/webapps/service-three/
我想查看服务目录是否存在,如果存在,我想运行一个shell脚本来优雅地停止服务。目前,我可以使用ignore_errors: yes
完成此步骤。
- name: Stop services
with_items: services_to_stop
shell: "/webapps/scripts/stopService.sh {{item}}"
ignore_errors: yes
虽然这样可行,但如果其中一个目录不存在或者第一次部署服务,则输出非常混乱。我实际上想要其中一个:
这:
- name: Stop services
with_items: services_to_stop
shell: "/webapps/scripts/stopService.sh {{item}}"
when: shell: [ -d /webapps/{{item}} ]
或者这个:
- name: Stop services
with_items: services_to_stop
shell: "/webapps/scripts/stopService.sh {{item}}"
stat:
path: /webapps/{{item}}
register: path
when: path.stat.exists == True
答案 0 :(得分:4)
我先收集事实,然后只做必要的事情。
- name: Check existing services
stat:
path: "/tmp/{{ item }}"
with_items: "{{ services_to_stop }}"
register: services_stat
- name: Stop existing services
with_items: "{{ services_stat.results | selectattr('stat.exists') | map(attribute='item') | list }}"
shell: "/webapps/scripts/stopService.sh {{ item }}"
另请注意,with_items
中的裸变量自Ansible 2.2起不起作用,因此您应该对它们进行模板化。
答案 1 :(得分:1)
这样您就可以在列表变量dir_names
中获取现有目录名称列表(使用recurse: no
只读取webapps下的第一级别):
---
- hosts: localhost
connection: local
vars:
dir_names: []
tasks:
- find:
paths: "/webapps"
file_type: directory
recurse: no
register: tmp_dirs
- set_fact: dir_names="{{ dir_names+ [item['path']] }}"
no_log: True
with_items:
- "{{ tmp_dirs['files'] }}"
- debug: var=dir_names
然后,您可以通过with_items在“停止服务”任务中使用dir_names
。看起来你打算只使用“webapps”下的目录名称,所以你可能想使用| basename
jinja2过滤器来实现它,所以像这样:
- name: Stop services
with_items: "{{ dir_names }}"
shell: "/webapps/scripts/stopService.sh {{item | basename }}"