Skip to content

Commit bdf27d0

Browse files
bcummingRMeli
andauthored
default views (#287)
recipes can now select a view that is loaded by default if no view is provided. default views are opt-in, so existing recipes will not change their behavior --------- Co-authored-by: Rocco Meli <r.meli@bluemail.ch>
1 parent f6cd944 commit bdf27d0

9 files changed

Lines changed: 58 additions & 54 deletions

File tree

docs/recipes.md

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ A recipe is comprised of the following yaml files in a directory:
1515
* `post-install`: _optional_ a script to run after Spack has been executed to build the stack.
1616
* `pre-install`: _optional_ a script to run before any packages have been built.
1717

18+
[](){#ref-recipes-config}
1819
## Configuration
1920

2021
```yaml title="config.yaml"
@@ -26,17 +27,18 @@ spack:
2627
packages:
2728
repo: https://github.com/spack/spack-packages.git
2829
commit: develop
29-
modules: true
3030
description: "HPC development tools for building MPI applications with the GNU compiler toolchain"
31+
default-view: develop
3132
version: 2
3233
```
3334
3435
* `name`: a plain text name for the environment
3536
* `store`: the location where the environment will be mounted.
3637
* `spack`: which spack and package repositories to use for installation.
37-
* `modules`: (_deprecated_) _optional_ enable/disable module file generation.
3838
* `description`: _optional_ a string that describes the environment (default empty).
39+
* `default-view`: _default = null_ the name of a uenv view to load if no view is explicitly requested by the user. See the documentation for [default views][ref-recipes-default-view]. If no default view is specified, none will be set.
3940
* `version`: _default = 1_ the version of the uenv recipe (see below)
41+
* `modules`: (_deprecated_) _optional_ enable/disable module file generation.
4042

4143
!!! note "uenv recipe versions"
4244
Stackinator 6 introduces breaking changes to the uenv recipe format, introduced to support Spack v1.0.
@@ -350,27 +352,34 @@ For example, the `views` description:
350352
```yaml
351353
cuda-env:
352354
views:
353-
default:
355+
full:
354356
no-python:
355357
exclude:
356358
- 'python'
357359
```
358360

359361
will configure two views:
360362

361-
* `default`: a view of all the software in the environment using the default settings of Spack.
362-
* `no-python`: everything in the default view, except any versions of `python`.
363+
* `full`: a view of all the software in the environment using the full settings of Spack.
364+
* `no-python`: everything in the `full` view, except any versions of `python`.
365+
366+
!!! warning "only name views default if they are loaded by default"
367+
It is possible to name views `default`, and there are uenv images like `prgenv-gnu` that follow this practice for legacy reasons.
368+
369+
However the name default can be confusing for users because it implies that the view is loaded by default.
370+
However, [default views][ref-recipes-default-view] must be explicitly set in [`config.yaml`][ref-recipes-config].
363371

364372
Stackinator provides some additional options that are not provided by Spack, to fine tune the view, that can be set in the `uenv:` field:
365373

366374
```yaml
367375
cuda-env:
368376
views:
369-
uenv:
370-
add_compilers: true
371-
prefix_paths:
372-
LD_LIBRARY_PATH: [lib, lib64]
373-
env_vars:
377+
my-view:
378+
uenv:
379+
add_compilers: true
380+
prefix_paths:
381+
LD_LIBRARY_PATH: [lib, lib64]
382+
env_vars:
374383
set:
375384
- WOMBAT: null
376385
- NOCOLOR: "1"
@@ -392,6 +401,18 @@ cuda-env:
392401
!!! info
393402
See the [interfaces documentation](interfaces.md#environment-views) for more information about how the environment views are provided.
394403

404+
[](){#ref-recipes-default-view}
405+
#### Setting default views
406+
407+
!!! info "available in uenv 9.3 and later"
408+
Default views are only loaded in recent versions of uenv.
409+
Older uenv versions will ignore the default view - it is not an error to load a uenv that provides a default view using uenv 9.2 and older.
410+
411+
It is possible to specify a view that will be loaded automatically if no view is specified, by setting the `default-view` field in [`config.yaml` file][ref-recipes-config].
412+
413+
* a default view is only used if it is explicitly specified in `config.yaml`.
414+
* if a uenv is started with a view specified, the default view is ignored.
415+
395416
#### Setting environment variables with `env_vars`
396417

397418
The `views:<view_name>:uenv:env_vars` field can be used to further fine-tune the environment variables that are set when the view is started.

stackinator/builder.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ def environment_meta(self, recipe):
156156
meta["name"] = conf["name"]
157157
meta["description"] = conf["description"]
158158
meta["views"] = recipe.environment_view_meta
159+
meta["default-view"] = recipe.default_view
159160
meta["mount"] = str(recipe.mount)
160161
modules = None
161162
if recipe.with_modules:

stackinator/recipe.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,6 @@ def __init__(self, args):
8787
self._logger.error(f"modules.yaml:{self.with_modules}")
8888
raise RuntimeError("conflicting modules configuration detected")
8989

90-
# optional packages.yaml file
91-
packages_path = self.path / "packages.yaml"
92-
self._logger.debug(f"opening {packages_path}")
93-
self.packages = None
94-
if packages_path.is_file():
95-
with packages_path.open() as fid:
96-
self.packages = yaml.load(fid, Loader=yaml.Loader)
97-
9890
self._logger.debug("creating packages")
9991

10092
# load recipe/packages.yaml -> recipe_packages (if it exists)
@@ -169,6 +161,21 @@ def __init__(self, args):
169161
schema.EnvironmentsValidator.validate(raw)
170162
self.generate_environment_specs(raw)
171163

164+
# check that the default view exists (if one has been set)
165+
self._default_view = self.config["default-view"]
166+
if self._default_view is not None:
167+
available_views = [view["name"] for env in self.environments.values() for view in env["views"]]
168+
# add the modules and spack views to the list of available views
169+
if self.with_modules:
170+
available_views.append("modules")
171+
available_views.append("spack")
172+
if self._default_view not in available_views:
173+
self._logger.error(
174+
f"The default-view {self._default_view} is not the name of a view in the environments.yaml "
175+
"definition (one of {[name for name in available_views]}"
176+
)
177+
raise RuntimeError("Ivalid default-view in the recipe.")
178+
172179
# optional mirror configurtion
173180
mirrors_path = self.path / "mirrors.yaml"
174181
if mirrors_path.is_file():
@@ -286,6 +293,10 @@ def with_modules(self) -> bool:
286293
def find_spack_version(self, develop):
287294
return "1.0"
288295

296+
@property
297+
def default_view(self):
298+
return self._default_view
299+
289300
@property
290301
def environment_view_meta(self):
291302
# generate the view meta data that is presented in the squashfs image meta data

stackinator/schema/config.json

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,6 @@
4646
}
4747
}
4848
},
49-
"mirror" : {
50-
"type" : "object",
51-
"additionalProperties": false,
52-
"default": {"enable": true, "key": null},
53-
"properties" : {
54-
"enable" : {
55-
"type": "boolean",
56-
"default": true
57-
},
58-
"key" : {
59-
"oneOf": [
60-
{"type" : "string"},
61-
{"type" : "null"}
62-
],
63-
"default": null
64-
}
65-
}
66-
},
6749
"modules" : {
6850
"type": "boolean"
6951
},
@@ -74,6 +56,13 @@
7456
],
7557
"default": null
7658
},
59+
"default-view" : {
60+
"oneOf": [
61+
{"type" : "string"},
62+
{"type" : "null"}
63+
],
64+
"default": null
65+
},
7766
"version" : {
7867
"type": "number",
7968
"default": 1,

unittests/recipes/base-nvgpu/config.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,4 @@ spack:
55
commit: 6408b51
66
packages:
77
repo: https://github.com/spack/spack-packages.git
8-
mirror:
9-
enable: false
108
version: 2

unittests/recipes/cache/config.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,4 @@ spack:
55
commit: 6408b51
66
packages:
77
repo: https://github.com/spack/spack-packages.git
8-
mirror:
9-
key: /scratch/e1000/bcumming/secret/spack-key.gpg
10-
enable: true
118
version: 2

unittests/test_schema.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ def test_config_yaml(yaml_path):
4343
assert raw["store"] == "/user-environment"
4444
assert raw["spack"]["commit"] is None
4545
assert raw["spack"]["packages"]["commit"] is None
46-
assert raw["mirror"] == {"enable": True, "key": None}
4746
assert raw["description"] is None
4847

4948
# no spack:commit
@@ -63,7 +62,6 @@ def test_config_yaml(yaml_path):
6362
schema.ConfigValidator.validate(raw)
6463
assert raw["spack"]["commit"] is None
6564
assert raw["spack"]["packages"]["commit"] is not None
66-
assert raw["mirror"] == {"enable": True, "key": None}
6765
assert raw["description"] is None
6866

6967
# no spack:packages:commit
@@ -83,7 +81,6 @@ def test_config_yaml(yaml_path):
8381
schema.ConfigValidator.validate(raw)
8482
assert raw["spack"]["commit"] == "develop"
8583
assert raw["spack"]["packages"]["commit"] is None
86-
assert raw["mirror"] == {"enable": True, "key": None}
8784
assert raw["description"] is None
8885

8986
# full config
@@ -94,7 +91,6 @@ def test_config_yaml(yaml_path):
9491
assert raw["spack"]["commit"] == "6408b51"
9592
assert raw["spack"]["packages"]["commit"] == "v2025.07.0"
9693
assert raw["modules"] == False # noqa: E712
97-
assert raw["mirror"] == {"enable": True, "key": "/home/bob/veryprivate.key"}
9894
assert raw["description"] == "a really useful environment"
9995

10096
# unsupported old version

unittests/yaml/config.defaults.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,5 @@ spack:
99
repo: https://github.com/spack/spack-packages.git
1010
# default: None == no `git checkout` command
1111
#commit: 6408b51
12-
#mirror:
13-
# default None
14-
#key: None
15-
# default True
16-
#enable: True
17-
# default True
1812
#modules: True
1913
version: 2

unittests/yaml/config.full.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ spack:
66
packages:
77
repo: https://github.com/spack/spack-packages.git
88
commit: v2025.07.0
9-
mirror:
10-
key: /home/bob/veryprivate.key
11-
enable: True
129
modules: False
1310
description: "a really useful environment"
1411
version: 2

0 commit comments

Comments
 (0)