繁体   English   中英

Ansible 和/或 Jinja2 中的子字符串

[英]SubString in Ansible and/or 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)

如果item匹配excluded列表中的任何内容,则上述表达式将生成一个非空列表(在布尔上下文中使用时其计算结果为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

如果由于匹配路径而不想排除挂载项,请迭代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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM