在我的 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 }}"
涉及的子目录共有约10万个文件。
上面的代码可以工作,但毫不奇怪,速度慢得令人痛苦。最初的大部分天真的实现连续运行了两天。
我的第一个优化是为几个不需要任何异常的子目录设置权限,然后在循环中跳过它们。这在一定程度上有所帮助;现在时间缩短到一两个小时。
作为下一个优化,我想在 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
您可以尝试拒绝过滤器,例如: