Ansible - Mode 755 for directories and 644 for files recursively

后端 未结 4 1941
难免孤独
难免孤独 2021-01-31 01:15

I\'d like to allow anyone to list and read all files in my directory tree, but I don\'t want to make the files executable :

dir
  \\subdir1
      file1
  \\subdi         


        
4条回答
  •  执念已碎
    2021-01-31 01:56

    Due to a "inadequate" implementation Ansible supports symbolic modes only partially (see explanation below).

    Other than using the command line chmod, setting mode to u=rwX,g=rX,o=rX with Ansible will not allways be sufficient to get your files set to 644. The resulting permissions will also depend on the original mode of the file!

    As stated in the docs for chmod and already pointed out by some comments to other answers of this question: If file permission for either u, g, or o is executable, then X will set the file permission also to x.

    For example. If one file has mode 740 -rwxr-----, setting mode u=rwX,g=rX,o=rX with ansible, you will get 755 -rwxr-xr-x instead the expected 644 -rw-r--r--. Despite that this is not what you wanted, it will make the file executable by group and others with unwanted security problems.

    In those cases, with Ansible you will need two steps to set file the permissions to 644.

    - file:
        path: /path/to/dir
        state: directory
        recurse: yes
        mode: '{{ item }}'
      loop:
        - '-x'
        - 'u=rwX,g=rX,o=rX'
    
    • Note that if you wanted mode 744 for files you'll need u=rwx,g=rX,o=rX (first x lowercase!). This will work in Ansible as for the current implementation BUT this is not the way command line chmod works. See **Symbolic nodes with* chmod below.

    Why is this so:

    Ansible states in the function _symbolic_mode_to_octal to include things like: u=rw-x+X,g=r-x+X,o=r-x+X. Nonetheless if the given mode is g=-x+X, ansible ignores the -x perm. The function _symbolic_mode_to_octal iterates over the given permissions, when it comes to X the function _get_octal_mode_from_symbolic_perms doesn't compare the requested permissions to the already applied but to the original ones, thus ignoring it:

    This is probably a bug in Ansible.

    The simplest and efficient way is to delegate to a shell command: As proposed in @BruceP's answer.

    If for some reason you are averse to use 'workarounds' and need an ansible-ish way to solve the problem AND you don't care about performance you could try the following:

    NOTE: This will take very, very long depending on the number of files and directories!

    - 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 }}'
    
    

    Symbolic modes with chmod

    Remember that setting symbolic modes with chmod can be very tricky. See the following examples that simply differ on the order of lowercase and uppercase X, i.e. u=X,g=X,o=x (o=lowercase x) vs. u=x,g=X,o=X (u=lowercase x) which results in 001 ---------x vs. 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
    
    

    This is due to the fact that the perms are processed first for u, then for g and last for o. In the first example X won't apply for files because there is no x perm. In the second case X will apply for files after u=x has been set, thus setting both g=x and o=x

提交回复
热议问题