Fix: --overwrite backs up old install dir, but it gets destroyed anyways (#25583)
* Make sure PackageInstaller does not remove the just-restored install dir after failure in spack install --overwrite * Remove cryptic error message and rethrow actual error
This commit is contained in:
@@ -692,7 +692,7 @@ def replace_directory_transaction(directory_name, tmp_root=None):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
yield tmp_dir
|
yield tmp_dir
|
||||||
except (Exception, KeyboardInterrupt, SystemExit) as e:
|
except (Exception, KeyboardInterrupt, SystemExit):
|
||||||
# Delete what was there, before copying back the original content
|
# Delete what was there, before copying back the original content
|
||||||
if os.path.exists(directory_name):
|
if os.path.exists(directory_name):
|
||||||
shutil.rmtree(directory_name)
|
shutil.rmtree(directory_name)
|
||||||
@@ -701,10 +701,7 @@ def replace_directory_transaction(directory_name, tmp_root=None):
|
|||||||
dst=os.path.dirname(directory_name)
|
dst=os.path.dirname(directory_name)
|
||||||
)
|
)
|
||||||
tty.debug('DIRECTORY RECOVERED [{0}]'.format(directory_name))
|
tty.debug('DIRECTORY RECOVERED [{0}]'.format(directory_name))
|
||||||
|
raise
|
||||||
msg = 'the transactional move of "{0}" failed.'
|
|
||||||
msg += '\n ' + str(e)
|
|
||||||
raise RuntimeError(msg.format(directory_name))
|
|
||||||
else:
|
else:
|
||||||
# Otherwise delete the temporary directory
|
# Otherwise delete the temporary directory
|
||||||
shutil.rmtree(tmp_dir)
|
shutil.rmtree(tmp_dir)
|
||||||
|
@@ -1569,6 +1569,9 @@ def install(self):
|
|||||||
if os.path.exists(rec.path):
|
if os.path.exists(rec.path):
|
||||||
with fs.replace_directory_transaction(
|
with fs.replace_directory_transaction(
|
||||||
rec.path):
|
rec.path):
|
||||||
|
# fs transaction will put the old prefix
|
||||||
|
# back on failure, so make sure to keep it.
|
||||||
|
keep_prefix = True
|
||||||
self._install_task(task)
|
self._install_task(task)
|
||||||
else:
|
else:
|
||||||
tty.debug("Missing installation to overwrite")
|
tty.debug("Missing installation to overwrite")
|
||||||
|
@@ -126,6 +126,31 @@ def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch):
|
|||||||
pkg.remove_prefix = instance_rm_prefix
|
pkg.remove_prefix = instance_rm_prefix
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.disable_clean_stage_check
|
||||||
|
def test_failing_overwrite_install_should_keep_previous_installation(
|
||||||
|
mock_fetch, install_mockery
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Make sure that whenever `spack install --overwrite` fails, spack restores
|
||||||
|
the original install prefix instead of cleaning it.
|
||||||
|
"""
|
||||||
|
# Do a successful install
|
||||||
|
spec = Spec('canfail').concretized()
|
||||||
|
pkg = spack.repo.get(spec)
|
||||||
|
pkg.succeed = True
|
||||||
|
|
||||||
|
# Do a failing overwrite install
|
||||||
|
pkg.do_install()
|
||||||
|
pkg.succeed = False
|
||||||
|
kwargs = {'overwrite': [spec.dag_hash()]}
|
||||||
|
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
pkg.do_install(**kwargs)
|
||||||
|
|
||||||
|
assert pkg.installed
|
||||||
|
assert os.path.exists(spec.prefix)
|
||||||
|
|
||||||
|
|
||||||
def test_dont_add_patches_to_installed_package(install_mockery, mock_fetch):
|
def test_dont_add_patches_to_installed_package(install_mockery, mock_fetch):
|
||||||
dependency = Spec('dependency-install')
|
dependency = Spec('dependency-install')
|
||||||
dependency.concretize()
|
dependency.concretize()
|
||||||
|
Reference in New Issue
Block a user