diff --git a/render/__main__.py b/render/__main__.py
index 63c11dd..6f84032 100644
--- a/render/__main__.py
+++ b/render/__main__.py
@@ -11,7 +11,7 @@ from traceback import format_exc
from flask import Flask, render_template, request
from glicid_spawner.form import TEMPLATES, options_from_form
from glicid_spawner.micromamba import MicromambaEnv
-from glicid_spawner.resources import CPU, MEMORY, gpu_max_duration
+from glicid_spawner.resources import CPU, MEMORY, get_folders, gpu_max_duration
from glicid_spawner.slurm import gres, sinfo_from_file
from livereload import Server
@@ -22,6 +22,7 @@ ENVS = [
MicromambaEnv('USER', 'bar', f'/{USERNAME}/envs/bar'),
MicromambaEnv('GLOBAL', 'baz', '/global/envs/baz'),
]
+FOLDERS = get_folders(USERNAME)
# Dummy SLURM config
DATA = Path(__file__).parent / '..' / 'tests' / 'data'
@@ -38,6 +39,7 @@ GPU_MULTI_CLUSTER = gpu_max_duration(gres(SLURM_MULTI_CLUSTER))
# Format dummy options
OPTIONS = {
'username': USERNAME,
+ 'folders': FOLDERS,
'envs': ENVS,
'cpus': CPU,
'mems': MEMORY,
diff --git a/src/glicid_spawner/form.py b/src/glicid_spawner/form.py
index aa4a87b..143e228 100644
--- a/src/glicid_spawner/form.py
+++ b/src/glicid_spawner/form.py
@@ -3,7 +3,7 @@
from jinja2 import Environment, PackageLoader, select_autoescape
from .micromamba import get_envs
-from .resources import CPU, GPU_DEFAULTS, MEMORY, gpu_max_duration
+from .resources import CPU, GPU_DEFAULTS, MEMORY, get_folders, gpu_max_duration
from .slurm import gres, sinfo
TEMPLATES = Environment(
@@ -21,6 +21,7 @@ def options_attrs(username: str) -> dict:
return {
'username': username,
+ 'folders': get_folders(username),
'envs': get_envs(username),
'cpus': CPU,
'mems': MEMORY,
@@ -38,6 +39,7 @@ def options_form(username: str) -> str:
def options_from_form(formdata) -> dict:
"""Export options from default form."""
# Parse form data response
+ workdir = formdata['workdir'][0]
env = formdata['python-env'][0]
cpu = int(formdata['cpu'][0])
mem = int(formdata['mem'][0])
@@ -52,6 +54,7 @@ def options_from_form(formdata) -> dict:
# Export options
options = {
+ 'workdir': workdir,
'pyenv': env,
'nprocs': cpu,
'memory': f'{mem}GB',
diff --git a/src/glicid_spawner/resources.py b/src/glicid_spawner/resources.py
index b4cdc52..3927afd 100644
--- a/src/glicid_spawner/resources.py
+++ b/src/glicid_spawner/resources.py
@@ -37,3 +37,15 @@ def gpu_max_duration(gpus: list, unknown_default=1) -> dict:
defaults = {gpu: duration for gpu, duration in GPU_DEFAULTS.items() if gpu in gpus}
unknowns = {gpu: unknown_default for gpu in gpus if gpu not in GPU_DEFAULTS}
return defaults | unknowns
+
+
+def get_folders(username: str) -> list:
+ """List of folders accessible to the users as a working directory."""
+ return [
+ f'/home/{username}',
+ f'/scratch/nautilus/users/{username}',
+ f'/scratch/waves/users/{username}',
+ '/scratch/nautilus/projects',
+ '/scratch/waves/projects',
+ '/LAB-DATA/',
+ ]
diff --git a/src/glicid_spawner/templates/spawner_form.jinja b/src/glicid_spawner/templates/spawner_form.jinja
index d6263f2..366d080 100644
--- a/src/glicid_spawner/templates/spawner_form.jinja
+++ b/src/glicid_spawner/templates/spawner_form.jinja
@@ -5,6 +5,7 @@
{% include "views/username.jinja" %}
+ {% include "views/chdir.jinja" %}
{% include "views/envs.jinja" %}
{% include "views/resources.jinja" %}
{% include "views/slurm.jinja" %}
diff --git a/src/glicid_spawner/templates/views/chdir.jinja b/src/glicid_spawner/templates/views/chdir.jinja
new file mode 100644
index 0000000..8d33074
--- /dev/null
+++ b/src/glicid_spawner/templates/views/chdir.jinja
@@ -0,0 +1,13 @@
+
diff --git a/src/glicid_spawner/templates/views/envs.jinja b/src/glicid_spawner/templates/views/envs.jinja
index 954db74..831d8ea 100644
--- a/src/glicid_spawner/templates/views/envs.jinja
+++ b/src/glicid_spawner/templates/views/envs.jinja
@@ -1,10 +1,13 @@
diff --git a/tests/test_form.py b/tests/test_form.py
index 2a706a1..d04fafd 100644
--- a/tests/test_form.py
+++ b/tests/test_form.py
@@ -48,6 +48,15 @@ def test_options_attrs(mock_cluster):
assert options['username'] == 'john-doe'
+ assert options['folders'] == [
+ '/home/john-doe',
+ '/scratch/nautilus/users/john-doe',
+ '/scratch/waves/users/john-doe',
+ '/scratch/nautilus/projects',
+ '/scratch/waves/projects',
+ '/LAB-DATA/',
+ ]
+
assert [env.path for env in options['envs']] == [
'/john-doe/envs/foo',
'/john-doe/envs/bar',
@@ -243,6 +252,7 @@ def test_options_from_form():
"""Test options from form parser."""
# No GPU
formdata = {
+ 'workdir': ['/home/john-doe/'],
'python-env': ['/john-doe/envs/foo'],
'cpu': ['1'],
'mem': ['4'],
@@ -250,6 +260,7 @@ def test_options_from_form():
}
assert options_from_form(formdata) == {
+ 'workdir': '/home/john-doe/',
'pyenv': '/john-doe/envs/foo',
'nprocs': 1,
'memory': '4GB',
@@ -258,6 +269,7 @@ def test_options_from_form():
# With GPU (in defaults list)
formdata = {
+ 'workdir': ['/scratch/nautilus/users/john-doe/'],
'python-env': ['/john-doe/envs/bar'],
'cpu': ['2'],
'mem': ['16'],
@@ -266,6 +278,7 @@ def test_options_from_form():
}
assert options_from_form(formdata) == {
+ 'workdir': '/scratch/nautilus/users/john-doe/',
'pyenv': '/john-doe/envs/bar',
'nprocs': 2,
'memory': '16GB',
@@ -276,6 +289,7 @@ def test_options_from_form():
# With unknown GPU (default 1h allocation)
formdata = {
+ 'workdir': ['/scratch/waves/projects/'],
'python-env': ['/global/envs/baz'],
'cpu': ['8'],
'mem': ['16'],
@@ -284,6 +298,7 @@ def test_options_from_form():
}
assert options_from_form(formdata) == {
+ 'workdir': '/scratch/waves/projects/',
'pyenv': '/global/envs/baz',
'nprocs': 8,
'memory': '16GB',
@@ -294,6 +309,7 @@ def test_options_from_form():
# Invalid CPU request (0h allocated)
formdata = {
+ 'workdir': ['/LAD-DATA/'],
'python-env': ['/global/envs/qux'],
'cpu': ['128'],
'mem': ['4096'],
@@ -302,6 +318,7 @@ def test_options_from_form():
}
assert options_from_form(formdata) == {
+ 'workdir': '/LAD-DATA/',
'pyenv': '/global/envs/qux',
'nprocs': 128,
'memory': '4096GB',
diff --git a/tests/test_resources.py b/tests/test_resources.py
index 482ba1c..f910d2f 100644
--- a/tests/test_resources.py
+++ b/tests/test_resources.py
@@ -1,6 +1,6 @@
"""Test resources module."""
-from glicid_spawner.resources import CPU, GPU_DEFAULTS, MEMORY, gpu_max_duration
+from glicid_spawner.resources import CPU, GPU_DEFAULTS, MEMORY, get_folders, gpu_max_duration
def test_default_resources():
@@ -22,3 +22,15 @@ def test_gpu_max_duration():
# Sorted by defaults order, then unknowns
assert list(gpu) == ['None', 'A100', 'T4', 'K80']
assert list(gpu.values()) == [24, 1, 3, 3]
+
+
+def test_resources_workdir():
+ """Test resources working directories."""
+ assert get_folders('john-doe') == [
+ '/home/john-doe',
+ '/scratch/nautilus/users/john-doe',
+ '/scratch/waves/users/john-doe',
+ '/scratch/nautilus/projects',
+ '/scratch/waves/projects',
+ '/LAB-DATA/',
+ ]