Skip to content

Commit ee4881a

Browse files
authored
adding uninstall all and fixing bug with depot install (#626)
* adding uninstall all and fixing bug with depot install * ensure path is abspath Signed-off-by: vsoch <[email protected]>
1 parent e1afb48 commit ee4881a

File tree

8 files changed

+84
-13
lines changed

8 files changed

+84
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
1414
The versions coincide with releases on pip. Only major versions will be released as tags on Github.
1515

1616
## [0.0.x](https://github.com/singularityhub/singularity-hpc/tree/main) (0.0.x)
17+
- Support for uninstall and fixing bug in biocontainers install (0.1.18)
1718
- GitHub action to update a registry from a cache or listing (0.1.17)
1819
- Support for "remove" command to more easily remove / uninstall entries
1920
- Fix bugs uninstalling all tags of a module (0.1.16)

docs/getting_started/user-guide.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1608,7 +1608,15 @@ You can also uninstall an entire family of modules:
16081608
$ shpc uninstall python
16091609
16101610
The uninstall will go up to the top level module folder but not remove it
1611-
in the case that you've added it to your ``MODULEPATH``.
1611+
in the case that you've added it to your ``MODULEPATH``. As of version 0.1.18,
1612+
you can also ask to uninstall all:
1613+
1614+
1615+
.. code-block:: console
1616+
1617+
$ shpc uninstall --all --force
1618+
1619+
16121620
16131621
.. _getting_started-commands-pull:
16141622

example/biocontainer-match.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
from shpc.logger import logger
2626
from shpc.main import get_client
27+
from shpc.main.container import ContainerConfig
2728

2829

2930
def get_parser():
@@ -84,9 +85,10 @@ def main():
8485
tagged = f"{container}:{tag}"
8586

8687
match = cli.registry.find(tagged)
88+
89+
# We don't have an exact match but can share aliases
8790
if not match:
88-
tagged = container
89-
match = cli.registry.find(tagged)
91+
match = cli.registry.find(container)
9092

9193
if not match:
9294
logger.warning(f"Warning: no match for {path}")
@@ -97,10 +99,28 @@ def main():
9799
seen.add(repo)
98100
continue
99101

100-
print(f"Installing {path} to {tagged}")
102+
# Note we need to install the correct version but using aliases
103+
# from the one we have (and they should be comparable)
104+
print(f"Installing {path} to {tagged} with aliases from {match.module}")
105+
106+
# Make sure we use the full container path
107+
path = os.path.join(depot, path)
108+
109+
# Create a new module, force the tag since the digest could be unknown
110+
module = cli.new_module(tagged)
111+
module.config = ContainerConfig(match)
112+
module.config.set_tag(tag, force=True)
113+
module.load_config(module.config, tagged)
114+
module.add_local_container(path, keep_path=True)
101115

102116
# We found a match! Install it (forcing keep path to not copy the container)
103-
cli.install(tagged, force=args.force, container_image=path, keep_path=True)
117+
cli.install(
118+
tagged,
119+
force=args.force,
120+
module=module,
121+
container_image=path,
122+
keep_path=True,
123+
)
104124
seen.add(repo)
105125

106126

shpc/client/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,15 @@ def get_parser():
310310
action="store_true",
311311
)
312312
uninstall.add_argument(
313-
"uninstall_recipe", help="module to uninstall (module/version)"
313+
"uninstall_recipe", help="module to uninstall (module/version)", nargs="?"
314+
)
315+
uninstall.add_argument(
316+
"--all",
317+
"-a",
318+
dest="uninstall_all",
319+
help="uninstall all recipes",
320+
default=False,
321+
action="store_true",
314322
)
315323

316324
# Update gets latest tags from OCI registries

shpc/client/uninstall.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
__license__ = "MPL 2.0"
44

55
import shpc.utils
6+
from shpc.logger import logger
67

78

89
def main(args, parser, extra, subparser):
@@ -20,4 +21,14 @@ def main(args, parser, extra, subparser):
2021

2122
# Update config settings on the fly
2223
cli.settings.update_params(args.config_params)
23-
cli.uninstall(args.uninstall_recipe, force=args.force)
24+
if args.uninstall_all:
25+
if not args.force:
26+
if not shpc.utils.confirm_uninstall("all modules?"):
27+
return
28+
for module_name in cli.list(return_modules=True):
29+
cli.uninstall(module_name, force=True)
30+
31+
else:
32+
if not args.uninstall_recipe:
33+
logger.exit("Please provide a recipe to uninstall or select --all")
34+
cli.uninstall(args.uninstall_recipe, force=args.force)

shpc/main/container/config.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,18 @@ def set(self, key, value):
213213
def add_tag(self, key, value):
214214
self.entry._config["tags"][key] = value
215215

216-
def set_tag(self, tag):
216+
def set_tag(self, tag, force=False):
217217
"""
218218
Set a tag to be the config default (defaults to latest otherwise)
219219
"""
220220
# If a tag isn't provided, default to latest
221221
if not tag:
222222
self.tag = self.tags.latest
223223

224+
# Force means we are explicitly adding a container knowing we won't check the tag
225+
elif force:
226+
self.tag = Tag(tag, "unknown")
227+
224228
# This way, if the user explicitly asks for a tag that does not exist
225229
# this value will be none (and we can raise an error)
226230
else:

shpc/main/modules/base.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,17 +258,25 @@ def get(self, module_name, env_file=False):
258258
return self.container.get_environment_file(module_name)
259259
return self.container.get(module_name)
260260

261-
def list(self, pattern=None, names_only=False, out=None, short=False):
261+
def list(
262+
self,
263+
pattern=None,
264+
names_only=False,
265+
out=None,
266+
short=False,
267+
return_modules=False,
268+
):
262269
"""
263270
List installed modules.
264271
"""
265-
self._list_modules(
272+
return self._list_modules(
266273
self.settings.module_base,
267274
self.modulefile,
268275
pattern,
269276
names_only,
270277
out,
271278
short=short,
279+
return_modules=return_modules,
272280
)
273281

274282
def docgen(self, module_name, registry=None, out=None, branch="main"):
@@ -328,14 +336,25 @@ def inspect(self, module_name):
328336
return self.container.inspect(image)
329337

330338
def _list_modules(
331-
self, base, filename, pattern=None, names_only=False, out=None, short=False
339+
self,
340+
base,
341+
filename,
342+
pattern=None,
343+
names_only=False,
344+
out=None,
345+
short=False,
346+
return_modules=False,
332347
):
333348
"""
334349
A shared function to list modules or registry entries.
335350
"""
336351
out = out or sys.stdout
337352
modules = self._get_module_lookup(base, filename, pattern)
338353

354+
# Return names
355+
if return_modules:
356+
return modules
357+
339358
# If we don't have modules, exit early
340359
if not modules:
341360
logger.exit("You don't have any install modules. Try shpc show.", 0)
@@ -424,7 +443,7 @@ def install(
424443
"force" is currently not used.
425444
"""
426445
# Create a new module
427-
module = self.get_module(
446+
module = kwargs.get("module") or self.get_module(
428447
name, container_image=container_image, keep_path=keep_path
429448
)
430449

shpc/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
__copyright__ = "Copyright 2021-2023, Vanessa Sochat"
33
__license__ = "MPL 2.0"
44

5-
__version__ = "0.1.17"
5+
__version__ = "0.1.18"
66
AUTHOR = "Vanessa Sochat"
77
88
NAME = "singularity-hpc"

0 commit comments

Comments
 (0)