Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding testing of a symlink tree install #502

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0cd0656
adding testing of a symlink tree install
vsoch Mar 3, 2022
016020b
unset symlink_home
vsoch Mar 3, 2022
6629b78
version bump
vsoch Mar 3, 2022
43e4a0b
missing module load
vsoch Mar 3, 2022
1a28792
adding symlink_tree setting to indicate to always set
vsoch Mar 4, 2022
e98d3df
missing command argument
vsoch Mar 4, 2022
7cf59d3
symlink_home -> symlink_tree and --symlink-tree instead of --symlink
vsoch Mar 4, 2022
504d66d
forgot to add dest
vsoch Mar 4, 2022
4e56788
ensure that we cleanup symlink directory of .version and empty
vsoch Mar 4, 2022
60e5867
ensure we dont create symlink version unless tcl and default version …
vsoch Mar 4, 2022
10cf953
do not require symlink_base to be defined
vsoch Mar 9, 2022
6e08a76
bugfix: without this, create_symlink would only be called based on th…
muffato Mar 9, 2022
7d7d90c
Merge branch 'main' into add/symlink-install
vsoch Mar 9, 2022
0be2837
verison bump
vsoch Mar 9, 2022
5bb4a06
Minor refactoring of `check_symlink` (#510)
muffato Mar 10, 2022
a1e8fc9
Merge branch 'main' into add/symlink-install
vsoch Mar 20, 2022
2277e6c
running black
vsoch Mar 20, 2022
18a76ee
Skip `module` in the symlinks (#511)
muffato Apr 1, 2022
39ebfae
hopefully resolving merge conflicts
vsoch Apr 2, 2022
7686e52
add force and symlink arg back in
vsoch Apr 2, 2022
01bbe7b
do not pin black
vsoch Apr 2, 2022
102c996
mucking things up
vsoch Apr 2, 2022
12e00ef
mucking things up
vsoch Apr 2, 2022
00a8912
Completion of the symlink feature (#539)
muffato Apr 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,12 @@ jobs:
cat test_output
grep --quiet 'Python 3.9.5' test_output
rm test_output
shpc uninstall --force python:3.9.5-alpine
shpc uninstall --force python:3.9.5-alpine

# Try creating symlink install
mkdir -p tmp-modules
shpc config set symlink_base:tmp-modules
shpc install python:3.9.5-alpine --symlink-tree

- name: Run python module tests (tcsh)
shell: tcsh -e {0}
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ and **Merged pull requests**. Critical items to know are:
The versions coincide with releases on pip. Only major versions will be released as tags on Github.

## [0.0.x](https://github.com/singularityhub/singularity-hpc/tree/main) (0.0.x)
- support for installing to symlink tree (0.0.46)
- also including cleanup of symlink tree on uninstall
- ability to set custom config variable on the fly with -c
- Adding support for wrapper scripts for global and container.yaml (0.0.45)
- Lua and tcl module file bug fixes for shell functions and aliases (0.0.44)
- restoring -B for Singularity bindpaths over using envar
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,4 @@


def setup(app):
app.add_stylesheet("sphinx-argparse.css")
app.add_css_file("sphinx-argparse.css")
70 changes: 70 additions & 0 deletions docs/getting_started/user-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ You can then easily install, load, and use modules:
$ module load biocontainers/samtools
$ samtools

Or set a configuration value on the fly for any command:

.. code-block:: console

$ shpc install -c set:symlink_base:/tmp/modules biocontainers/samtools

The above assumes that you've installed the software, and have already
added the modules folder to be seen by your module software. If your module
Expand Down Expand Up @@ -174,6 +179,12 @@ variable replacement. A summary table of variables is included below, and then f
* - container_tech
- The container technology to use (singularity or podman)
- singularity
* - symlink_base
- If set, where you want to install a simplified module tree to using ``--symlink-tree``
- unset
* - symlink_tree
- If set to true, ALWAYS generate a symlink tree given that a symlink base is defined regardless of ``--symlink-tree`` flag
- false
* - updated_at
- a timestamp to keep track of when you last saved
- never
Expand Down Expand Up @@ -233,6 +244,14 @@ variable replacement. A summary table of variables is included below, and then f
- All features default to null


Note that any configuration value can be set permanently by using ``shpc config``
or manually editing the file, but you can also set config values "one off" as follows:

.. code-block:: console

$ shpc install -c set:symlink_base:/tmp/modules ghcr.io/autamus/clingo


These settings will be discussed in more detail in the following sections.

Features
Expand Down Expand Up @@ -359,6 +378,57 @@ you can add or remove entries via the config variable ``registry``
# Note that "add" is used for lists of things (e.g., the registry config variable is a list)
and "set" is used to set a key value pair.

Symlink Base
------------

By default, your modules are installed to your ``module_base`` described above with a complete
namespace, meaning the container registry from where they arise. We do this so that the namespace
is consistent and there are no conflicts. However, if you want a simplified tree to install from,
meaning the module full names are _just_ the final container name, you can set the ``symlink_base``
in your settings to a different root. For example, let's say we want to install a set of modules,
after seting our symlink base to ``tmp-modules``. We could do:

.. code-block:: console

$ shpc install ghcr.io/autamus/clingo --symlink-tree
$ shpc install ghcr.io/autamus/samtools --symlink-tree

Then, for example, if you want to load the modules, you'll see the shorter names are
available!

.. code-block:: console

$ module use ./tmp-modules
$ module load clingo/5.5.1/module

This is much more efficient compared to the install that uses the full paths:

.. code-block:: console

$ module use ./modules
$ module load ghcr.io/autamus/clingo/5.5.1/module

Since we install based on the container name *and* version tag, this even gives you
the ability to install versions from different container bases in the same root.
If there is a conflict, you will be given the option to exit (and abort) or continue.
Finally, if you need an easy way to run through the containers you've already installed
to create the links:


.. code-block:: console

for module in $(shpc list); do
shpc install $module --symlink-tree
done

And that will reinstall the modules you have installed, but in their symlink tree location.


.. warning::

Be cautious about creating symlinks in containers or other contexts where a bind
could eliminate the symlink or make the path non-existent.


Module Names
------------
Expand Down
19 changes: 18 additions & 1 deletion shpc/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ def get_parser():
help="custom path to settings file.",
)

# On the fly updates to config params
parser.add_argument(
"-c",
dest="config_params",
help=""""customize a config value on the fly to ADD/SET/REMOVE for a command
shpc -c set:key:value <command> <args>
shpc -c add:registry:/tmp/registry <command> <args>
shpc -c rm:registry:/tmp/registry""",
action="append",
)

parser.add_argument(
"--version",
dest="version",
Expand Down Expand Up @@ -89,6 +100,13 @@ def get_parser():
"install_recipe",
help="recipe to install\nshpc install python\nshpc install python:3.9.5-alpine",
)
install.add_argument(
"--symlink-tree",
dest="symlink",
help="install to symlink tree too.",
default=False,
action="store_true",
)

# List installed modules
listing = subparsers.add_parser("list", description="list installed modules.")
Expand Down Expand Up @@ -147,7 +165,6 @@ def get_parser():

config.add_argument(
"--central",
"-c",
dest="central",
help="make edits to the central config file.",
default=False,
Expand Down
3 changes: 3 additions & 0 deletions shpc/client/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ def main(args, parser, extra, subparser):
module=args.module,
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
cli.add(args.sif_path[0], args.module_id[0])
3 changes: 3 additions & 0 deletions shpc/client/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ def main(args, parser, extra, subparser):
module=args.module,
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
cli.check(args.module_name)
23 changes: 5 additions & 18 deletions shpc/client/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,12 @@ def main(args, parser, extra, subparser):
return cli.settings.inituser()
if command == "edit":
return cli.settings.edit()
elif command in ["set", "add", "remove"]:
for param in args.params:
if ":" not in param:
logger.warning(
"Param %s is missing a :, should be key:value pair. Skipping."
% param
)
continue

key, value = param.split(":", 1)
if command == "set":
cli.settings.set(key, value)
logger.info("Updated %s to be %s" % (key, value))
elif command == "add":
cli.settings.add(key, value)
logger.info("Added %s to %s" % (key, value))
elif command == "remove":
cli.settings.remove(key, value)
logger.info("Removed %s from %s" % (key, value))
if command in ["set", "add", "remove"]:

# Update each param
for param in args.params:
cli.settings.update_param(command, param)

# Save settings
cli.settings.save()
Expand Down
2 changes: 2 additions & 0 deletions shpc/client/docgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ def main(args, parser, extra, subparser):
module=args.module,
container_tech=args.container_tech,
)
# Update config settings on the fly
cli.settings.update_params(args.config_params)
cli.docgen(args.module_name)
2 changes: 2 additions & 0 deletions shpc/client/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def main(args, parser, extra, subparser):
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
result = cli.get(args.module_name, args.env_file)
if result:
print(result)
3 changes: 3 additions & 0 deletions shpc/client/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def main(args, parser, extra, subparser):
settings_file=args.settings_file,
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
metadata = cli.inspect(args.module_name)

# Case 1: dump entire thing as json
Expand Down
7 changes: 6 additions & 1 deletion shpc/client/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ def main(args, parser, extra, subparser):
module=args.module,
container_tech=args.container_tech,
)
cli.install(args.install_recipe)

# Update config settings on the fly
cli.settings.update_params(args.config_params)

# And do the install
cli.install(args.install_recipe, symlink=args.symlink)
2 changes: 2 additions & 0 deletions shpc/client/listing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ def main(args, parser, extra, subparser):
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
cli.list(args.pattern, args.names_only, short=args.short)
3 changes: 3 additions & 0 deletions shpc/client/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def main(args, parser, extra, subparser):

cli = get_client(quiet=args.quiet, settings_file=args.settings_file)

# Update config settings on the fly
cli.settings.update_params(args.config_params)

# Case 1: we need to unset a namespace
if not args.namespace:
sys.exit("Please choose: shpc use <namespace> or shpc unset.")
Expand Down
6 changes: 5 additions & 1 deletion shpc/client/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ def main(args, parser, extra, subparser):
def create_client(args):
from shpc.main import get_client

return get_client(
cli = get_client(
quiet=args.quiet,
settings_file=args.settings_file,
module=args.module,
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
return cli


def ipython(args):
"""
Expand Down
3 changes: 3 additions & 0 deletions shpc/client/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ def main(args, parser, extra, subparser):
from shpc.main import get_client

cli = get_client(quiet=args.quiet, settings_file=args.settings_file)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
cli.show(args.name, names_only=not args.versions, filter_string=args.filter_string)
2 changes: 2 additions & 0 deletions shpc/client/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def main(args, parser, extra, subparser):
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
cli.test(
args.module_name,
test_exec=args.test_exec,
Expand Down
3 changes: 3 additions & 0 deletions shpc/client/uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ def main(args, parser, extra, subparser):
module=args.module,
container_tech=args.container_tech,
)

# Update config settings on the fly
cli.settings.update_params(args.config_params)
cli.uninstall(args.uninstall_recipe, args.force)
Loading