summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/spack/defaults/windows/config.yaml1
-rw-r--r--lib/spack/spack/package_base.py5
-rw-r--r--lib/spack/spack/schema/config.py1
-rw-r--r--lib/spack/spack/stage.py13
-rw-r--r--lib/spack/spack/test/stage.py7
5 files changed, 21 insertions, 6 deletions
diff --git a/etc/spack/defaults/windows/config.yaml b/etc/spack/defaults/windows/config.yaml
index 367bf831cf..53116391cc 100644
--- a/etc/spack/defaults/windows/config.yaml
+++ b/etc/spack/defaults/windows/config.yaml
@@ -3,3 +3,4 @@ config:
concretizer: clingo
build_stage::
- '$spack/.staging'
+ stage_name: '{name}-{version}-{hash:7}'
diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py
index 470a41c460..98bf4d9c23 100644
--- a/lib/spack/spack/package_base.py
+++ b/lib/spack/spack/package_base.py
@@ -57,7 +57,7 @@ import spack.util.web
from spack.filesystem_view import YamlFilesystemView
from spack.install_test import TestFailure, TestSuite
from spack.installer import InstallError, PackageInstaller
-from spack.stage import ResourceStage, Stage, StageComposite, stage_prefix
+from spack.stage import ResourceStage, Stage, StageComposite, compute_stage_name
from spack.util.executable import ProcessError, which
from spack.util.package_hash import package_hash
from spack.util.prefix import Prefix
@@ -1022,8 +1022,7 @@ class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta):
)
# Construct a path where the stage should build..
s = self.spec
- stage_name = "{0}{1}-{2}-{3}".format(stage_prefix, s.name, s.version, s.dag_hash())
-
+ stage_name = compute_stage_name(s)
stage = Stage(
fetcher,
mirror_paths=mirror_paths,
diff --git a/lib/spack/spack/schema/config.py b/lib/spack/spack/schema/config.py
index abe207cac0..106e45ce7a 100644
--- a/lib/spack/spack/schema/config.py
+++ b/lib/spack/spack/schema/config.py
@@ -61,6 +61,7 @@ properties = {
"build_stage": {
"oneOf": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]
},
+ "stage_name": {"type": "string"},
"test_stage": {"type": "string"},
"extensions": {"type": "array", "items": {"type": "string"}},
"template_dirs": {"type": "array", "items": {"type": "string"}},
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index f6ed3c1ef4..97e05f365e 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -35,6 +35,7 @@ import spack.error
import spack.fetch_strategy as fs
import spack.mirror
import spack.paths
+import spack.spec
import spack.util.lock
import spack.util.path as sup
import spack.util.pattern as pattern
@@ -49,6 +50,13 @@ _source_path_subdir = "spack-src"
stage_prefix = "spack-stage-"
+def compute_stage_name(spec):
+ """Determine stage name given a spec"""
+ default_stage_structure = "spack-stage-{name}-{version}-{hash}"
+ stage_name_structure = spack.config.get("config:stage_name", default=default_stage_structure)
+ return spec.format(format_string=stage_name_structure)
+
+
def create_stage_root(path: str) -> None:
"""Create the stage root directory and ensure appropriate access perms."""
assert os.path.isabs(path) and len(path.strip()) > 1
@@ -150,7 +158,10 @@ def _resolve_paths(candidates):
# Ensure the path is unique per user.
can_path = sup.canonicalize_path(path)
- if user not in can_path:
+ # When multiple users share a stage root, we can avoid conflicts between
+ # them by adding a per-user subdirectory.
+ # Avoid doing this on Windows to keep stage absolute path as short as possible.
+ if user not in can_path and not sys.platform == "win32":
can_path = os.path.join(can_path, user)
paths.append(can_path)
diff --git a/lib/spack/spack/test/stage.py b/lib/spack/spack/test/stage.py
index 1cc1f20472..f790a66d0e 100644
--- a/lib/spack/spack/test/stage.py
+++ b/lib/spack/spack/test/stage.py
@@ -765,8 +765,11 @@ class TestStage(object):
# resolved path without user appends user
paths = [os.path.join(os.path.sep, "a", "b", "c")]
+ can_paths = [paths[0]]
user = getpass.getuser()
- can_paths = [os.path.join(paths[0], user)]
+
+ if sys.platform != "win32":
+ can_paths = [os.path.join(paths[0], user)]
assert spack.stage._resolve_paths(paths) == can_paths
# resolved path with node including user does not append user
@@ -789,7 +792,7 @@ class TestStage(object):
res_paths[1] = can_tempdir
res_paths[2] = os.path.join(can_tempdir, user)
res_paths[3] = os.path.join(can_tempdir, "stage", user)
- else:
+ elif sys.platform != "win32":
res_paths[0] = os.path.join(res_paths[0], user)
assert spack.stage._resolve_paths(paths) == res_paths