def ensure_dirs_gw(path, _parent_mode=False):
"""Ensure that path is a directory by creating it and parents if
necessary. Also ensure that it is group-writeable and
-executable, and setgid. All created parent directories get their
mode bits set comparably.
This is a fairly specialized function used in support of the NRAO
Lustre staging feature.
Implementation copied from os.makedirs() with some tweaks.
"""
import os.path
import stat
head, tail = os.path.split(path) # /a/b/c => /a/b, c
if not len(tail): # if we got something like "a/b/" => ("a/b", "")
head, tail = os.path.split(head)
if len(head) and head != '/':
ensure_dirs_gw(head, _parent_mode=True)
try_chmod = not _parent_mode # deepest directory must be g+wxs
try:
# Note: the `mode` passed to mkdir is altered by the umask, which may
# remove the group-write bit we want, so we can't rely on it to set
# permissions correctly.
os.mkdir(path)
try_chmod = True # we created it, so definitely chmod
except OSError as e:
if e.errno == 17:
pass # already exists; no problem, and maybe no chmod
elif e.errno == 13: # EACCES
raise Exception('unable to create directory \"%s\"; you probably '
'need to make its parent group-writeable with:\n\n'
'chmod g+wx \'%s\'' % (path, os.path.dirname(path)))
else:
raise
if try_chmod:
st = os.stat(path)
mode = stat.S_IMODE(st.st_mode)
new_mode = mode | (stat.S_IWUSR | stat.S_IWGRP | stat.S_IXUSR | stat.S_IXGRP | stat.S_ISGID)
if new_mode != mode: # avoid failure if perms are OK but we don't own the dir
try:
os.chmod(path, new_mode)
except OSError as e:
if e.errno == 1: # EPERM
raise Exception('unable to make \"%s\" group-writeable; '
'please do so yourself with:\n\nchmod g+wx \'%s\''
% (path, path))
raise
评论列表
文章目录