Ansible 和/或 Jinja2 中的子字符串



我正在尝试取消所有挂载点,除非它们是当前列表的一部分:

excluded: ['home', 'cdrom', 'tmpfs', 'sys', 'run', 'dev', 'root']

仅 fstab 设备示例:

/
  • dev/mapper/vgroot-local_home
  • devtmpfs
  • TMPFS

应从卸载中排除/dev/mapper/vgroot-local_home,因为子字符串home存在于数组上,并且devtmpfs子字符串tmpfs也是如此。对于tmpfs,我们有一个完美的匹配。目标是检查设备。

在检查了所有 Ansible 过滤器和 Jinja2 文档后,我没有找到解决此问题的方法。收集所有 Ansible 事实。

- name: Ensure the mountpoint is on the excluded list
ansible.posix.mount:
path: '{{ mount.device }}'
state: unmounted
when: {{ ??? }}
with_items: '{{ ??? }}'
become: true
tags: mountpoints

为了测试一个字符串是否包含 Jinja 中的子字符串,我们使用in测试,非常类似于 Python:

"somestring" in somevariable

在您的情况下,您要检查给定字符串是否包含excluded列表中的任何子字符串。从概念上讲,我们想要的是类似于Python表达式的东西。

if any(x in mount.device for x in excluded)

使用 Jinja 过滤器,我们需要稍微颠倒一下我们的逻辑。 我们 可以使用select筛选器从excluded给定目标字符串中包含的列表(例如mount.device) 像这样:

excluded|select('in', item)

如果itemexcluded列表中的任何内容匹配,则上述 表达式将生成一个非空列表(计算结果为true在布尔上下文中使用时)。

在剧本中使用,它看起来像这样:

- hosts: localhost
gather_facts: false
vars:
excluded: ['home', 'cdrom', 'tmpfs', 'sys', 'run', 'dev', 'root']
mounts:
- /dev/mapper/vgroot-local_home
- devtmpfs
- tmpfs
- something/else
tasks:
- debug:
msg: "unmount {{ item }}"
when: not excluded|select('in', item)
loop: "{{ mounts }}"

上述剧本生成为输出:

TASK [debug] *******************************************************************
skipping: [localhost] => (item=/dev/mapper/vgroot-local_home) 
skipping: [localhost] => (item=devtmpfs) 
skipping: [localhost] => (item=tmpfs) 
ok: [localhost] => (item=something/else) => {
"msg": "unmount something/else"
}

也就是说,当当前循环项包含excluded列表中的子字符串。

假设您的目标是"卸载除以下文件系统之外的所有文件系统 设备名称包含excluded列表中的子字符串", 你可以这样写:

- name: Unmount filesystems that aren't excluded
ansible.posix.mount:
path: '{{ mount.device }}'
state: unmounted
when: not excluded|select('in', item.device)
loop: "{{ ansible_mounts }}"
become: true
tags: mountpoints

如果您不想因为匹配路径而排除挂载的项目,例如,如果您不想排除/dev/mapper/vgroot-local_home,因为排除列表中的dev而迭代基本名称

- debug:
msg: "Unmount {{ item }}"
loop: "{{ mounts|map('basename') }}"
when: not excluded|select('in', item)

最新更新