Ansible - 模式755用于目录,644用于文件递归

myk*_*ola 63 file-permissions ansible

我想允许任何人列出并读取目录树中的所有文件,但我不想让文件可执行:

dir
  \subdir1
      file1
  \subdir2
      file2
  ...
  \subdirX
      fileX
Run Code Online (Sandbox Code Playgroud)

以下任务使我的目录和文件可读,但它使所有文件也可执行:

- name: Make my directory tree readable
  file:
    path: dir
    mode: 0755
    recurse: yes
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我选择模式0644,那么我的所有文件都不可执行,但我无法列出我的目录.

是否可以为所有目录设置模式755,为目录树中的所有文件设置644?

谢谢.

Adr*_*erc 94

从1.8版开始,Ansible支持符号模式.因此,以下将执行您想要的任务:

- name: Make my directory tree readable
  file:
    path: dir
    mode: u=rwX,g=rX,o=rX
    recurse: yes
Run Code Online (Sandbox Code Playgroud)

因为X(而不是x)仅适用于至少设置了一个x位的目录或文件.

  • 我不会说这是一个完整的解决方案.如果您取消归档具有各种权限的内容(例如,所有文件和目录都设置为755),则不会执行任何操作.假设您想要仅将文件更改为644,则不能,因为它们都至少设置了一个x位.ansible需要的是一种递归目录的方法,只针对文件并相应地更新它们,如果没有一些解决方法,这似乎是不可能的. (8认同)
  • 这是最好且最短的解决方案 (2认同)
  • IIRC,虽然这个工作,它会执行得非常慢,因为它使用`stat`来单独检查每个文件/文件夹.在盒子上调用`chmod`要快得多 (2认同)
  • `chmod` 也会使用 `stat(2)`。你可以用“strace”看到这一点。它可能会更快,因为 ansible 可能会在 python 中实现它。 (2认同)
  • 得到'失败!=> {"已更改":false,"failed":true,"msg":"递归选项要求状态为'目录'","路径":"dir","状态":"缺席"} (2认同)

Bru*_*e P 25

Ansible文件/副本模块没有为您提供基于文件类型指定权限的粒度,因此您很可能需要通过以下方式执行此操作来手动执行此操作:

- name: Ensure directories are 0755
  command: find {{ path }} -type d -exec chmod -c 0755 {} \;
  register: chmod_result
  changed_when: "chmod_result.stdout != \"\""

- name: Ensure files are 0644
  command: find {{ path }} -type f -exec chmod -c 0644 {} \;
  register: chmod_result
  changed_when: "chmod_result.stdout != \"\""
Run Code Online (Sandbox Code Playgroud)

这些将具有递归{{ path }}和将每个文件或目录的权限更改为指定权限的效果.

  • 实际上,这是一种解决方法,而不是解决方案.此任务的状态始终"已更改",因此不断运行以确保配置一致无效. (4认同)
  • 语义.除非有人愿意编写模块,shell脚本等来执行此操作并向Ansible报告是否有任何更改,然后这是唯一的解决方案.最初的问题并未指明需要,只是希望根据文件与目录递归更改权限. (4认同)
  • 将提出一个很好的功能请求:https://github.com/ansible/ansible/issues (3认同)
  • @mykola你可以尝试`chmod -c`并使用`changed_when`条件. (3认同)

wol*_*evo 7

由于“不充分”的实现,Ansible 仅部分支持符号模式(请参阅下面的解释)。

除了使用命令行之外chmod,使用 Ansible 将模式设置为u=rwX,g=rX,o=rX并不总是足以将文件设置为 644。生成的权限还将取决于文件的原始模式!

正如chmod该问题的其他答案的一些评论中所述,并且已经指出:如果u、或g的文件权限o是可执行的,则X也将文件权限设置为x

例如。如果一个文件的模式为 740 ,使用 ansible-rwxr-----设置模式,您将得到 755而不是预期的 644 。尽管这不是您想要的,但它将使文件可由组和其他存在不需要的安全问题的人执行。u=rwX,g=rX,o=rX-rwxr-xr-x-rw-r--r--

在这些情况下,使用 Ansible,您需要两个步骤将文件权限设置为 644。

- file:
    path: /path/to/dir
    state: directory
    recurse: yes
    mode: '{{ item }}'
  loop:
    - '-x'
    - 'u=rwX,g=rX,o=rX'
Run Code Online (Sandbox Code Playgroud)
  • 请注意,如果您想要文件的模式 744 u=rwx,g=rX,o=rX(第一x个小写!)。对于当前的实现,这将在 Ansible 中工作,但这不是命令行的工作方式chmod。请参阅下面的**带* chmod 的符号节点。

为什么会这样:

Ansible 在函数中声明_symbolic_mode_to_octal包含以下内容u=rw-x+X,g=r-x+X,o=r-x+X:尽管如此,如果给定的模式是g=-x+X,ansible 会忽略-xperm。该函数_symbolic_mode_to_octal迭代给定的权限,当涉及到X该函数时_get_octal_mode_from_symbolic_perms,不会将请求的权限与已应用的权限进行比较,而是与原始权限进行比较,从而忽略它:

这可能是 Ansible 中的一个错误。

最简单有效的方法是委托给 shell 命令:正如@BruceP's 答案中所建议的。

如果由于某种原因您不愿意使用“解决方法”并且需要一种可靠的方法来解决问题并且您不关心性能,您可以尝试以下方法:

注意:这将需要非常非常长的时间,具体取决于文件和目录的数量!

- name: example
  hosts: 192.168.111.123
  become: yes
  gather_facts: no
  vars:
    path_to_dir: /path/to/dir
    target_mode_for_directories: 755
    target_mode_for_files: 644
  tasks:
    - name: collect list of directories '{{ path_to_dir }}'
      find:
        paths: '{{ path_to_dir }}'
        recurse: yes
        file_type: directory
      register: found_directories
    - name: set collected directories to mode '{{ target_mode_for_directories }}'
      file:
        dest: '{{ item.path }}'
        mode: '{{ target_mode_for_directories }}'
      loop: '{{ found_directories.files }}'
    - name: collect list of files under '{{ path_to_dir }}'
      find:
        paths: '{{ path_to_dir }}'
        recurse: yes
        file_type: file
      register: found_files
    - name: set collected files to mode '{{ target_mode_for_files }}'
      file:
        dest: '{{ item.path }}'
        mode: '{{ target_mode_for_files }}'
      loop: '{{ found_files.files }}'

Run Code Online (Sandbox Code Playgroud)

使用 chmod 的符号模式

请记住,设置符号模式chmod可能非常棘手。请参阅以下示例,这些示例仅在小写和大写的顺序上有所不同X,即u=X,g=X,o=x(o=小写 x) 与u=x,g=X,o=X(u=小写 x) ,结果为001 ---------xvs. 111 ---x--x--x

$ sudo chmod -R 000 path/to/file; \
  sudo chmod -R u=X,g=X,o=x path/to/file; \
  sudo find path/to/file -printf ""%03m" "%M" "%p\\n"";

001 ---------x path/to/file

$ sudo chmod -R 000 path/to/file; \
  sudo chmod -R u=x,g=X,o=X path/to/file; \
  sudo find path/to/file -printf ""%03m" "%M" "%p\\n"";

111 ---x--x--x path/to/file

Run Code Online (Sandbox Code Playgroud)

这是因为首先处理 for 的权限u,然后处理 for g,最后处理 for o。在第一个示例中,X不会申请文件,因为没有x权限。在第二种情况下,将在设置X后应用文件,从而设置和u=xg=xo=x