Friday, April 1, 2022

[SOLVED] Does path.mkdir()'s updates the file permissions if path already exists and mode is passed?

Issue

I have a volume attached in kubernetes with path /var/www/aaa/tmp.

That volume was created using href="https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir" rel="nofollow noreferrer">path.mkdir() and currently have 755 permissions. It was created with code path.mkdir(parents=True, exist_ok=True) initially.

I'm trying to update its permissions without deleting the existing path.

I'm using path.mkdir(parents=True, exist_ok=True, mode=0o777). I'm still facing issues related to permissions and getting 502 Bad gateway for the flask app that is creating the above directories.

Does the path.mkdir(parents=True, exist_ok=True, mode=0o777) updates the path permissions if it already exists and have 755 permissions? Or will it ignore it completely as we've mentioned exists_ok=True ? I don't see the permissions getting updated for the path.

Should I be deleting the path completely and re-running the path.mkdir..... with mode=0o777 which creates new directories and set permissions?

Edit 1: I've tried using os.chmod() on the path. But it's throwing PermissionError.

Here's the code snippet.

path.mkdir(parents=True, exist_ok=True)
os.chmod(path, mode=0o777)

Error:

File "./app/init.py", line 79, in create_prediction_app create_directories(app) File "./app/init.py", line 36, in create_directories os.chmod(path, mode=0o777) PermissionError: [Errno 1] Operation not permitted: '/var/www/aaa/tmp' unable to load app 0 (mountpoint='') (callable not found or import error) * no app loaded. GAME OVER *


Solution

If the path is already existing, you should use the os.chmod(path, mode) instead of deleting/re-creating.

For example:

import os

os.chmod("/var/www/aaa/tmp", 0o777)

Furthermore, the chmod can get the permission from stat module.

  • stat.S_ISUID − Set user ID on execution.
  • stat.S_ISGID − Set group ID on execution.
  • stat.S_ENFMT − Record locking enforced.
  • stat.S_ISVTX − Save text image after execution.
  • stat.S_IREAD − Read by owner.
  • stat.S_IWRITE − Write by owner.
  • stat.S_IEXEC − Execute by owner.
  • stat.S_IRWXU − Read, write, and execute by owner.
  • stat.S_IRUSR − Read by owner.
  • stat.S_IWUSR − Write by owner.
  • stat.S_IXUSR − Execute by owner.
  • stat.S_IRWXG − Read, write, and execute by group.
  • stat.S_IRGRP − Read by group.
  • stat.S_IWGRP − Write by group.
  • stat.S_IXGRP − Execute by group.
  • stat.S_IRWXO − Read, write, and execute by others.
  • stat.S_IROTH − Read by others.
  • stat.S_IWOTH − Write by others.
  • stat.S_IXOTH − Execute by others.

For example:

import os
import stat

# Set a file write by others.
os.chmod("/var/www/aaa/tmp", stat.S_IWOTH)

You can set more permission with the bitwise operator.

For example:

import os
import stat

os.chmod(
    '/var/www/aaa/tmp',
    stat.S_IRUSR |
    stat.S_IROTH |
    stat.S_IRGRP 
)

Complete testing:

>>> touch test_perm.sh
>>> ll test_perm.sh
-rw-rw-r-- test_perm.sh
>>> python -c "import os; os.chmod('test_perm.sh', 0755)"
>>> ll test_perm.sh
-rwxr-xr-x test_perm.sh

EDIT:

If you get PermissionError: [Errno 1] Operation not permitted:... exception when you want to change the permission with os.chmod, you should try the following code part to solve it. It's important to run the script with admin rights (with sudo in Linux environment).

Code:

from getpwnam import pwd
from getgrnam import grp
import os

uid = getpwnam("USERNAME")[2]
gid = grp.getgrnam("GROUPNAME")[2]
os.chown("/var/www/aaa/tmp", uid, gid)

Based on the official chown documentation:

os.chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)

Change the owner and group id of path to the numeric uid and gid. To leave one of the ids unchanged, set it to -1.

This function can support specifying a file descriptor, paths relative to directory descriptors and not following symlinks.

See shutil.chown() for a higher-level function that accepts names in addition to numeric ids.

Availability: Unix.

New in version 3.3: Added support for specifying path as an open file descriptor, and the dir_fd and follow_symlinks arguments.

Changed in version 3.6: Supports a path-like object.

Link to documentation: https://docs.python.org/3/library/os.html#os.chown



Answered By - milanbalazs
Answer Checked By - Senaida (WPSolving Volunteer)