pyinfra-dev / pyinfra

pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands.
https://pyinfra.com
MIT License
3.91k stars 382 forks source link

files.sync ignores mode on destination directory #736

Open si14 opened 2 years ago

si14 commented 2 years ago

files.sync always applies host's file permission on the destination directory regardless of mode in the command: https://github.com/Fizzadar/pyinfra/blob/ff0913d6a172966760b63fe59e55dff9ea852e0d/pyinfra/operations/files.py#L573

It might be the intended behaviour, but it's fairly surprising, as code like this

files.sync(
    name="Sync static",
    sudo=True,
    src=str(HOST_REPO_ROOT / "staticweb"),
    dest=str(TARGET_ROOT / "staticweb"),
    user="root",
    group="www-data",
    mode=660,
)

might lead to staticweb being listable for everyone on the target host.

sysadmin75 commented 2 years ago

I'm unable to reproduce this issue. The files permissions and ownership in the deploy are honored.

Maybe this has been fixed since you opened the issue. Maybe update your version and try again.

If you still have this issue, then provide more details on reproducing.

filips123 commented 2 years ago

This still happens to me on the latest version from PyPI. I created a simple example repo. After running pyinfra inventory.py deploy.py, everything is uploaded to the server. However, only files are given the specified permissions, while directories are set to 777:

$ ls -al /opt/test/
total 12
drwxrwxrwx 3 root root 4096 Aug  9 19:25 ./
drwxr-xr-x 5 root root 4096 Aug  9 19:25 ../
-rw-r--r-- 1 root root    0 Aug  9 19:25 first.txt
drwxrwxrwx 2 root root 4096 Aug  9 19:25 nested/
-rw-r--r-- 1 root root    0 Aug  9 19:25 second.txt

$ ls -al /opt/test/nested/
total 8
drwxrwxrwx 2 root root 4096 Aug  9 19:25 ./
drwxrwxrwx 3 root root 4096 Aug  9 19:25 ../
-rw-r--r-- 1 root root    0 Aug  9 19:25 third.txt

Output of pyinfra --support:

    System: Windows
      Platform: Windows-10-10.0.19044-SP0
      Release: 10
      Machine: AMD64
    pyinfra: v2.3
    Executable: C:\Users\filips\AppData\Local\Temp\pyinfra-permissions-bug\venv\Scripts\pyinfra.exe
    Python: 3.10.5 (CPython, MSC v.1929 64 bit (AMD64))

Computer where I run pyinfra has Windows 10. Target host has Debian 11 and is accessed over SSH.


Changing the code to mode=mode or ... for both yield from directory-ies fixes the issue. However, it would probably be better to create an additional dir_mode parameter, as sometimes you want directories to have different permissions than files (e.g, +x attribute). I can create a PR for this.