如何从 ansible 列表中删除项目?

如何从 ansible 列表中删除项目?

在我的 Ansible 剧本中,我需要更改许多文件的权限,但一些子目录需要读写权限,而大多数子目录需要只读权限。根据超级用户的另一个建议,我有这个解决方案:

- name: A few directories need group-write permissions
  file:
    path: "{{item}}"
    mode: "u+rwX,g+rwX,o+rX,o-w"
    recurse: True
  with_items:
    - /opt/myapp/path1/excludeddir1
    - /opt/myapp/path1/excludeddir2
    - /opt/myapp/path2/excludeddir1
    - /opt/myapp/path2/excludeddir2

- name: For performance, set a lot of directories directly
  file:
    path: "{{item}}"
    mode: "u+rwX,go+rX,go-w"
    recurse: True
  with_items:
    - /opt/myapp/path1/readonlydir1
    - /opt/myapp/path1/readonlydir2

#############################################
# This step generates a very large list
- name: Find all files in my directory
  find:
    paths:
      - "/opt/myapp/path1"
      - "/opt/myapp/path2"
    recurse: True
    file_type: any
    follow: False
  register: filestochange

#############################################
# This step is painfully slow
- name: Clear group-write permissions where needed
  file:
    path: "{{ item.path }}"
    mode: "u+rwX,go+rX,go-w"
    follow: False
  when:
    - not item.islnk
    - "'/opt/myapp/path1/excludeddir1' not in item.path"
    - "'/opt/myapp/path1/excludeddir2' not in item.path"
    - "'/opt/myapp/path2/excludeddir1' not in item.path"
    - "'/opt/myapp/path2/excludeddir2' not in item.path"
    - "'/opt/myapp/path1/readonlydir1' not in item.path
    - "'/opt/myapp/path1/readonlydir2' not in item.path
  loop: "{{ filestochange.files }}"
  loop_control:
    label: "{{ item.path }}"

涉及的子目录总共有大约100k个文件。

上述代码可以运行,但速度慢得令人难以忍受。最初的实现非常幼稚,连续运行了两天。

我的第一个优化是设置一些不需要例外的子目录的权限,然后在循环中跳过它们。这在一定程度上有所帮助;时间现在减少到一两个小时。

作为下一个优化,我想在将其输入循环之前从 find 模块生成的列表中删除相同的条目,但我还没有找到这样做的方法。

文件模块确实有一个排除属性,但它似乎只匹配文件名,而不是目录名。

因此,我正在寻找一种方法来从列表中删除与某些通配符模式匹配的项目。

当然,我也愿意接受任何其他关于如何进一步优化这一点的建议。

注意:这种简单的实现不起作用,因为它会重置,然后设置权限。

- name: Set everything to G read-only
  file:
    path: "{{item}}"
    mode: "u+rwX,go+rX,go-w"
    recurse: True
  with_items:
    - /opt/myapp/path1
    - /opt/myapp/path2

- name: A few directories need group-write permissions
  file:
    path: "{{item}}"
    mode: "u+rwX,g+wrX,o+rX,o-w"
    recurse: True
  with_items:
    - /opt/myapp/path1/excludeddir1
    - /opt/myapp/path1/excludeddir2
    - /opt/myapp/path2/excludeddir1
    - /opt/myapp/path2/excludeddir2

答案1

您可以尝试拒绝过滤器,例如:

set_fact:
  new_list: "{{ old_list | reject('search', 'SOME WORD') | list }}"

相关内容