Skip to content

Commit

Permalink
add pre-install hook, similar to post-install hook feature
Browse files Browse the repository at this point in the history
  • Loading branch information
bcumming committed Sep 6, 2023
1 parent 9f21a18 commit 0d422a8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 13 deletions.
14 changes: 12 additions & 2 deletions docs/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ A recipe is comprised of the following yaml files in a directory:
* `repo`: _optional_ custom spack package definitions.
* `extra`: _optional_ additional meta data to copy to the meta data of the stack.
* `post-install`: _optional_ a script to run after Spack has been executed to build the stack.
* `pre-install`: _optional_ a script to run any packages have been built.

## Configuration

Expand Down Expand Up @@ -332,14 +333,14 @@ Post install scripts can be used to modify or extend an environment with operati
The following steps are effectively run, where we assume that the recipe is in `$recipe` and the mount point is the default `/user-environment`:

```bash
# copy the
# copy the post-install script to the mount point
cp "$recipe"/post-install /user-environment
chmod +x /user-environment/post-install
# apply Jinja templates
jinja -d env.json /user-environment/post-install > /user-environment/post-install
# execute the script from inside the mount point
# execute the script from the mount point
cd /user-environment
/user-environment/post-install
```
Expand Down Expand Up @@ -368,6 +369,15 @@ echo "export PATH=$gmx_path:$PATH" >> {{ env.mount }}/activate.sh
!!! note
The script does not have to be bash - it can be in any scripting language, such as Python or Perl, that is available on the target system.

## Pre install configuration

Similarly to the post-install hook, if a `pre-install` script is provided in the recipe, it will be run during the build process:

* directly after the initial test that Spack has been installed correctly;
* directly before the build cache is configured, or the first compiler environment is concretised.

The pre-install script is copied, tempalted and executed similarly to the post-install hook (see above).

## Meta-Data

Stackinator generates meta-data about the stack to the `extra` path of the installation path.
Expand Down
40 changes: 30 additions & 10 deletions stackinator/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def generate(self, recipe):
cache=recipe.mirror,
modules=recipe.config["modules"],
post_install_hook=recipe.post_install_hook,
pre_install_hook=recipe.pre_install_hook,
verbose=False,
)
)
Expand All @@ -207,6 +208,15 @@ def generate(self, recipe):
for f_etc in ["Make.inc", "bwrap-mutable-root.sh", "add-compiler-links.py"]:
shutil.copy2(etc_path / f_etc, self.path / f_etc)


# used to configure both pre and post install hooks, if they are provided.
hook_env = {
"mount": recipe.mount,
"config": recipe.mount / "config",
"build": self.path,
"spack": self.path / "spack",
}

# copy post install hook file, if provided
post_hook = recipe.post_install_hook
if post_hook is not None:
Expand All @@ -215,19 +225,29 @@ def generate(self, recipe):
loader=jinja2.FileSystemLoader(recipe.path)
)
post_hook_template = jinja_recipe_env.get_template("post-install")
hook_destination = store_path / "post-install-hook"

with hook_destination.open("w") as f:
hook_env = {
"mount": recipe.mount,
"config": recipe.mount / "config",
"build": self.path,
"spack": self.path / "spack",
}
post_hook_destination = store_path / "post-install-hook"

with post_hook_destination.open("w") as f:
f.write(post_hook_template.render(env=hook_env, verbose=False))
f.write("\n")

os.chmod(hook_destination, os.stat(hook_destination).st_mode | stat.S_IEXEC)
os.chmod(post_hook_destination, os.stat(post_hook_destination).st_mode | stat.S_IEXEC)

# copy pre install hook file, if provided
pre_hook = recipe.pre_install_hook
if pre_hook is not None:
self._logger.debug("installing pre-install-hook script")
jinja_recipe_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(recipe.path)
)
pre_hook_template = jinja_recipe_env.get_template("pre-install")
pre_hook_destination = store_path / "pre-install-hook"

with pre_hook_destination.open("w") as f:
f.write(pre_hook_template.render(env=hook_env, verbose=False))
f.write("\n")

os.chmod(pre_hook_destination, os.stat(pre_hook_destination).st_mode | stat.S_IEXEC)

# Generate the system configuration: the compilers, environments, etc.
# that are defined for the target cluster.
Expand Down
16 changes: 16 additions & 0 deletions stackinator/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ def __init__(self, args):
else:
self._logger.debug("no post install hook provided")

# optional pre install hook
if self.pre_install_hook is not None:
self._logger.debug(f"pre install hook {self.pre_install_hook}")
else:
self._logger.debug("no pre install hook provided")

# Returns:
# Path: of the recipe extra path if it exists
# None: if there is no user-provided extra path in the recipe
Expand All @@ -142,6 +148,16 @@ def post_install_hook(self):
return hook_path
return None

# Returns:
# Path: of the recipe pre install script if it was provided
# None: if there is no user-provided pre install script
@property
def pre_install_hook(self):
hook_path = self.path / "pre-install"
if hook_path.exists() and hook_path.is_file():
return hook_path
return None

# Returns a dictionary with the following fields
#
# root: /path/to/cache
Expand Down
6 changes: 5 additions & 1 deletion stackinator/templates/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ spack-setup: spack-version
$(SANDBOX) $(SPACK) spec zlib > /dev/null; \
printf "yup\n"

mirror-setup: spack-setup
pre-install: spack-setup
$(SANDBOX) $(STORE)/pre-install-hook

mirror-setup: spack-setup{% if pre_install_hook %} pre-install{% endif %}

{% if cache %}
$(SANDBOX) $(SPACK) buildcache keys --install --trust
{% if cache.key %}
Expand Down
18 changes: 18 additions & 0 deletions unittests/recipes/host-recipe/pre-install
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

echo "====================================="
echo "===== pre install hook ====="

mount_path={{ env.mount }}
build_path={{ env.build }}
echo RUNNING IN $mount_path with build path $build_path

echo
echo "===== environment variabls ====="
printenv

echo
echo "===== create \"config\" file {{ env.build }}/configxxx ====="
echo "$(date)" > "$build_path/configxxx"

echo "====================================="

0 comments on commit 0d422a8

Please sign in to comment.