Skip to content

Instantly share code, notes, and snippets.

@saravanabalagi
Last active October 20, 2022 17:23
Show Gist options
  • Save saravanabalagi/688e34150506759ea9d493fc913222d1 to your computer and use it in GitHub Desktop.
Save saravanabalagi/688e34150506759ea9d493fc913222d1 to your computer and use it in GitHub Desktop.
Singularity Module

Singualarity Module

A convenience python script that helps create shortcuts in host machine to programs inside of singularity containers.

  • Place this inside ~/.local/bin and make sure you have export PATH="$HOME/.local/bin:$PATH" in .bashrc or .zshrc
  • Make module executable by running chmod +x ~/.local/bin/module
  • To load a shortcut to node from dev singularity instance into ~/.local/bin:
module load node dev

Then simply doing node --version should use the node inside the container.

  • To remove node,
module remove node

This obviously requires the instance to be loaded when the executable is used.

#!/usr/bin/python3
import argparse
import subprocess
import sys
import os
sys.tracebacklimit = 0
parser = argparse.ArgumentParser()
parser.add_argument('action', choices=['load', 'remove'])
parser.add_argument('module')
parser.add_argument('instance', nargs='?', default='',
help='instance[:module_path], if module path is not given, '
'an executable with the module name should be present inside the container')
args = parser.parse_args()
action = args.action
module = args.module
instance = args.instance
module_path = module
filepath = os.path.expanduser(f'~/.local/bin/{module}')
if action == 'load' and len(instance) == 0:
parser.error('instance is required when using load')
colon_idx = instance.find(':')
if colon_idx >= 0:
instance = instance[:colon_idx]
module_path = instance[colon_idx+1:]
if action == 'load':
# validate
cmd = f'singularity exec instance://{instance} which {module_path} | wc -l'
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode == 0 and not result.stderr:
num_lines_which = int(result.stdout)
if not num_lines_which > 0:
raise IOError(f'Could not find {module_path} in instance {instance}')
else:
print(result.stderr, end='')
exit()
# create file
content = [
f'#!/bin/sh',
f'singularity exec instance://{instance} {module_path} "$@"'
]
with open(filepath, 'w') as f:
for line in content:
print(line, file=f)
# verify if file exists
if not os.path.exists(filepath):
raise IOError(f'could not create {filepath}')
# make file executable
cmd = f'chmod +x {filepath}'
result = subprocess.run(cmd, shell=True)
if result.returncode == 0:
print(f'module {module} loaded successfully')
else:
print(f'Process exited with return code {result.returncode}')
if action == 'remove':
if not os.path.exists(filepath):
raise IOError(f'module {module} does not exist')
os.remove(filepath)
print(f'module {module} unloaded successfully')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment