Skip to content

Commit dbd4789

Browse files
EBR-54: add missing fields from remote run configuration, add monitoring button for unicore
1 parent 56dd18d commit dbd4789

File tree

6 files changed

+131
-14
lines changed

6 files changed

+131
-14
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"schemaDir": "schema"
129129
},
130130
"eslintIgnore": [
131+
"src",
131132
"node_modules",
132133
"dist",
133134
"coverage",

src/XircuitsFactory.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
runIcon,
2121
saveIcon,
2222
undoIcon,
23-
type LabIcon
23+
type LabIcon,
2424
} from "@jupyterlab/ui-components";
2525
import { ToolbarButton } from '@jupyterlab/apputils';
2626
import { LoggerCommandIDs } from './log/LogPlugin';
@@ -147,6 +147,7 @@ export class XircuitsFactory extends ABCWidgetFactory<DocumentWidget> {
147147
widget.toolbar.insertItem(11, 'xircuits-add-compile', compileButton);
148148
widget.toolbar.insertItem(12, 'xircuits-add-run', compileAndRunButton);
149149
widget.toolbar.insertItem(13, 'xircuits-run-type', new RunSwitcher(this));
150+
widget.toolbar.insertItem(14, 'xircuits-add-monitor', monitoringButton);
150151

151152
return widget;
152153
}

src/components/XircuitsBodyWidget.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -838,8 +838,8 @@ export const BodyWidget: FC<BodyWidgetProps> = ({
838838
let remoteRunType = dialogResult["value"]['remoteRunType'] ?? "";
839839
let runConfig = dialogResult["value"]['remoteRunConfig'] ?? "";
840840
let runProject = dialogResult["value"]['project'] ?? "";
841-
let runStageOut = dialogResult["value"]['stage-out'] ?? "";
842-
let runMonitoring = dialogResult["value"]['monitoring'] ?? "";
841+
let runStageOut = dialogResult["value"]['stage_out'] ?? false;
842+
let runMonitoring = dialogResult["value"]['monitoring'] ?? false;
843843
let runFilesystem = dialogResult["value"]['filesystem'] ?? "";
844844
let runPython = dialogResult["value"]['python'] ?? "";
845845
let runModules = dialogResult["value"]['modules'] ?? "";
@@ -854,7 +854,7 @@ export const BodyWidget: FC<BodyWidgetProps> = ({
854854
cfg['python'] = runPython.length > 0 ? runPython : 'NONE';
855855
cfg['modules'] = runModules.length > 0 ? runModules : 'NONE';
856856
cfg['libraries'] = runLibraries.length > 0 ? runLibraries : 'NONE';
857-
setLastConfigs(config);
857+
setLastConfigs(cfg);
858858
}
859859
})
860860
}

src/components/runner/RemoteRun.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ export function buildRemoteRunCommand(path: string, config: { formattedCommand:
1111
'$XIRCUITS_PATH': path
1212
};
1313

14-
let command_str = command;
14+
let command_str = command + " " + path + " " + config['run_config_name']
15+
+ " " + config['project']
16+
+ " " + config['stage_out']
17+
+ " " + config['filesystem']
18+
+ " " + config['python']
19+
+ " " + config['modules']
20+
+ " " + config['libraries'];
1521
Object.keys(envVariables).forEach(key => {
1622
command_str = command_str.replace(new RegExp(`\\${key}`, 'g'), envVariables[key]);
1723
});

src/dialog/RemoteRunDialog.tsx

+114-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import {
66
NumberInput,
77
TextAreaInput
88
} from './RunDialogComponents';
9+
import { useCollapse } from "react-collapsed";
910

1011
interface RemoteRunDialogProps {
1112
remoteRunTypes;
12-
remoteRunConfigs: { id: string; run_type: string; run_config_name: string; command: string }[];
13-
lastConfig: { run_type: string; run_config_name: string; command: string } | null;
13+
remoteRunConfigs: { id: string; run_type: string; run_config_name: string; command: string; project: string}[];
14+
lastConfig: { run_type: string; run_config_name: string; command: string; project: string } | null;
1415
childStringNodes: string[];
1516
childBoolNodes: string[];
1617
childIntNodes: string[];
@@ -31,6 +32,12 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
3132
const [remoteRunType, setRemoteRunType] = useState("");
3233
const [remoteRunConfig, setRemoteRunConfig] = useState("");
3334
const [command, setCommand] = useState("");
35+
const [project, setProject] = useState("");
36+
const [isMonitoringEnabled, setIsMonitoringEnabled] = useState(false);
37+
const [isStageOutEnabled, setIsStageOutEnabled] = useState(false);
38+
const [filesystem, setFilesystem] = useState('HOME');
39+
const [python, setPython] = useState('python3.10');
40+
const [modules, setModules] = useState('Python');
3441
const [placeholders, setPlaceholders] = useState<string[]>([]);
3542
const [formattedCommand, setFormattedCommand] = useState("");
3643
const [sectionsCollapsed, setSectionsCollapsed] = useState({
@@ -51,6 +58,9 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
5158
setRemoteRunType(lastConfig.run_type);
5259
setRemoteRunConfig(lastConfig.run_config_name);
5360
setCommand(lastConfig.command);
61+
setProject(lastConfig.project);
62+
setIsMonitoringEnabled(false);
63+
setIsStageOutEnabled(false);
5464
const extractedPlaceholders = extractPlaceholders(lastConfig.command);
5565
setPlaceholders(extractedPlaceholders);
5666
setInputValues(prefillInputValues(lastConfig, extractedPlaceholders));
@@ -70,6 +80,9 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
7080
setRemoteRunType(type);
7181
setRemoteRunConfig("-");
7282
setCommand("");
83+
setProject("");
84+
setIsMonitoringEnabled(false);
85+
setIsStageOutEnabled(false);
7386
setPlaceholders([]);
7487
setInputValues({});
7588
};
@@ -79,6 +92,9 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
7992
setRemoteRunConfig(configName);
8093
if (configName === "-") {
8194
setCommand("");
95+
setProject("");
96+
setIsMonitoringEnabled(false);
97+
setIsStageOutEnabled(false);
8298
setPlaceholders([]);
8399
setInputValues({});
84100
} else {
@@ -89,6 +105,14 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
89105
setPlaceholders(extractedPlaceholders);
90106
setInputValues(prefillInputValues(selectedConfig, extractedPlaceholders));
91107
}
108+
if (configName === 'JUWELS') {
109+
setFilesystem('HOME');
110+
setPython('python3.11');
111+
} else {
112+
setFilesystem('PROJECT');
113+
setPython('python3.10');
114+
}
115+
setModules('Python');
92116
}
93117
};
94118

@@ -167,11 +191,61 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
167191
const hasArguments = childStringNodes.length > 0 || childBoolNodes.length > 0 ||
168192
childIntNodes.length > 0 || childFloatNodes.length > 0;
169193

194+
function Collapsible() {
195+
const { getCollapseProps, getToggleProps, isExpanded } = useCollapse();
196+
return (
197+
<div className="collapsible">
198+
<div className="header" {...getToggleProps()}>
199+
{isExpanded ? 'Advanced setup' : 'Advanced setup'}
200+
<div className="icon">
201+
<i className={'fas fa-chevron-circle-' + (isExpanded ? 'up' : 'down')}></i>
202+
</div>
203+
</div>
204+
<div {...getCollapseProps()}>
205+
<div>
206+
Filesystem:
207+
<div>
208+
<input
209+
name='filesystem'
210+
defaultValue={filesystem}
211+
title={'Filesystem to use on HPC for preparing the environment'}
212+
style={{ width: 300, fontSize: 13 }}/>
213+
</div>
214+
Python dir:
215+
<div>
216+
<input
217+
name='python'
218+
defaultValue={python}
219+
title={'Python directory to use on HPC'}
220+
style={{ width: 300, fontSize: 13 }}/>
221+
</div>
222+
Modules to load:
223+
<div>
224+
<input
225+
name='modules'
226+
defaultValue={modules}
227+
title={'Modules to load on HPC'}
228+
style={{ width: 300, fontSize: 13 }}/>
229+
</div>
230+
Libraries to install:
231+
<div>
232+
<input
233+
name='libraries'
234+
defaultValue={'tvb-ext-xircuits,tvb-data'}
235+
title={'Libraries to install on HPC'}
236+
style={{ width: 300, fontSize: 13 }}/>
237+
</div>
238+
</div>
239+
</div>
240+
</div>
241+
);
242+
}
243+
170244
return (
171245
<form>
172246
<h2>Remote Run</h2>
173247

174-
{renderCollapsibleSection("Available Run Type", (
248+
{renderCollapsibleSection('Available Run Type', (
175249
<div style={styles.select}>
176250
<HTMLSelect
177251
onChange={(e) => handleTypeChange(e)}
@@ -187,9 +261,9 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
187261
))}
188262
</HTMLSelect>
189263
</div>
190-
), "runType")}
264+
), 'runType')}
191265

192-
{renderCollapsibleSection("Available Run Config", (
266+
{renderCollapsibleSection('Available Run Config', (
193267
<div style={styles.select}>
194268
<HTMLSelect
195269
onChange={(e) => handleConfigChange(e)}
@@ -210,6 +284,41 @@ export const RemoteRunDialog: React.FC<RemoteRunDialogProps> = ({
210284
</div>
211285
), "runConfig")}
212286

287+
{renderCollapsibleSection("Project", (
288+
<TextAreaInput
289+
name="project"
290+
title=""
291+
oldValue={project}
292+
onChange={() => {}}
293+
/>
294+
), "project")}
295+
296+
{renderCollapsibleSection("Launch Monitoring HPC", (
297+
<div>
298+
<input type={'checkbox'}
299+
title={'If checked, the HPC monitoring widget is opened up automatically in a new tab. This can be accessed from the Monitor HPC button as well.'}
300+
name='monitoring'
301+
checked={isMonitoringEnabled}
302+
onChange={(e) => setIsMonitoringEnabled(e.target.checked)}
303+
>
304+
</input>
305+
</div>
306+
), "launchHPC")}
307+
308+
{renderCollapsibleSection("Stage-out results", (
309+
<div>
310+
<input type={'checkbox'}
311+
title={'If checked, the workflow waits for all HPC jobs to finish and stages-out the results. Otherwise, they can be downloaded manually from the HPC monitoring widget.'}
312+
name='stage_out'
313+
checked={isStageOutEnabled}
314+
onChange={(e) => setIsStageOutEnabled(e.target.checked)}
315+
>
316+
</input>
317+
</div>
318+
), "launchHPC")}
319+
320+
<Collapsible/>
321+
213322
{renderCollapsibleSection("Command Template", (
214323
<TextAreaInput
215324
name="commandTemplate"

tvbextxircuits/hpc_config/pyunicore_config.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from urllib.error import HTTPError
1414
import pyunicore.client as unicore_client
1515
import requests
16-
from pyunicore.helpers.jobs import Status as unicore_status
17-
from pyunicore.credentials import AuthenticationFailedException
16+
from pyunicore.client import JobStatus as unicore_status
17+
from pyunicore.credentials import AuthenticationFailedException, OIDCToken
1818
from tvb_ext_bucket.ebrains_drive_wrapper import BucketWrapper
1919
from tvb_ext_bucket.exceptions import CollabAccessError
2020
from tvbwidgets.core.auth import get_current_token
@@ -74,7 +74,7 @@ def _install_dependencies_command(self):
7474

7575
def connect_client(self):
7676
LOGGER.info(f"Connecting to {self.site}...")
77-
token = get_current_token()
77+
token = OIDCToken(get_current_token())
7878
transport = unicore_client.Transport(token)
7979
registry = unicore_client.Registry(transport, unicore_client._HBP_REGISTRY_URL)
8080

@@ -363,7 +363,7 @@ def launch_job(site, project, workflow_file_name, workflow_file_path, files_to_u
363363
python_arg = sys.argv[6] if sys.argv[6] != 'NONE' else None
364364
modules_arg = sys.argv[7] if sys.argv[7] != 'NONE' else None
365365
libraries_arg = sys.argv[8] if sys.argv[8] != 'NONE' else None
366-
do_stage_out = True if stage_out_arg == 'true' else False
366+
do_stage_out = True if stage_out_arg == 'on' else False
367367
launch_job(site=site_arg, project=project_arg, workflow_file_name=workflow_name,
368368
workflow_file_path=workflow_path, files_to_upload=files_to_upload, do_stage_out=do_stage_out,
369369
filesystem=filesystem_arg, python=python_arg, libraries=libraries_arg, modules=modules_arg)

0 commit comments

Comments
 (0)