Ansible - 检查是否存在多个目录 - 如果存在 运行 每个目录上的脚本 - 如何?
Ansible - Check if multiple directories exist - if so run a script on each directory - How?
我正在为我们的 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
这将让您将现有目录名称的列表放入列表变量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 在 "Stop services" 任务中使用 dir_names
。看起来你打算只使用 "webapps" 下的目录名称,所以你可能想使用 | basename
jinja2 过滤器来获取它,所以像这样:
- name: Stop services
with_items: "{{ dir_names }}"
shell: "/webapps/scripts/stopService.sh {{item | basename }}"
我会先收集事实,然后只做必要的事情。
- 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 起不再起作用,因此您应该将它们模板化。
我正在为我们的 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
这将让您将现有目录名称的列表放入列表变量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 在 "Stop services" 任务中使用 dir_names
。看起来你打算只使用 "webapps" 下的目录名称,所以你可能想使用 | basename
jinja2 过滤器来获取它,所以像这样:
- name: Stop services
with_items: "{{ dir_names }}"
shell: "/webapps/scripts/stopService.sh {{item | basename }}"
我会先收集事实,然后只做必要的事情。
- 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 起不再起作用,因此您应该将它们模板化。