Skip to content

Commit 750504e

Browse files
committed
Ensure correct permissions for copied files, even if an error happens during copying
1 parent d99a064 commit 750504e

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

nbgrader/exchange/default/exchange.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -97,31 +97,36 @@ def do_copy(self, src, dest, log=None):
9797
self.log.error("Directory size is too big")
9898
raise RuntimeError(f"Directory size is too big. Size is {dir_size}, maximum size is {1000 * max_dir_size}")
9999

100-
shutil.copytree(src, dest,
101-
ignore=ignore_patterns(exclude=self.coursedir.ignore,
102-
include=self.coursedir.include,
103-
max_file_size=self.coursedir.max_file_size,
104-
log=self.log))
105-
# copytree copies access mode too - so we must add go+rw back to it if
106-
# we are in groupshared.
107-
if self.coursedir.groupshared:
108-
for dirname, _, filenames in os.walk(dest):
109-
# dirs become ug+rwx
110-
st_mode = os.stat(dirname).st_mode
111-
if st_mode & 0o2770 != 0o2770:
112-
try:
113-
os.chmod(dirname, (st_mode|0o2770) & 0o2777)
114-
except PermissionError:
115-
self.log.warning("Could not update permissions of %s to make it groupshared", dirname)
116-
117-
for filename in filenames:
118-
filename = os.path.join(dirname, filename)
119-
st_mode = os.stat(filename).st_mode
120-
if st_mode & 0o660 != 0o660:
100+
try:
101+
shutil.copytree(src, dest,
102+
ignore=ignore_patterns(exclude=self.coursedir.ignore,
103+
include=self.coursedir.include,
104+
max_file_size=self.coursedir.max_file_size,
105+
log=self.log))
106+
except OSError as err:
107+
raise err
108+
# Set permissions for copied files, even if some failed to copy
109+
finally:
110+
# copytree copies access mode too - so we must add go+rw back to it if
111+
# we are in groupshared.
112+
if self.coursedir.groupshared:
113+
for dirname, _, filenames in os.walk(dest):
114+
# dirs become ug+rwx
115+
st_mode = os.stat(dirname).st_mode
116+
if st_mode & 0o2770 != 0o2770:
121117
try:
122-
os.chmod(filename, (st_mode|0o660) & 0o777)
118+
os.chmod(dirname, (st_mode|0o2770) & 0o2777)
123119
except PermissionError:
124-
self.log.warning("Could not update permissions of %s to make it groupshared", filename)
120+
self.log.warning("Could not update permissions of %s to make it groupshared", dirname)
121+
122+
for filename in filenames:
123+
filename = os.path.join(dirname, filename)
124+
st_mode = os.stat(filename).st_mode
125+
if st_mode & 0o660 != 0o660:
126+
try:
127+
os.chmod(filename, (st_mode|0o660) & 0o777)
128+
except PermissionError:
129+
self.log.warning("Could not update permissions of %s to make it groupshared", filename)
125130

126131
def start(self):
127132
if sys.platform == 'win32':

0 commit comments

Comments
 (0)