diff options
Diffstat (limited to 'lib/spack/llnl/util/filesystem.py')
-rw-r--r-- | lib/spack/llnl/util/filesystem.py | 40 |
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=[]): |