[英]SubString in Ansible and/or Jinja2
I'm trying to unmout all mountpoints, excepted if they are part of the current list:我正在尝试取消所有挂载点,除非它们是当前列表的一部分:
excluded: ['home', 'cdrom', 'tmpfs', 'sys', 'run', 'dev', 'root']
Sample fstab only devices:仅适用于 fstab 的设备示例:
/dev/mapper/vgroot-local_home
should be excluded from unmounting because the substring home
is present on the array and the same for devtmpfs
substring tmpfs
. /dev/mapper/vgroot-local_home
应该从卸载中排除,因为子字符串home
存在于阵列上,并且对于devtmpfs
子字符串tmpfs
也是如此。 For tmpfs
we have a perfect match.对于tmpfs
,我们有一个完美的匹配。 The goal is to check against devices.目标是检查设备。
After checking all Ansible filters and the Jinja2 documentation , I didn't find a solution to this problem.在检查了所有Ansible 过滤器和Jinja2 文档后,我没有找到解决这个问题的方法。 All Ansible facts are collected.收集所有 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
To test if a string contains a substring in Jinja, we use the in
test, much like Python:要在 Jinja 中测试一个字符串是否包含子字符串,我们使用in
测试,很像 Python:
"somestring" in somevariable
In your case, you want to check if a given string contains any substring from the excluded
list.在您的情况下,您想检查给定字符串是否包含excluded
列表中的任何子字符串。 Conceptually, what we want is something like the Python expression从概念上讲,我们想要的是类似于 Python 表达式的东西
if any(x in mount.device for x in excluded)
Using Jinja filters, we need to reverse our logic a little bit.使用 Jinja 过滤器,我们需要稍微反转我们的逻辑。 We can use the select
filter to get a list of strings from the excluded
list that are contained in a given target string (such as mount.device
) like this:我们可以使用select
过滤器从excluded
列表中获取包含在给定目标字符串(例如mount.device
)中的字符串列表,如下所示:
excluded|select('in', item)
If item
matches anything in the excluded
list, the above expression will result in a non-empty list (which evaluates to true
when used in a boolean context).如果item
匹配excluded
列表中的任何内容,则上述表达式将生成一个非空列表(在布尔上下文中使用时其计算结果为true
)。
Used in a playbook, it would look like this:在剧本中使用,它看起来像这样:
- 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 }}"
The above playbook produces as output:上面的剧本作为输出产生:
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"
}
That is, it skips the task when the current loop item contains a substring from the excluded
list.也就是说,当当前循环项包含excluded
列表中的子字符串时,它会跳过任务。
Assuming that your goal is "unmount all filesystems except those for which the device name contains a substring from the excluded
list", you might write:假设您的目标是“卸载所有文件系统,但设备名称包含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
Iterate basename if you don't want to exclude the items of mounts because of matching the path, eg if you don't want to exclude /dev/mapper/vgroot-local_home
because of dev
in the excluded list如果由于匹配路径而不想排除挂载项,请迭代basename ,例如,如果由于排除列表中的dev
而不想排除/dev/mapper/vgroot-local_home
- debug:
msg: "Unmount {{ item }}"
loop: "{{ mounts|map('basename') }}"
when: not excluded|select('in', item)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.