-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Severe issues with config scopes when -C and -e are used together #51459
Description
Steps to reproduce
Kudos to @albestro for reporting the issue and helping debug it
Summary
Config scopes cannot be trusted when -C and -e are used together on the command line. The issue has been introduced in #50853 and is really nasty for two reasons:
- When
-Cand-eare used together, Spack silently shuffles the config scopes in the middle of execution. The environment scope might be swapped with some other custom scope. Due to the mechanics involved this is also difficult to debug, since the output ofspack config get/blamecannot be trusted. - The documentation was never updated in config: CLI scopes should override environments #50853. The priority for the CUSTOM config scope in the code is higher than the priority of ENVIRONMENT. The docs say otherwise.
Why are the scopes shuffled?
Since #50853 was merged, environments added from the command line are considered at CUSTOM priority:
Lines 901 to 905 in e250ec0
| for i, path in enumerate(command_line_scopes): | |
| # If an environment is set on the CLI, add its scope in the order it appears there. | |
| # Subsequent custom scopes will override it, and it will override prior custom scopes. | |
| if path is _ENV: | |
| add_environment(ConfigScopePriority.CUSTOM) |
When the environment is loaded, we use a context manager:
spack/lib/spack/spack/environment/environment.py
Lines 999 to 1004 in e250ec0
| def _load_manifest_file(self): | |
| """Instantiate and load the manifest file contents into memory.""" | |
| with lk.ReadTransaction(self.txlock): | |
| self.manifest = EnvironmentManifestFile(self.path, self.name) | |
| with self.manifest.use_config(): | |
| self._read() |
that adds the environment at ENVIRONMENT priority:
spack/lib/spack/spack/environment/environment.py
Lines 3035 to 3039 in e250ec0
| def prepare_config_scope( | |
| self, priority: ConfigScopePriority = ConfigScopePriority.ENVIRONMENT | |
| ) -> None: | |
| """Add the manifest's scope to the global configuration search path.""" | |
| spack.config.CONFIG.push_scope(self.env_config_scope, priority) |
The result is that config scopes are swapped in the middle of execution, and user might see unexpected behaviors.
Minimal reproducer
This can be reproduced easily with the following setup:
$ tree
.
├── custom
│ └── config.yaml
├── env1
│ └── spack.yaml
└── script.py
2 directories, 3 filesThe files are the following:
# script.py
import spack.config
import spack.environment
KEY = "config:install_tree:root"
print(f"[Before context manager] {spack.config.CONFIG.get(KEY)}")
with spack.environment.active_environment().manifest.use_config():
print(f"[Within context manager] {spack.config.CONFIG.get(KEY)}")
print(f"[After context manager] {spack.config.CONFIG.get(KEY)}")# spack.yaml
spack:
specs: []
config:
install_tree:
root: /tmp/env# config.yaml
config:
install_tree:
root: /tmp/customThen we can run the script like:
$ spack -C custom -e env1 python script.py
[Before context manager] /tmp/env
[Within context manager] /tmp/custom
[After context manager] /tmp/customand see the swapping in action 😞
Error message
There is no clear error message, just weird observed behavior that doesn't match:
- the documentation
- the output of
spack config blame
The report above has been obtained with trial and error + a debugger. The original issue was reported because some modifications in a custom repository added at environment scope were not taken into account correctly.
Information on your system
- Spack: 1.1.0.dev0 (e250ec0)
- Builtin repo: spack/spack-packages@8f612a2
- Python: 3.13.2
- Platform: linux-ubuntu20.04-icelake
General information
- I have run
spack debug reportand reported the version of Spack/Python/Platform - I have searched the issues of this repo and believe this is not a duplicate
- I have run the failing commands in debug mode and reported the output
Metadata
Metadata
Assignees
Labels
Type
Projects
Status