diff --git a/lib/spack/spack/globals.py b/lib/spack/spack/globals.py index 3ef7e53bb8..2182c56413 100644 --- a/lib/spack/spack/globals.py +++ b/lib/spack/spack/globals.py @@ -36,9 +36,17 @@ verbose = False debug = False -# Whether stage should use tmp filesystem or build in the spack prefix +# Whether to build in tmp space or directly in the stage_path. +# If this is true, then spack will make stage directories in +# a tmp filesystem, and it will symlink them into stage_path. use_tmp_stage = True +# Locations to use for staging and building, in order of preference +# Spack will try to create stage directories in / +# if one of these tmp_dirs exists. Otherwise it'll use a default +# location per the python implementation of tempfile.mkdtemp(). +tmp_dirs = ['/nfs/tmp2', '/var/tmp', '/tmp'] + # Important environment variables SPACK_NO_PARALLEL_MAKE = 'SPACK_NO_PARALLEL_MAKE' SPACK_LIB = 'SPACK_LIB' diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py index 9fd273d26f..b8d7e81ee3 100644 --- a/lib/spack/spack/stage.py +++ b/lib/spack/spack/stage.py @@ -2,6 +2,7 @@ import re import shutil import tempfile +import getpass import spack import packages @@ -30,11 +31,39 @@ def path(self): def setup(self): + # If the user switched stage types on us, destroy the old one and + # start over + if spack.use_tmp_stage: + if not os.path.islink(self.path): + self.destroy() + else: + if os.path.islink(self.path): + self.destroy() + if os.path.exists(self.path): if not os.path.isdir(self.path): tty.die("Stage path %s is not a directory!" % self.path) else: - os.makedirs(self.path) + # Now create the stage directory + spack.mkdirp(spack.stage_path) + + # And the stage for this build within it + if not spack.use_tmp_stage: + # non-tmp stage is just a directory in spack.stage_path + spack.mkdirp(self.path) + else: + # tmp stage is created in tmp but linked to spack.stage_path + tmp_dir = next((tmp for tmp in spack.tmp_dirs + if os.access(tmp, os.R_OK|os.W_OK)), None) + + username = getpass.getuser() + if username: + tmp_dir = spack.new_path(tmp_dir, username) + spack.mkdirp(tmp_dir) + tmp_dir = tempfile.mkdtemp( + '.stage', self.stage_name + '-', tmp_dir) + + os.symlink(tmp_dir, self.path) ensure_access(self.path) @@ -136,4 +165,8 @@ def restage(self): def destroy(self): """Blows away the stage directory. Can always call setup() again.""" if os.path.exists(self.path): - shutil.rmtree(self.path, True) + if os.path.islink(self.path): + shutil.rmtree(os.path.realpath(self.path), True) + os.unlink(self.path) + else: + shutil.rmtree(self.path, True)