Skip to content

Commit a88b080

Browse files
authored
Merge branch 'easybuilders:develop' into toolchains
2 parents c7b0463 + 03891cb commit a88b080

18 files changed

+3306
-752
lines changed

docs/changelog-docs.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ search:
77

88
(for EasyBuild release notes, see [EasyBuild release notes][release_notes])
99

10+
- **release 20230911.01** (*9 Sept 2023*): update
11+
release notes for EasyBuild v4.8.1 (see
12+
[EasyBuild v4.8.1 (11 Sept 2023)][release_notes_eb481])
13+
- **release 20230707.01** (*7 July 2023*): update
14+
release notes for EasyBuild v4.8.0 (see
15+
[EasyBuild v4.8.0 (7 July 2023)][release_notes_eb480])
1016
- **release 20230527.01** (*27 May 2023*): update
1117
release notes for EasyBuild v4.7.2 (see
1218
[EasyBuild v4.7.2 (27 May 2023)][release_notes_eb472])

docs/code-style.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The only (major) exception to PEP8 is our preference for longer line lengths: li
1919
## Notes
2020

2121
Code style in easyconfig files can be **automatically checked** using `--check-contrib`,
22-
for example: `eb --check-contrib sympy-1.3-intel-2018a-Python-2.7.14.eb`
22+
for example: `eb --check-contrib HPL-2.3-foss-2022b.eb`
2323
(see [Code style review][contributing_review_process_code_style] for more details).
2424

2525
Style guides that go a step beyond PEP8:

docs/hooks.md

Lines changed: 105 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,28 @@ eb ...
4343

4444
## Available hooks
4545

46-
Currently (since EasyBuild v3.7.0), three types of hooks are supported:
46+
Since EasyBuild v4.8.1, six different types of hooks are supported:
4747

48-
* `start_hook` and `end_hook`, which are triggered *once* before starting software installations,
49-
and *once* right after completing all installations, respectively
48+
* `start_hook`, `pre_build_and_install_loop_hook`, `post_build_and_install_loop_hook`, and `end_hook` which are triggered *once* right after
49+
EasyBuild starts, *once* before looping over the easyconfigs to be built, *once* after completing the loop over the eayconfigs to be installed,
50+
and *once* shortly before EasyBuild completes, respectively.
5051
* `parse_hook`, which is triggered when an easyconfig file is being parsed
5152
* `module_write_hook`, which is triggered right before a module file is written.
5253
This includes the temporary module file used when installing extensions and during the sanity check,
5354
as well as the devel module.
5455
* "*step*" hooks that are triggered before and after every step of each installation procedure that is performed,
55-
also aptly named '`pre`'- and '`post`'-hooks
56+
also aptly named '`pre`'- and '`post`' hooks.
57+
* `cancel_hook` and `fail_hook` which are triggered when a `KeyboardInterrupt` or `EasyBuildError` is raised,
58+
respectively.
59+
* `pre_run_shell_cmd_hook` and `post_run_shell_cmd_hook` which are triggered right before and after running
60+
a shell command, respectively.
5661

5762
The list of currently available hooks in order of execution,
5863
which can also be consulted using `eb --avail-hooks`, is:
5964

6065
* `start_hook` *(only called once in an EasyBuild session)*
6166
* `parse_hook` *(available since EasyBuild v3.7.0)*
67+
* `pre_build_and_install_loop` *(available since EasyBuild v4.8.1)*
6268
* `pre_fetch_hook`, `post_fetch_hook`
6369
* `pre_ready_hook`, `post_ready_hook`
6470
* `pre_source_hook`, `post_source_hook`
@@ -68,16 +74,27 @@ which can also be consulted using `eb --avail-hooks`, is:
6874
* `pre_build_hook`, `post_build_hook`
6975
* `pre_test_hook`, `post_test_hook`
7076
* `pre_install_hook`, `post_install_hook`
71-
* `pre_extensions_hook`, `post_extensions_hook`
77+
* `pre_extensions_hook`
78+
* `pre_single_extension_hook`, `post_single_extension_hook` *(available since EasyBuild v4.7.1)*
79+
* `post_extensions_hook`
80+
* `pre_postiter_hook`, `post_postiter_hook` *(available since EasyBuild v4.8.1)*
7281
* `pre_postproc_hook`, `post_postproc_hook`
7382
* `pre_sanitycheck_hook`, `post_sanitycheck_hook`
7483
* `pre_cleanup_hook`, `post_cleanup_hook`
75-
* `pre_module_hook`, `post_module_hook`
84+
* `pre_module_hook`
85+
* `module_write_hook` *(called multiple times per installation, available since EasyBuild v4.4.1)*
86+
* `post_module_hook`
7687
* `pre_permissions_hook`, `post_permissions_hook`
7788
* `pre_package_hook`, `post_package_hook`
7889
* `pre_testcases_hook`, `post_testcases_hook`
90+
* `post_build_and_install_loop` *(available since EasyBuild v4.8.1)*
7991
* `end_hook` *(only called once in an EasyBuild session)*
80-
* `module_write_hook` *(called multiple times per installation, available since EasyBuild v4.4.1)*
92+
* `cancel_hook` *(available since EasyBuild v4.8.1)*
93+
* `fail_hook` *(available since EasyBuild v4.8.1)*
94+
95+
`pre_run_shell_cmd_hook` and `post_run_shell_cmd_hook` *(available since EasyBuild v4.8.1)* are not included in
96+
the list above because they can not be put in a particular order relative to other hooks, since these hooks
97+
are triggered several times throughout an EasyBuild session.
8198

8299
All functions implemented in the provided Python module for which the name ends with `_hook` are considered.
83100

@@ -102,20 +119,46 @@ Run 'eb --avail-hooks' to get an overview of known hooks
102119
To implement hooks, simply define one or more functions in a Python module (`*.py`),
103120
each named after an available hook.
104121

122+
In hooks you have access to the full functionality provided by the EasyBuild framework,
123+
so do `import` from `easybuild.tools.*` (or other `easybuild.*` namespaces) to leverage
124+
those functions.
125+
105126
Do take into account the following:
106127

107-
* for `start_hook` and `end_hook`, no arguments are provided
108-
* for `parse_hook`, one argument is provided: the `EasyConfig` instance
109-
that corresponds to the easyconfig file being parsed (usually referred to as `ec`)
110-
* for `module_write_hook`, 3 arguments are provided:
111-
* the `EasyBlock` instance used to perform the installation (usually referred to as `self`)
112-
* the filepath of the module that will be written
113-
* the module text as a string
114-
The return value of this hook, when set, will replace the original text that is then written to the module file.
115-
* for the step hooks, one argument is provided:
116-
the `EasyBlock` instance used to perform the installation (usually referred to as `self`)
117-
* the parsed easyconfig file can be accessed in the step hooks via the `EasyBlock` instance,
118-
i.e., via `self.cfg`
128+
* [Hook arguments][hooks-arguments]
129+
* [Return value of hooks][hooks-return-value]
130+
* [Parse hook specifics][parse-hook-specifics]
131+
132+
133+
### Hook arguments {: #hooks-arguments }
134+
135+
* For both `start_hook` and `end_hook` no arguments are provided.
136+
* For `cancel_hook` and `fail_hook` the `KeyboardInterrupt` or `EasyBuildError` exception that was raised
137+
is provided as an argument.
138+
* For `parse_hook` the `EasyConfig` instance that corresponds to the easyconfig file being parsed
139+
(usually referred to as `ec`) is passed as an argument.
140+
* For `pre_build_and_install_loop_hook` a list of easyconfigs is provided as an argument.
141+
* For `post_build_and_install_loop_hook` a list of easyconfigs with build results is provided as an argument.
142+
* For `pre_run_shell_cmd_hook`, multiple arguments are passed:
143+
* An unnamed argument (often called `cmd`) that corresponds to the shell command that will be run,
144+
which could be provided either as a string value (like `"echo hello"`) or a list value (like `['echo', 'hello']`).
145+
* A named argument `work_dir` that specifies the path of the working directory in which the command will be run.
146+
* For interactive commands (which are run via the `run_cmd_qa` function), an additional named argument
147+
`interactive` is set to `True`.
148+
* For `post_run_shell_cmd_hook`, multiple arguments are passed:
149+
* An unnamed argument (often called `cmd`) that corresponds to the shell command that was run,
150+
which could be provided either as a string value (like `"echo hello"`) or a list value (like `['echo', 'hello']`).
151+
* A named argument `work_dir` that specifies the working directory in which the shell command was run.
152+
* A named argument `exit_code` that specifies the exit code of the shell command that was run.
153+
* A named argument `output` that specifies the output of the shell command that was run.
154+
* For interactive commands (which are run via the `run_cmd_qa` function), an additional named argument
155+
`interactive` is set to `True`.
156+
* For `module_write_hook`, 3 arguments are provided:
157+
* The `EasyBlock` instance used to perform the installation (usually referred to as `self`).
158+
* The filepath of the module that will be written.
159+
* The module text as a string.
160+
* For the step hooks, the `EasyBlock` instance used to perform the installation (usually referred to as `self`).
161+
The parsed easyconfig file can be accessed in the step hooks via the `EasyBlock` instance, i.e., via `self.cfg`.
119162

120163
It is recommended to anticipate possible changes in the provided (named) arguments,
121164
using the `*args` and `**kwargs` mechanism commonly used in Python. This
@@ -127,11 +170,22 @@ def pre_configure_hook(self, *args, **kwargs):
127170
...
128171
```
129172

130-
In hooks you have access to the full functionality provided by the EasyBuild framework,
131-
so do `import` from `easybuild.tools.*` (or other `easybuild.*` namespaces) to leverage
132-
those functions.
133173

134-
### Parse hook specifics
174+
### Return value of hooks {: #hooks-return-value }
175+
176+
The return value of a hook is usually ignored by EasyBuild, except in particular cases:
177+
178+
* If the `module_write_hook` returns a (string) value, it **replaces the original text that was going to be
179+
written to the module file**. This way the `module_write_hook` can extend, change, or entirely replace the
180+
module text that was provided as an argument.
181+
182+
* If the `pre_run_shell_cmd_hook` returns a value, it **replaces the shell command that was going to be run**.
183+
Hence, this hook can change or entirely replace particular shell commands right before they are executed.
184+
Note that the value type of the return value of `pre_run_shell_cmd_hook` *must* match with the type of the
185+
first (unnamed) argument that provides the shell command that would have been run originally.
186+
187+
188+
### Parse hook specifics {: #parse-hook-specifics }
135189

136190
`parse_hook` is triggered right *after* reading the easyconfig file,
137191
before further parsing of some easyconfig parameters (like `*dependencies`) into
@@ -220,7 +274,7 @@ To achieve the intended effect, you can either:
220274
```
221275

222276
A better approach for manipulating easyconfig parameters is to use the `parse_hook` that
223-
was introduced in EasyBuild v3.7.0 (see [Parse hook specifics](#parse-hook-specifics)),
277+
was introduced in EasyBuild v3.7.0 (see [Parse hook specifics][parse-hook-specifics]),
224278
where these kind of surprises will not occur (because templating is automatically disabled
225279
before `parse_hook` is called and restored immediately afterwards).
226280
See also [Example hook to inject a custom patch file](#inject-a-custom-patch-file).
@@ -276,3 +330,30 @@ def module_write_hook(self, filepath, module_txt, *args, **kwargs):
276330
replace = 'prepend_path("EBPYTHONPREFIXES", root)'
277331
return re.sub(search, replace, module_txt)
278332
```
333+
334+
### Log running of shell commands + prepend `make install` with `sudo`
335+
336+
```py
337+
shell_cmds_log = '/tmp/eb_shell_cmds.log'
338+
339+
def pre_run_shell_cmd_hook(cmd, work_dir=None, interactive=None):
340+
"""
341+
Log shell commands before they are run,
342+
and replace 'make install' with 'sudo make install'.
343+
"""
344+
with open(shell_cmds_log, 'a') as fp:
345+
cmd_type = 'interactive' if interactive else 'non-interactive'
346+
fp.write("%s command '%s' will be run in %s ...\n" % (cmd_type, cmd, work_dir))
347+
348+
if cmd == "make install":
349+
return "sudo make install"
350+
351+
352+
def post_run_shell_cmd_hook(cmd, work_dir=None, interactive=None, exit_code=None, output=None):
353+
"""
354+
Log shell commands that were run.
355+
"""
356+
with open(shell_cmds_log, 'a') as fp:
357+
cmd_type = 'interactive' if interactive else 'non-interactive'
358+
fp.write("%s command '%s' in %s exited with %s - output: %s\n" % (cmd_type, cmd, work_dir, exit_code, output))
359+
```

docs/installation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ $ module load EasyBuild
6262
$ module list
6363

6464
Currently Loaded Modules:
65-
1) EasyBuild/4.7.2
65+
1) EasyBuild/4.8.0
6666

6767
$ eb --version
68-
This is EasyBuild 4.7.2 (framework: 4.7.2, easyblocks: 4.7.2) on host example.local
68+
This is EasyBuild 4.8.0 (framework: 4.8.0, easyblocks: 4.8.0) on host example.local
6969
```
7070

7171
!!! tip
@@ -228,7 +228,7 @@ $ EB_VERBOSE=1 eb --version
228228
>> 'python3' version: 3.6.8, which matches Python 3 version requirement (>= 3.5)
229229
>> Selected Python command: python3 (/usr/bin/python3.6)
230230
>> python3.6 -m easybuild.main --version
231-
This is EasyBuild 4.7.2 (framework: 4.7.2, easyblocks: 4.7.2) on host example
231+
This is EasyBuild 4.8.0 (framework: 4.8.0, easyblocks: 4.8.0) on host example
232232
```
233233

234234

docs/locks.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Locks are created in the [locks directory][locks_dir].
2525
The lock created by EasyBuild is an empty directory (rather than a file),
2626
because that can be created more atomically on modern filesystems.
2727

28-
For example, if `OpenFOAM-7-foss-2019b.eb` is being installed to `/apps/easybuild/software`,
28+
For example, if `OpenFOAM-v2206-foss-2022a.eb` is being installed to `/apps/easybuild/software`,
2929
an empty directory that serves as a lock for this installation will be created at
3030
`/apps/easybuild/software/.locks/_apps_easybuild_software_OpenFOAM_7_foss_2019b.lock`
3131
(assuming the default [locks directory][locks_dir] is used).
@@ -60,20 +60,29 @@ performing those installations!**
6060

6161
#### Waiting for locks to be removed {: #locks_wait }
6262

63-
*(`--wait-on-lock`)*
63+
*(`--wait-on-lock-interval`)*
6464

65-
Using the `--wait-on-lock` configuration option, you can change how EasyBuild deals with existing locks,
66-
by specifying how frequently EasyBuild should check whether an existing lock was removed. By specifying a non-zero value `S`,
67-
you can indicate how many seconds EasyBuild should wait before checking again whether the lock is still in place.
65+
Wait interval (in seconds) to use when waiting for existing lock to be removed
6866

69-
!!! note
70-
EasyBuild will wait indefinitely for an existing lock to be removed if `--wait-on-lock` is set to a non-zero value...
67+
*(`--wait-on-lock-limit`)*
68+
69+
Maximum amount of time (in seconds) to wait until lock is released (0 means no waiting at all, exit with error;
70+
-1 means no waiting limit, keep waiting).
71+
72+
*(`--wait-on-lock <secs>`)* (DEPRECATED)
7173

74+
Using the `--wait-on-lock` configuration option, you can change how EasyBuild deals with existing locks, by specifying
75+
how frequently EasyBuild should check whether an existing lock was removed. By specifying a non-zero value `secs`, you
76+
can indicate how many seconds EasyBuild should wait before checking again whether the lock is still in place.
77+
78+
!!! warning
79+
The `--wait-on-lock` configuration option is deprecated, please use `--wait-on-lock-interval` and `--wait-on-lock-limit` instead!
80+
81+
!!! note
7282
If the lock is never removed, the EasyBuild session will never terminate; it will keep checking every `S` seconds whether the lock is still in place.
7383

7484
By default, EasyBuild will *abort* the installation with an error like "`Lock ... already exists, aborting!`"
75-
if a corresponding lock already exists, which is equivalent to setting `--wait-on-lock` to zero (`0`),
76-
implying that no waiting should be done at all.
85+
if a corresponding lock already exists.
7786

7887

7988
### Locks directory {: #locks_dir }

docs/log-files.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,24 @@ file is copied to the install directory for future reference.
1717

1818
By default, the application log file is copied to a subdirectory of the
1919
installation prefix named `easybuild`, and has a filename like
20-
`easybuild-HPL-2.0-20141103.104412.log` for example, which corresponds
20+
`easybuild-WRF-4.4.1-20230426.143346.log` for example, which corresponds
2121
to the filename template
2222
`easybuild-%(name)s-%(version)s-%(date)s.%(time)s.log`. This aspect can
2323
be tweaked via the `--logfile-format` configuration option.
2424

2525
Example:
2626

2727
``` console
28-
$ eb HPL-2.0-goolf-1.4.10.eb
29-
== temporary log file in case of crash /tmp/easybuild-rHHgBu/easybuild-XD0Ae_.log
28+
$ eb WRF-4.4.1-foss-2022b-dmpar.eb
29+
== Temporary log file in case of crash /tmp/eb-1zbqix6e/easybuild-1ixy86r2.log
3030
[...]
31-
== building and installing HPL/2.0-goolf-1.4.10...
31+
== building and installing WRF/4.4.1-foss-2022b-dmpar...
3232
[...]
3333
== COMPLETED: Installation ended successfully
34-
== Results of the build can be found in the log file /home/example/.local/easybuild/software/HPL/2.0-goolf-1.4.10/easybuild/easybuild-HPL-2.0-20141103.104412.log
34+
== Results of the build can be found in the log file(s) /home/example/.local/easybuild/software/WRF/4.4.1-foss-2022b-dmpar/easybuild/easybuild-WRF-4.4.1-20230531.181321.log
3535
== Build succeeded for 1 out of 1
36-
== temporary log file /tmp/easybuild-rHHgBu/easybuild-XD0Ae_.log has been removed.
37-
== temporary directory /tmp/easybuild-rHHgBu has been removed.
36+
== temporary log file /tmp/eb-1zbqix6e/easybuild-1ixy86r2.log* has been removed.
37+
== temporary directory /tmp/eb-1zbqix6e has been removed.
3838
```
3939

4040
!!! note
@@ -63,16 +63,16 @@ Each log message as emitted by EasyBuild follows a well-defined format.
6363
Example:
6464

6565
``` console
66-
== 2014-11-03 13:34:31,906 main.EB_HPL INFO This is EasyBuild 1.15.2 (framework: 1.15.2, easyblocks: 1.15.2) on host example.
66+
== 2023-05-31 16:11:21,044 easyblock.py:313 INFO This is EasyBuild 4.7.3 (framework: 4.7.3, easyblocks: 4.7.3) on host example.
6767
```
6868

6969
Each log line consists of the following parts:
7070

7171
- a prefix label `==`, which is useful to discriminate between
7272
EasyBuild log messages and the output of executed shell commands;
73-
- date and time information (e.g., `2014-11-03 13:34:31,906`);
73+
- date and time information (e.g., `2023-05-31 16:11:21,044`);
7474
- the Python module/class/function that is responsible for the log
75-
message (e.g., `main.EB_HPL`);
75+
message (e.g., `easyblock.py:313`);
7676
- the log level (e.g., `INFO`);
7777
- and a string with the actual log message at the end
7878

@@ -88,10 +88,10 @@ For each step performed in the build and installation process,
8888
corresponding log messages is emitted. For example:
8989

9090
``` console
91-
== 2014-11-03 13:34:48,816 main.EB_HPL INFO configuring...
92-
== 2014-11-03 13:34:48,817 main.EB_HPL INFO Starting configure step
91+
== 2023-05-31 16:11:44,977 build_log.py:267 INFO configuring...
92+
== 2023-05-31 16:11:44,981 easyblock.py:3926 INFO Starting configure step
9393
[...]
94-
== 2014-11-03 13:34:48,823 main.EB_HPL INFO Running method configure_step part of step configure
94+
== 2023-05-31 16:11:44,982 easyblock.py:3934 INFO Running method configure_step part of step configure
9595
```
9696

9797
This allows you to navigate a log file step by step, for example using
@@ -104,9 +104,10 @@ command line, the location where the command was executed and the
104104
command's output and exit code. For example:
105105

106106
``` console
107-
== 2014-11-03 13:34:48,823 main.run DEBUG run_cmd: running cmd /bin/bash make_generic (in /tmp/user/easybuild_build/HPL/2.0/goolf-1.4.10/hpl-2.0/setup)
108-
== 2014-11-03 13:34:48,823 main.run DEBUG run_cmd: Command output will be logged to /tmp/easybuild-W85p4r/easybuild-run_cmd-XoJwMY.log
109-
== 2014-11-03 13:34:48,849 main.run INFO cmd "/bin/bash make_generic" exited with exitcode 0 and output:
107+
== 2023-05-31 18:59:24,222 run.py:176 DEBUG run_cmd: Output of "/home/example/.local/easybuild/software/WRF/4.4.1-foss-2022b-dmpar/WRF-4.4.1/compile -j 8 wrf" will be logged to /tmp/eb-1zbqix6e/easybuild-run_cmd-ueqo5bn0.log
108+
== 2023-05-31 18:59:24,225 run.py:217 DEBUG run_cmd: running cmd /home/example/.local/easybuild/software//WRF/4.4.1-foss-2022b-dmpar/WRF-4.4.1/compile -j 8 wrf (in /home/example/.local/easybuild/software//WRF/4.4.1-foss-2022b-dmpar/WRF-4.4.1)
109+
[...]
110+
== 2023-05-31 20:06:35,979 run.py:650 DEBUG cmd "/home/example/.local/easybuild/software/WRF/4.4.1-foss-2022b-dmpar/WRF-4.4.1/compile -j 8 wrf" exited with exit code 0 and output:
110111
```
111112

112113
If you are primarily interested in the different commands as they were

0 commit comments

Comments
 (0)