Better handling of stage.

- better symlink handling
- remove stage directories on successful install.
This commit is contained in:
Todd Gamblin 2013-02-21 23:01:37 -08:00
parent 5899308ad3
commit 707db8dafe
2 changed files with 35 additions and 10 deletions

View file

@ -315,6 +315,11 @@ def do_install(self):
tty.msg("Successfully installed %s" % self.name) tty.msg("Successfully installed %s" % self.name)
tty.pkg(self.prefix) tty.pkg(self.prefix)
# Once the install is done, destroy the stage where we built it,
# unless the user wants it kept around.
if not self.dirty:
self.stage.destroy()
def setup_install_environment(self): def setup_install_environment(self):
"""This ensures a clean install environment when we build packages.""" """This ensures a clean install environment when we build packages."""

View file

@ -14,10 +14,24 @@ def ensure_access(dir=spack.stage_path):
tty.die("Insufficient permissions on directory %s" % dir) tty.die("Insufficient permissions on directory %s" % dir)
def remove_linked_tree(path):
"""Removes a directory and its contents. If the directory is a symlink,
follows the link and reamoves the real directory before removing the link.
"""
if os.path.exists(path):
if os.path.islink(path):
shutil.rmtree(os.path.realpath(path), True)
os.unlink(path)
else:
shutil.rmtree(path, True)
def purge(): def purge():
"""Remove the entire stage path.""" """Remove any build directories in the stage path."""
if os.path.isdir(spack.stage_path): if os.path.isdir(spack.stage_path):
shutil.rmtree(spack.stage_path, True) for stage_dir in os.listdir(spack.stage_path):
stage_path = spack.new_path(spack.stage_path, stage_dir)
remove_linked_tree(stage_path)
class Stage(object): class Stage(object):
@ -31,8 +45,16 @@ def path(self):
def setup(self): def setup(self):
# If the user switched stage types on us, destroy the old one and # If we're using a stag in tmp that has since been deleted,
# start over # remove the stale symbolic link.
if os.path.islink(self.path):
real_path = os.path.realpath(self.path)
if not os.path.exists(real_path):
os.unlink(self.path)
# If the user switched stage modes, destroy the old stage and
# start over. We could move the old archive, but that seems
# like a pain when we could just fetch it again.
if spack.use_tmp_stage: if spack.use_tmp_stage:
if not os.path.islink(self.path): if not os.path.islink(self.path):
self.destroy() self.destroy()
@ -40,6 +62,8 @@ def setup(self):
if os.path.islink(self.path): if os.path.islink(self.path):
self.destroy() self.destroy()
# Make sure that the stage is actually a directory. Something
# is seriously wrong if it's not.
if os.path.exists(self.path): if os.path.exists(self.path):
if not os.path.isdir(self.path): if not os.path.isdir(self.path):
tty.die("Stage path %s is not a directory!" % self.path) tty.die("Stage path %s is not a directory!" % self.path)
@ -65,6 +89,7 @@ def setup(self):
os.symlink(tmp_dir, self.path) os.symlink(tmp_dir, self.path)
# Finally make sure we can actually do something with the stage
ensure_access(self.path) ensure_access(self.path)
@ -164,9 +189,4 @@ def restage(self):
def destroy(self): def destroy(self):
"""Blows away the stage directory. Can always call setup() again.""" """Blows away the stage directory. Can always call setup() again."""
if os.path.exists(self.path): remove_linked_tree(self.path)
if os.path.islink(self.path):
shutil.rmtree(os.path.realpath(self.path), True)
os.unlink(self.path)
else:
shutil.rmtree(self.path, True)