Compare commits
65 Commits
develop
...
f/env-loca
Author | SHA1 | Date | |
---|---|---|---|
![]() |
79e821a43e | ||
![]() |
c16f166dcc | ||
![]() |
4ae9730ffe | ||
![]() |
9debeaf4e7 | ||
![]() |
47cdefcbe8 | ||
![]() |
2acc356ed4 | ||
![]() |
36bf6c9009 | ||
![]() |
29fbad20a2 | ||
![]() |
5f78703af8 | ||
![]() |
9b390bdc2c | ||
![]() |
bc427e8435 | ||
![]() |
3c6e6e22be | ||
![]() |
4a8f755632 | ||
![]() |
51de7ed7ee | ||
![]() |
047110c086 | ||
![]() |
7fa16089fc | ||
![]() |
065eaa739f | ||
![]() |
8d8e88c177 | ||
![]() |
8cc69cecfc | ||
![]() |
9c690a1ef5 | ||
![]() |
3532d6ff16 | ||
![]() |
7494893d3b | ||
![]() |
54e4a72b8e | ||
![]() |
b86980461f | ||
![]() |
23b5932f73 | ||
![]() |
93760847e8 | ||
![]() |
a35d2f39af | ||
![]() |
af17cc60a9 | ||
![]() |
b0528cae3f | ||
![]() |
372a18392a | ||
![]() |
70db49dfed | ||
![]() |
1d24c196da | ||
![]() |
fa3d768947 | ||
![]() |
9b6a109c7e | ||
![]() |
663967d984 | ||
![]() |
b47ff2a2de | ||
![]() |
f7b4993810 | ||
![]() |
3e07eb8cf0 | ||
![]() |
e773396747 | ||
![]() |
e19cc2385e | ||
![]() |
e867662e1b | ||
![]() |
6aad926838 | ||
![]() |
41cf807804 | ||
![]() |
cf8b919954 | ||
![]() |
47957dccf4 | ||
![]() |
38313cadf4 | ||
![]() |
730d005a56 | ||
![]() |
2f7c850a20 | ||
![]() |
5aa7a564d3 | ||
![]() |
d50c8f1727 | ||
![]() |
0ac6dfa8f3 | ||
![]() |
0b0ffe645d | ||
![]() |
9984c838c8 | ||
![]() |
b1bd61321d | ||
![]() |
c144558245 | ||
![]() |
ef43044672 | ||
![]() |
da7294cd90 | ||
![]() |
addb891f42 | ||
![]() |
bce2d38bfc | ||
![]() |
2cae95334c | ||
![]() |
076d60ce35 | ||
![]() |
9ecdafd8de | ||
![]() |
76fde639e8 | ||
![]() |
490b5eef7c | ||
![]() |
3f2e77e5fa |
@ -72,6 +72,7 @@ config:
|
|||||||
root: $TMP_DIR/install
|
root: $TMP_DIR/install
|
||||||
misc_cache: $$user_cache_path/cache
|
misc_cache: $$user_cache_path/cache
|
||||||
source_cache: $$user_cache_path/source
|
source_cache: $$user_cache_path/source
|
||||||
|
environments_root: $TMP_DIR/envs
|
||||||
EOF
|
EOF
|
||||||
cat >"$SPACK_USER_CONFIG_PATH/bootstrap.yaml" <<EOF
|
cat >"$SPACK_USER_CONFIG_PATH/bootstrap.yaml" <<EOF
|
||||||
bootstrap:
|
bootstrap:
|
||||||
|
@ -81,6 +81,10 @@ config:
|
|||||||
source_cache: $spack/var/spack/cache
|
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.
|
# Cache directory for miscellaneous files, like the package index.
|
||||||
# This can be purged with `spack clean --misc-cache`
|
# This can be purged with `spack clean --misc-cache`
|
||||||
misc_cache: $user_cache_path/cache
|
misc_cache: $user_cache_path/cache
|
||||||
|
@ -58,9 +58,9 @@ Using Environments
|
|||||||
Here we follow a typical use case of creating, concretizing,
|
Here we follow a typical use case of creating, concretizing,
|
||||||
installing and loading an environment.
|
installing and loading an environment.
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Creating a named Environment
|
Creating a managed Environment
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
An environment is created by:
|
An environment is created by:
|
||||||
|
|
||||||
@ -72,7 +72,8 @@ Spack then creates the directory ``var/spack/environments/myenv``.
|
|||||||
|
|
||||||
.. note::
|
.. 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
|
In the ``var/spack/environments/myenv`` directory, Spack creates the
|
||||||
file ``spack.yaml`` and the hidden directory ``.spack-env``.
|
file ``spack.yaml`` and the hidden directory ``.spack-env``.
|
||||||
|
@ -166,7 +166,7 @@ def env_activate(args):
|
|||||||
short_name = os.path.basename(env_path)
|
short_name = os.path.basename(env_path)
|
||||||
ev.Environment(env).write(regenerate=False)
|
ev.Environment(env).write(regenerate=False)
|
||||||
|
|
||||||
# Named environment
|
# Managed environment
|
||||||
elif ev.exists(env_name_or_dir) and not args.dir:
|
elif ev.exists(env_name_or_dir) and not args.dir:
|
||||||
env_path = ev.root(env_name_or_dir)
|
env_path = ev.root(env_name_or_dir)
|
||||||
short_name = env_name_or_dir
|
short_name = env_name_or_dir
|
||||||
|
@ -95,7 +95,7 @@ def location(parser, args):
|
|||||||
spack.cmd.require_active_env("location -e")
|
spack.cmd.require_active_env("location -e")
|
||||||
path = ev.active_environment().path
|
path = ev.active_environment().path
|
||||||
else:
|
else:
|
||||||
# Get named environment path
|
# Get path of requested environment
|
||||||
if not ev.exists(args.location_env):
|
if not ev.exists(args.location_env):
|
||||||
tty.die("no such environment: '%s'" % args.location_env)
|
tty.die("no such environment: '%s'" % args.location_env)
|
||||||
path = ev.root(args.location_env)
|
path = ev.root(args.location_env)
|
||||||
|
@ -64,8 +64,8 @@
|
|||||||
_active_environment = None
|
_active_environment = None
|
||||||
|
|
||||||
|
|
||||||
#: path where environments are stored in the spack tree
|
#: default path where environments are stored in the spack tree
|
||||||
env_path = os.path.join(spack.paths.var_path, "environments")
|
default_env_path = os.path.join(spack.paths.var_path, "environments")
|
||||||
|
|
||||||
|
|
||||||
#: Name of the input yaml file for an environment
|
#: Name of the input yaml file for an environment
|
||||||
@ -80,6 +80,26 @@
|
|||||||
env_subdir_name = ".spack-env"
|
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():
|
def default_manifest_yaml():
|
||||||
"""default spack.yaml file to put in new environments"""
|
"""default spack.yaml file to put in new environments"""
|
||||||
return """\
|
return """\
|
||||||
@ -216,7 +236,7 @@ def active_environment():
|
|||||||
|
|
||||||
def _root(name):
|
def _root(name):
|
||||||
"""Non-validating version of root(), to be used internally."""
|
"""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):
|
def root(name):
|
||||||
@ -251,10 +271,12 @@ def read(name):
|
|||||||
|
|
||||||
|
|
||||||
def create(name, init_file=None, with_view=None, keep_relative=False):
|
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)
|
validate_env_name(name)
|
||||||
if exists(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)
|
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."""
|
"""List the names of environments that currently exist."""
|
||||||
# just return empty if the env path does not exist. A read-only
|
# just return empty if the env path does not exist. A read-only
|
||||||
# operation like list should not try to create a directory.
|
# 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 []
|
return []
|
||||||
|
|
||||||
candidates = sorted(os.listdir(env_path))
|
candidates = sorted(os.listdir(env_root_path()))
|
||||||
names = []
|
names = []
|
||||||
for candidate in candidates:
|
for candidate in candidates:
|
||||||
yaml_path = os.path.join(_root(candidate), manifest_name)
|
yaml_path = os.path.join(_root(candidate), manifest_name)
|
||||||
@ -281,7 +303,7 @@ def all_environment_names():
|
|||||||
|
|
||||||
|
|
||||||
def all_environments():
|
def all_environments():
|
||||||
"""Generator for all named Environments."""
|
"""Generator for all managed Environments."""
|
||||||
for name in all_environment_names():
|
for name in all_environment_names():
|
||||||
yield read(name)
|
yield read(name)
|
||||||
|
|
||||||
@ -849,14 +871,14 @@ def clear(self, re_read=False):
|
|||||||
@property
|
@property
|
||||||
def internal(self):
|
def internal(self):
|
||||||
"""Whether this environment is managed by Spack."""
|
"""Whether this environment is managed by Spack."""
|
||||||
return self.path.startswith(env_path)
|
return self.path.startswith(env_root_path())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Human-readable representation of the environment.
|
"""Human-readable representation of the environment.
|
||||||
|
|
||||||
This is the path for directory environments, and just the name
|
This is the path for directory environments, and just the name
|
||||||
for named environments.
|
for managed environments.
|
||||||
"""
|
"""
|
||||||
if self.internal:
|
if self.internal:
|
||||||
return os.path.basename(self.path)
|
return os.path.basename(self.path)
|
||||||
@ -1036,7 +1058,9 @@ def env_file_config_scope(self):
|
|||||||
|
|
||||||
def config_scopes(self):
|
def config_scopes(self):
|
||||||
"""A list of all configuration scopes for this environment."""
|
"""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):
|
def destroy(self):
|
||||||
"""Remove this environment from Spack entirely."""
|
"""Remove this environment from Spack entirely."""
|
||||||
|
@ -459,7 +459,7 @@ def make_argument_parser(**kwargs):
|
|||||||
dest="env_dir",
|
dest="env_dir",
|
||||||
metavar="DIR",
|
metavar="DIR",
|
||||||
action="store",
|
action="store",
|
||||||
help="run with an environment directory (ignore named environments)",
|
help="run with an environment directory (ignore managed environments)",
|
||||||
)
|
)
|
||||||
env_group.add_argument(
|
env_group.add_argument(
|
||||||
"-E",
|
"-E",
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
"license_dir": {"type": "string"},
|
"license_dir": {"type": "string"},
|
||||||
"source_cache": {"type": "string"},
|
"source_cache": {"type": "string"},
|
||||||
"misc_cache": {"type": "string"},
|
"misc_cache": {"type": "string"},
|
||||||
|
"environments_root": {"type": "string"},
|
||||||
"connect_timeout": {"type": "integer", "minimum": 0},
|
"connect_timeout": {"type": "integer", "minimum": 0},
|
||||||
"verify_ssl": {"type": "boolean"},
|
"verify_ssl": {"type": "boolean"},
|
||||||
"suppress_gpg_warnings": {"type": "boolean"},
|
"suppress_gpg_warnings": {"type": "boolean"},
|
||||||
|
@ -9,8 +9,7 @@
|
|||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
from spack.main import SpackCommand
|
from spack.main import SpackCommand
|
||||||
|
|
||||||
# everything here uses the mock_env_path
|
pytestmark = pytest.mark.usefixtures("config", "mutable_mock_repo")
|
||||||
pytestmark = pytest.mark.usefixtures("mutable_mock_env_path", "config", "mutable_mock_repo")
|
|
||||||
|
|
||||||
env = SpackCommand("env")
|
env = SpackCommand("env")
|
||||||
add = SpackCommand("add")
|
add = SpackCommand("add")
|
||||||
@ -21,7 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("unify", unification_strategies)
|
@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."""
|
"""Check all test dependencies are concretized."""
|
||||||
env("create", "test")
|
env("create", "test")
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ def test_concretize_all_test_dependencies(unify):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("unify", unification_strategies)
|
@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."""
|
"""Check that test dependencies are not concretized recursively."""
|
||||||
env("create", "test")
|
env("create", "test")
|
||||||
|
|
||||||
@ -45,7 +44,7 @@ def test_concretize_root_test_dependencies_not_recursive(unify):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("unify", unification_strategies)
|
@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."""
|
"""Check that root test dependencies are concretized."""
|
||||||
env("create", "test")
|
env("create", "test")
|
||||||
|
|
||||||
|
@ -3236,3 +3236,20 @@ def test_relative_view_path_on_command_line_is_made_absolute(tmpdir, config):
|
|||||||
env("create", "--with-view", "view", "--dir", "env")
|
env("create", "--with-view", "view", "--dir", "env")
|
||||||
environment = ev.Environment(os.path.join(".", "env"))
|
environment = ev.Environment(os.path.join(".", "env"))
|
||||||
assert os.path.samefile("view", environment.default_view.root)
|
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))
|
||||||
|
@ -223,7 +223,7 @@ class TestUninstallFromEnv(object):
|
|||||||
concretize = SpackCommand("concretize")
|
concretize = SpackCommand("concretize")
|
||||||
find = SpackCommand("find")
|
find = SpackCommand("find")
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture(scope="function")
|
||||||
def environment_setup(
|
def environment_setup(
|
||||||
self, mutable_mock_env_path, config, mock_packages, mutable_database, install_mockery
|
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.add("dt-diamond-bottom")
|
||||||
TestUninstallFromEnv.concretize()
|
TestUninstallFromEnv.concretize()
|
||||||
install("--fake")
|
install("--fake")
|
||||||
|
yield "environment_setup"
|
||||||
|
TestUninstallFromEnv.env("rm", "e1", "-y")
|
||||||
|
TestUninstallFromEnv.env("rm", "e2", "-y")
|
||||||
|
|
||||||
def test_basic_env_sanity(self, environment_setup):
|
def test_basic_env_sanity(self, environment_setup):
|
||||||
for env_name in ["e1", "e2"]:
|
for env_name in ["e1", "e2"]:
|
||||||
|
@ -1551,14 +1551,14 @@ def get_rev():
|
|||||||
yield t
|
yield t
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture(scope="function")
|
||||||
def mutable_mock_env_path(tmpdir_factory):
|
def mutable_mock_env_path(tmpdir_factory, mutable_config):
|
||||||
"""Fixture for mocking the internal spack environments directory."""
|
"""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")
|
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
|
yield mock_path
|
||||||
ev.environment.env_path = saved_path
|
ev.environment.default_env_path = saved_path
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
@ -143,3 +143,21 @@ def test_user_view_path_is_not_canonicalized_in_yaml(tmpdir, config):
|
|||||||
snd = ev.Environment(env_path)
|
snd = ev.Environment(env_path)
|
||||||
assert snd.yaml["spack"]["view"] == view
|
assert snd.yaml["spack"]["view"] == view
|
||||||
assert os.path.samefile(snd.default_view.root, absolute_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)
|
||||||
|
Loading…
Reference in New Issue
Block a user