summaryrefslogtreecommitdiff
path: root/lib/spack/llnl/util/filesystem.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/llnl/util/filesystem.py')
-rw-r--r--lib/spack/llnl/util/filesystem.py40
1 files changed, 25 insertions, 15 deletions
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index e44f8c608f..f3c2ee5ab1 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -656,6 +656,12 @@ def working_dir(dirname, **kwargs):
os.chdir(orig_dir)
+class CouldNotRestoreDirectoryBackup(RuntimeError):
+ def __init__(self, inner_exception, outer_exception):
+ self.inner_exception = inner_exception
+ self.outer_exception = outer_exception
+
+
@contextmanager
def replace_directory_transaction(directory_name, tmp_root=None):
"""Moves a directory to a temporary space. If the operations executed
@@ -683,29 +689,33 @@ def replace_directory_transaction(directory_name, tmp_root=None):
assert os.path.isabs(tmp_root)
tmp_dir = tempfile.mkdtemp(dir=tmp_root)
- tty.debug('TEMPORARY DIRECTORY CREATED [{0}]'.format(tmp_dir))
+ tty.debug('Temporary directory created [{0}]'.format(tmp_dir))
shutil.move(src=directory_name, dst=tmp_dir)
- tty.debug('DIRECTORY MOVED [src={0}, dest={1}]'.format(
- directory_name, tmp_dir
- ))
+ tty.debug('Directory moved [src={0}, dest={1}]'.format(directory_name, tmp_dir))
try:
yield tmp_dir
- except (Exception, KeyboardInterrupt, SystemExit):
- # Delete what was there, before copying back the original content
- if os.path.exists(directory_name):
- shutil.rmtree(directory_name)
- shutil.move(
- src=os.path.join(tmp_dir, directory_basename),
- dst=os.path.dirname(directory_name)
- )
- tty.debug('DIRECTORY RECOVERED [{0}]'.format(directory_name))
+ except (Exception, KeyboardInterrupt, SystemExit) as inner_exception:
+ # Try to recover the original directory, if this fails, raise a
+ # composite exception.
+ try:
+ # Delete what was there, before copying back the original content
+ if os.path.exists(directory_name):
+ shutil.rmtree(directory_name)
+ shutil.move(
+ src=os.path.join(tmp_dir, directory_basename),
+ dst=os.path.dirname(directory_name)
+ )
+ except Exception as outer_exception:
+ raise CouldNotRestoreDirectoryBackup(inner_exception, outer_exception)
+
+ tty.debug('Directory recovered [{0}]'.format(directory_name))
raise
else:
# Otherwise delete the temporary directory
- shutil.rmtree(tmp_dir)
- tty.debug('TEMPORARY DIRECTORY DELETED [{0}]'.format(tmp_dir))
+ shutil.rmtree(tmp_dir, ignore_errors=True)
+ tty.debug('Temporary directory deleted [{0}]'.format(tmp_dir))
def hash_directory(directory, ignore=[]):