summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn W. Parent <45471568+johnwparent@users.noreply.github.com>2023-03-31 14:46:47 -0400
committerGitHub <noreply@github.com>2023-03-31 11:46:47 -0700
commita8e2961010e3bc010325b40a97d3b8891d980f33 (patch)
tree9aae83e0058f22df9e443bb78c15a98810536698
parenta6a364d3b8aa527eaa977a0ca150ef86ff4fb16f (diff)
downloadspack-a8e2961010e3bc010325b40a97d3b8891d980f33.tar.gz
spack-a8e2961010e3bc010325b40a97d3b8891d980f33.tar.bz2
spack-a8e2961010e3bc010325b40a97d3b8891d980f33.tar.xz
spack-a8e2961010e3bc010325b40a97d3b8891d980f33.zip
Allow configurable stage names (#36509)
Add `config:stage_name` which is a Spec format string that can customize the names of stages created by Spack. This was primarily created to allow generating shorter stage names on Windows (along with `config:build_stage`, this can be used to create stages with short absolute paths). By default, this is not set and the prior name stage format is used. This also removes the username component that is always added to Stage paths on Windows (if users want to include this, they can add it to the `build_stage`).
-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