在我的 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 }}"