Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.buildout
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
slapos.buildout
Commits
508c6a3f
Commit
508c6a3f
authored
Dec 23, 2020
by
Thomas Gambier
🚴🏼
Browse files
Options
Browse Files
Download
Plain Diff
rmtree: import more code from slapos.core to support case of parent directory not writable
See merge request
nexedi/slapos.buildout!22
parents
44b3c076
6dcf6b6e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
39 additions
and
6 deletions
+39
-6
src/zc/buildout/rmtree.py
src/zc/buildout/rmtree.py
+39
-6
No files found.
src/zc/buildout/rmtree.py
View file @
508c6a3f
...
...
@@ -16,6 +16,8 @@
import
shutil
import
os
import
doctest
import
errno
import
sys
def
rmtree
(
path
):
"""
...
...
@@ -26,6 +28,8 @@ def rmtree (path):
Also it tries to remove symlink itself if a symlink as passed as
path argument.
Finally, it tries to make parent directory writable.
>>> from tempfile import mkdtemp
Let's make a directory ...
...
...
@@ -46,7 +50,11 @@ def rmtree (path):
and make it unwriteable
>>> os.chmod (foo, 256) # 0400
>>> os.chmod (foo, 0o400)
and make parent dir unwritable
>>> os.chmod (d, 0o400)
rmtree should be able to remove it:
...
...
@@ -89,7 +97,9 @@ def rmtree (path):
>>> os.path.isdir (d)
0
"""
def
retry_writeable
(
func
,
path
,
exc
):
def
chmod_retry
(
func
,
failed_path
,
exc_info
):
"""Make sure the directories are executable and writable.
"""
if
func
is
os
.
path
.
islink
:
os
.
unlink
(
path
)
elif
func
is
os
.
lstat
:
...
...
@@ -97,10 +107,33 @@ def rmtree (path):
raise
os
.
unlink
(
path
)
else
:
os
.
chmod
(
path
,
0o600
)
func
(
path
)
shutil
.
rmtree
(
path
,
onerror
=
retry_writeable
)
# Depending on the Python version, the following items differ.
if
sys
.
version_info
>=
(
3
,
):
expected_error_type
=
PermissionError
expected_func_tuple
=
(
os
.
lstat
,
os
.
open
)
else
:
expected_error_type
=
OSError
expected_func_tuple
=
(
os
.
listdir
,
)
e
=
exc_info
[
1
]
if
isinstance
(
e
,
expected_error_type
):
if
e
.
errno
==
errno
.
ENOENT
:
# because we are calling again rmtree on listdir errors, this path might
# have been already deleted by the recursive call to rmtree.
return
if
e
.
errno
==
errno
.
EACCES
:
if
func
in
expected_func_tuple
:
os
.
chmod
(
failed_path
,
0o700
)
# corner case to handle errors in listing directories.
# https://bugs.python.org/issue8523
return
shutil
.
rmtree
(
failed_path
,
onerror
=
chmod_retry
)
# If parent directory is not writable, we still cannot delete the file.
# But make sure not to change the parent of the folder we are deleting.
if
failed_path
!=
path
:
os
.
chmod
(
os
.
path
.
dirname
(
failed_path
),
0o700
)
return
func
(
failed_path
)
raise
shutil
.
rmtree
(
path
,
onerror
=
chmod_retry
)
def
test_suite
():
return
doctest
.
DocTestSuite
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment