[PATCH 1/3] Add a function to recursively change owner of a directory
Vratislav Podzimek
vpodzime at redhat.com
Wed Jun 5 12:17:19 UTC 2013
Implemented by using a universal function for mapping a function on the
directory tree.
Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
pyanaconda/iutil.py | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index 7020da5..ff36405 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -628,3 +628,79 @@ def cmp_obj_attrs(obj1, obj2, attr_list):
else:
return False
return True
+
+def dir_tree_map(root, func, files=True, dirs=True):
+ """
+ Apply the given function to all files and directories in the directory tree
+ under the given root directory.
+
+ :param root: root of the directory tree the function should be mapped to
+ :type root: str
+ :param func: a function taking the directory/file path
+ :type func: path -> None
+ :param files: whether to apply the function to the files in the dir. tree
+ :type files: bool
+ :param dirs: whether to apply the function to the directories in the dir. tree
+ :type dirs: bool
+
+ TODO: allow using globs and thus more trees?
+
+ """
+
+ for (dir_ent, dir_items, file_items) in os.walk(root):
+ if dirs:
+ # try to call the function on the directory entry
+ try:
+ func(dir_ent)
+ except:
+ pass
+
+ if files:
+ # try to call the function on the files in the directory entry
+ for file_ent in (os.path.join(dir_ent, f) for f in file_items):
+ try:
+ func(file_ent)
+ except:
+ pass
+
+ # directories under the directory entry will appear as directory entries
+ # in the loop
+
+def chown_dir_tree(root, uid, gid, from_uid_only=None, from_gid_only=None):
+ """
+ Change owner (uid and gid) of the files and directories under the given
+ directory tree (recursively).
+
+ :param root: root of the directory tree that should be chown'ed
+ :type root: str
+ :param uid: UID that should be set as the owner
+ :type uid: int
+ :param gid: GID that should be set as the owner
+ :type gid: int
+ :param from_uid_only: if given, the owner is changed only for the files and
+ directories owned by that UID
+ :type from_uid_only: int or None
+ :param from_gid_only: if given, the owner is changed only for the files and
+ directories owned by that GID
+ :type from_gid_only: int or None
+
+ """
+
+ def conditional_chown(path, uid, gid, from_uid=None, from_gid=None):
+ stats = os.stat(path)
+ if (from_uid and stats.st_uid != from_uid) or \
+ (from_gid and stats.st_gid != from_gid):
+ # owner UID or GID not matching, do nothing
+ return
+
+ # UID and GID matching or not required
+ os.chown(path, uid, gid)
+
+ if not from_uid_only and not from_gid_only:
+ # the easy way
+ dir_tree_map(root, lambda path: os.chown(path, uid, gid))
+ else:
+ # conditional chown
+ dir_tree_map(root, lambda path: conditional_chown(path, uid, gid,
+ from_uid_only,
+ from_gid_only))
--
1.7.11.7
More information about the anaconda-patches
mailing list