Compare commits

...

65 Commits

Author SHA1 Message Date
Gregory Becker
79e821a43e docs: consistently use 'managed environment' over 'named ...' 2023-02-21 15:53:34 -08:00
psakievich
c16f166dcc
Update lib/spack/docs/environments.rst 2023-02-21 16:33:45 -07:00
psakiev
4ae9730ffe remove env's 2023-02-21 12:57:13 -07:00
psakiev
9debeaf4e7 Try to resolve uninstall failure 2023-02-21 12:01:10 -07:00
psakiev
47cdefcbe8 Try setting mutable_mock_env in each func 2023-02-21 11:18:26 -07:00
psakiev
2acc356ed4 Style 2023-02-21 10:09:22 -07:00
psakiev
36bf6c9009 Add unit-tests back 2023-02-21 10:00:50 -07:00
psakiev
29fbad20a2 Undo hoops for avoiding env include 2023-02-21 09:18:44 -07:00
psakiev
5f78703af8 Fixture function scope 2023-02-21 08:53:07 -07:00
psakiev
9b390bdc2c Add back mutable-config 2023-02-15 16:55:33 -07:00
psakiev
bc427e8435 Adjust vars in mutable_mock_env_path 2023-02-15 14:46:54 -07:00
psakiev
3c6e6e22be Undo all unit-tests to see if CI will pass 2023-02-15 13:08:19 -07:00
psakievich
4a8f755632 [@spackbot] updating style on behalf of psakievich 2023-02-13 18:52:06 +00:00
psakievich
51de7ed7ee
Merge branch 'develop' into f/env-location 2023-02-13 10:50:53 -07:00
psakiev
047110c086 Debug print statement 2023-01-11 05:37:29 -07:00
psakiev
7fa16089fc Add entry to tmpconfig 2023-01-11 04:46:42 -07:00
Philip Sakievich
065eaa739f Remove accidental bleed over trilinos change 2023-01-10 09:38:51 -07:00
psakiev
8d8e88c177 Try renaming dir 2023-01-09 16:24:14 -07:00
psakiev
8cc69cecfc Add function scope 2023-01-09 15:27:27 -07:00
psakiev
9c690a1ef5 Revert "Try something else"
This reverts commit 3532d6ff16.
2023-01-09 14:20:28 -07:00
psakiev
3532d6ff16 Try something else 2023-01-09 13:22:13 -07:00
psakiev
7494893d3b Drop the hidden dir 2023-01-09 12:46:59 -07:00
psakievich
54e4a72b8e
Merge branch 'develop' into f/env-location 2023-01-07 22:23:23 -07:00
psakiev
b86980461f Modify failing test 2023-01-07 20:59:44 -07:00
psakiev
23b5932f73 Make hidden dir for mock env location 2022-12-21 14:56:52 -07:00
psakiev
93760847e8 Use tmpdir for all mutable env paths 2022-12-19 21:18:37 -07:00
psakievich
a35d2f39af
Merge branch 'develop' into f/env-location 2022-12-19 17:02:19 -07:00
psakiev
af17cc60a9 Add tmpdir 2022-12-19 16:13:01 -07:00
psakiev
b0528cae3f Improve robustness of env test in parallel 2022-12-19 16:07:34 -07:00
psakiev
372a18392a Add syntax for debugging CI 2022-12-19 13:54:45 -07:00
psakievich
70db49dfed
Merge branch 'develop' into f/env-location 2022-12-19 13:50:43 -07:00
psakiev
1d24c196da Use proper import 2022-12-08 12:36:36 -07:00
psakievich
fa3d768947
Update lib/spack/spack/environment/environment.py 2022-12-08 12:34:57 -07:00
psakiev
9b6a109c7e Remove constraint on environments_root creation 2022-12-07 22:24:18 -07:00
psakievich
663967d984
Merge branch 'develop' into f/env-location 2022-12-07 15:03:51 -07:00
psakiev
b47ff2a2de Fix missing function 2022-12-07 14:32:36 -07:00
psakiev
f7b4993810 Address reviewer comments 2022-12-07 14:25:12 -07:00
psakiev
3e07eb8cf0 Fix scope detection issue 2022-12-01 22:21:10 -07:00
psakievich
e773396747
Merge branch 'develop' into f/env-location 2022-12-01 17:00:36 -07:00
psakiev
e19cc2385e Don't automatically create the default env path 2022-12-01 16:50:24 -07:00
psakievich
e867662e1b
Merge branch 'develop' into f/env-location 2022-11-09 17:19:41 -07:00
psakiev
6aad926838 Fix unicode error 2022-11-09 15:50:16 -07:00
psakievich
41cf807804
Merge branch 'develop' into f/env-location 2022-11-09 15:09:22 -07:00
psakiev
cf8b919954 Remove accidental changes to bin/sbang 2022-11-09 13:39:56 -07:00
psakiev
47957dccf4 Remove shell driven command from env activation test 2022-11-09 13:19:17 -07:00
Philip Sakievich
38313cadf4 Revert "avoid using realpath, readlink -f is more portable"
This reverts commit 2cae95334c.
2022-11-08 23:40:03 -07:00
Philip Sakievich
730d005a56 Only create default path when used 2022-11-08 23:39:03 -07:00
psakiev
2f7c850a20 style 2022-11-08 23:08:19 -07:00
psakiev
5aa7a564d3 Why do we have mutliple cod paths for env activation? 2022-11-08 22:59:29 -07:00
psakiev
d50c8f1727 Add guard-rail and unit-test (not working) 2022-11-08 22:41:09 -07:00
psakievich
0ac6dfa8f3
Merge branch 'develop' into f/env-location 2022-10-12 08:45:01 -06:00
Philip Sakievich
0b0ffe645d Ugh python 2 🤦‍♂️ 2022-10-11 22:37:57 -06:00
Philip Sakievich
9984c838c8 Fix failing shell tests 2022-10-11 22:18:43 -06:00
psakievich
b1bd61321d
Merge branch 'develop' into f/env-location 2022-10-11 21:53:49 -06:00
psakievich
c144558245
Merge branch 'develop' into f/env-location 2022-09-29 11:50:06 -06:00
psakiev
ef43044672 Change name of variable 2022-09-27 22:17:29 -06:00
psakievich
da7294cd90
Update lib/spack/spack/test/config.py
Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>
2022-09-27 21:08:32 -06:00
psakievich
addb891f42
Update lib/spack/docs/environments.rst
Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>
2022-09-27 21:08:25 -06:00
psakievich
bce2d38bfc
Merge branch 'develop' into f/env-location 2022-09-27 14:40:57 -06:00
Tom Scogland
2cae95334c avoid using realpath, readlink -f is more portable 2022-09-27 18:33:52 +00:00
psakiev
076d60ce35 Add check that env_root dir exists 2022-09-27 12:02:43 -06:00
psakiev
9ecdafd8de Add some documentation 2022-09-27 11:25:31 -06:00
psakievich
76fde639e8 Update lib/spack/spack/environment/environment.py
Co-authored-by: Greg Becker <becker33@llnl.gov>

Add back path canonicalization
2022-09-27 11:17:47 -06:00
psakiev
490b5eef7c Rework path access strategy 2022-09-27 10:57:28 -06:00
psakiev
3f2e77e5fa Allow users to specify root env dir
Environments managed by spack have some advantages over anonymous Environments
but they are tucked away inside spack's directory tree. This PR gives
users the ability to specify where the environments should live.

See #32823
2022-09-26 22:31:29 -06:00
13 changed files with 97 additions and 29 deletions

View File

@ -72,6 +72,7 @@ config:
root: $TMP_DIR/install
misc_cache: $$user_cache_path/cache
source_cache: $$user_cache_path/source
environments_root: $TMP_DIR/envs
EOF
cat >"$SPACK_USER_CONFIG_PATH/bootstrap.yaml" <<EOF
bootstrap:

View File

@ -81,6 +81,10 @@ config:
source_cache: $spack/var/spack/cache
## Directory where spack managed environments are created and stored
# environments_root: $spack/var/spack/environments
# Cache directory for miscellaneous files, like the package index.
# This can be purged with `spack clean --misc-cache`
misc_cache: $user_cache_path/cache

View File

@ -58,9 +58,9 @@ Using Environments
Here we follow a typical use case of creating, concretizing,
installing and loading an environment.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Creating a named Environment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Creating a managed Environment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
An environment is created by:
@ -72,7 +72,8 @@ Spack then creates the directory ``var/spack/environments/myenv``.
.. note::
All named environments are stored in the ``var/spack/environments`` folder.
All managed environments by default are stored in the ``var/spack/environments`` folder.
This location can be changed by setting the ``environments_root`` variable in ``config.yaml``.
In the ``var/spack/environments/myenv`` directory, Spack creates the
file ``spack.yaml`` and the hidden directory ``.spack-env``.

View File

@ -166,7 +166,7 @@ def env_activate(args):
short_name = os.path.basename(env_path)
ev.Environment(env).write(regenerate=False)
# Named environment
# Managed environment
elif ev.exists(env_name_or_dir) and not args.dir:
env_path = ev.root(env_name_or_dir)
short_name = env_name_or_dir

View File

@ -95,7 +95,7 @@ def location(parser, args):
spack.cmd.require_active_env("location -e")
path = ev.active_environment().path
else:
# Get named environment path
# Get path of requested environment
if not ev.exists(args.location_env):
tty.die("no such environment: '%s'" % args.location_env)
path = ev.root(args.location_env)

View File

@ -64,8 +64,8 @@
_active_environment = None
#: path where environments are stored in the spack tree
env_path = os.path.join(spack.paths.var_path, "environments")
#: default path where environments are stored in the spack tree
default_env_path = os.path.join(spack.paths.var_path, "environments")
#: Name of the input yaml file for an environment
@ -80,6 +80,26 @@
env_subdir_name = ".spack-env"
def env_root_path():
"""Override default root path if the user specified it"""
return spack.util.path.canonicalize_path(
spack.config.get("config:environments_root", default=default_env_path)
)
def check_disallowed_env_config_mods(scopes):
for scope in scopes:
with spack.config.use_configuration(scope):
if spack.config.get("config:environments_root"):
raise SpackEnvironmentError(
"Spack environments are prohibited from modifying 'config:environments_root' "
"because it can make the definition of the environment ill-posed. Please "
"remove from your environment and place it in a permanent scope such as "
"defaults, system, site, etc."
)
return scopes
def default_manifest_yaml():
"""default spack.yaml file to put in new environments"""
return """\
@ -216,7 +236,7 @@ def active_environment():
def _root(name):
"""Non-validating version of root(), to be used internally."""
return os.path.join(env_path, name)
return os.path.join(env_root_path(), name)
def root(name):
@ -251,10 +271,12 @@ def read(name):
def create(name, init_file=None, with_view=None, keep_relative=False):
"""Create a named environment in Spack."""
"""Create a managed environment in Spack."""
if not os.path.isdir(env_root_path()):
fs.mkdirp(env_root_path())
validate_env_name(name)
if exists(name):
raise SpackEnvironmentError("'%s': environment already exists" % name)
raise SpackEnvironmentError("'%s': environment already exists at %s" % (name, root(name)))
return Environment(root(name), init_file, with_view, keep_relative)
@ -268,10 +290,10 @@ def all_environment_names():
"""List the names of environments that currently exist."""
# just return empty if the env path does not exist. A read-only
# operation like list should not try to create a directory.
if not os.path.exists(env_path):
if not os.path.exists(env_root_path()):
return []
candidates = sorted(os.listdir(env_path))
candidates = sorted(os.listdir(env_root_path()))
names = []
for candidate in candidates:
yaml_path = os.path.join(_root(candidate), manifest_name)
@ -281,7 +303,7 @@ def all_environment_names():
def all_environments():
"""Generator for all named Environments."""
"""Generator for all managed Environments."""
for name in all_environment_names():
yield read(name)
@ -849,14 +871,14 @@ def clear(self, re_read=False):
@property
def internal(self):
"""Whether this environment is managed by Spack."""
return self.path.startswith(env_path)
return self.path.startswith(env_root_path())
@property
def name(self):
"""Human-readable representation of the environment.
This is the path for directory environments, and just the name
for named environments.
for managed environments.
"""
if self.internal:
return os.path.basename(self.path)
@ -1036,7 +1058,9 @@ def env_file_config_scope(self):
def config_scopes(self):
"""A list of all configuration scopes for this environment."""
return self.included_config_scopes() + [self.env_file_config_scope()]
return check_disallowed_env_config_mods(
self.included_config_scopes() + [self.env_file_config_scope()]
)
def destroy(self):
"""Remove this environment from Spack entirely."""

View File

@ -459,7 +459,7 @@ def make_argument_parser(**kwargs):
dest="env_dir",
metavar="DIR",
action="store",
help="run with an environment directory (ignore named environments)",
help="run with an environment directory (ignore managed environments)",
)
env_group.add_argument(
"-E",

View File

@ -67,6 +67,7 @@
"license_dir": {"type": "string"},
"source_cache": {"type": "string"},
"misc_cache": {"type": "string"},
"environments_root": {"type": "string"},
"connect_timeout": {"type": "integer", "minimum": 0},
"verify_ssl": {"type": "boolean"},
"suppress_gpg_warnings": {"type": "boolean"},

View File

@ -9,8 +9,7 @@
import spack.environment as ev
from spack.main import SpackCommand
# everything here uses the mock_env_path
pytestmark = pytest.mark.usefixtures("mutable_mock_env_path", "config", "mutable_mock_repo")
pytestmark = pytest.mark.usefixtures("config", "mutable_mock_repo")
env = SpackCommand("env")
add = SpackCommand("add")
@ -21,7 +20,7 @@
@pytest.mark.parametrize("unify", unification_strategies)
def test_concretize_all_test_dependencies(unify):
def test_concretize_all_test_dependencies(unify, mutable_mock_env_path):
"""Check all test dependencies are concretized."""
env("create", "test")
@ -33,7 +32,7 @@ def test_concretize_all_test_dependencies(unify):
@pytest.mark.parametrize("unify", unification_strategies)
def test_concretize_root_test_dependencies_not_recursive(unify):
def test_concretize_root_test_dependencies_not_recursive(unify, mutable_mock_env_path):
"""Check that test dependencies are not concretized recursively."""
env("create", "test")
@ -45,7 +44,7 @@ def test_concretize_root_test_dependencies_not_recursive(unify):
@pytest.mark.parametrize("unify", unification_strategies)
def test_concretize_root_test_dependencies_are_concretized(unify):
def test_concretize_root_test_dependencies_are_concretized(unify, mutable_mock_env_path):
"""Check that root test dependencies are concretized."""
env("create", "test")

View File

@ -3236,3 +3236,20 @@ def test_relative_view_path_on_command_line_is_made_absolute(tmpdir, config):
env("create", "--with-view", "view", "--dir", "env")
environment = ev.Environment(os.path.join(".", "env"))
assert os.path.samefile("view", environment.default_view.root)
def test_environment_created_in_users_location(mutable_config, tmpdir):
"""Test that an environment is created in a location based on the config"""
spack.config.set("config:environments_root", str(tmpdir.join("envs")))
env_dir = spack.config.get("config:environments_root")
assert tmpdir.strpath in env_dir
assert not os.path.isdir(env_dir)
dir_name = "user_env"
env("create", dir_name)
out = env("list")
assert dir_name in out
assert env_dir in ev.root(dir_name)
assert os.path.isdir(os.path.join(env_dir, dir_name))

View File

@ -223,7 +223,7 @@ class TestUninstallFromEnv(object):
concretize = SpackCommand("concretize")
find = SpackCommand("find")
@pytest.fixture
@pytest.fixture(scope="function")
def environment_setup(
self, mutable_mock_env_path, config, mock_packages, mutable_database, install_mockery
):
@ -242,6 +242,9 @@ def environment_setup(
TestUninstallFromEnv.add("dt-diamond-bottom")
TestUninstallFromEnv.concretize()
install("--fake")
yield "environment_setup"
TestUninstallFromEnv.env("rm", "e1", "-y")
TestUninstallFromEnv.env("rm", "e2", "-y")
def test_basic_env_sanity(self, environment_setup):
for env_name in ["e1", "e2"]:

View File

@ -1551,14 +1551,14 @@ def get_rev():
yield t
@pytest.fixture()
def mutable_mock_env_path(tmpdir_factory):
@pytest.fixture(scope="function")
def mutable_mock_env_path(tmpdir_factory, mutable_config):
"""Fixture for mocking the internal spack environments directory."""
saved_path = ev.environment.env_path
saved_path = ev.environment.default_env_path
mock_path = tmpdir_factory.mktemp("mock-env-path")
ev.environment.env_path = str(mock_path)
ev.environment.default_env_path = str(mock_path)
yield mock_path
ev.environment.env_path = saved_path
ev.environment.default_env_path = saved_path
@pytest.fixture()

View File

@ -143,3 +143,21 @@ def test_user_view_path_is_not_canonicalized_in_yaml(tmpdir, config):
snd = ev.Environment(env_path)
assert snd.yaml["spack"]["view"] == view
assert os.path.samefile(snd.default_view.root, absolute_view)
def test_environment_cant_modify_environments_root(tmpdir):
filename = str(tmpdir.join("spack.yaml"))
with open(filename, "w") as f:
f.write(
"""\
spack:
config:
environments_root: /a/black/hole
view: false
specs: []
"""
)
with tmpdir.as_cwd():
with pytest.raises(ev.SpackEnvironmentError):
e = ev.Environment(tmpdir.strpath)
ev.activate(e)