Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/build_and_deploy.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: build and deploy container
on:
pull_request_target:
branches:
- master
types:
- closed
jobs:
Expand Down
13 changes: 7 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
The directory structure of this project is organized as follows:

```
client/ client js codes
common/ JS code shared between client and server
documentMD/ markdown documents
server/ server js codes
server/tetst/ server unit test
test/ end-to-end test with cypress
client/ client js codes
common/ JS code shared between client and server
documentMD/ markdown documents
server/ server js codes
server/tetst/ server unit test
test/cypress/e2e end-to-end test with cypress
test/cypress/component component test with cypress
```

## npm scripts
Expand Down
45 changes: 38 additions & 7 deletions client/src/components/componentProperty.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@
variant="outlined"
data-cy="component_property-script-autocomplete"
/>
<v-autocomplete
v-if="isTask"
v-model="copySelectedComponent.checker"
label="checker script"
:readonly="readOnly"
:items="scriptCandidates"
clearable
variant="outlined"
data-cy="component_property-checker-autocomplete"
/>
<v-select
v-if="hasHost"
v-model="copySelectedComponent.host"
Expand All @@ -124,33 +134,39 @@
data-cy="component_property-job_scheduler-switch"
/>
<v-select
v-if="hasJobScheduler"
v-if="hasJobScheduler && copySelectedComponent.useJobScheduler"
v-model="copySelectedComponent.queue"
label="queue"
:readonly="readOnly"
:items="queues"
:disabled="! copySelectedComponent.useJobScheduler"
variant="outlined"
data-cy="component_property-queue-select"
/>
<v-text-field
v-if="hasJobScheduler"
v-if="hasJobScheduler && copySelectedComponent.useJobScheduler"
v-model="submitCmd"
:readonly="readOnly"
label="submit command"
:disabled="! copySelectedComponent.useJobScheduler"
variant="outlined"
data-cy="component_property-submit_command-text_field"
/>
<v-text-field
v-if="hasJobScheduler"
v-if="hasJobScheduler && copySelectedComponent.useJobScheduler"
v-model="copySelectedComponent.submitOption"
label="submit option"
:readonly="readOnly"
:disabled="! copySelectedComponent.useJobScheduler"
variant="outlined"
data-cy="component_property-submit_option-text_field"
/>
<v-text-field
v-if="hasScript && copySelectedComponent.useJobScheduler"
v-model="copySelectedComponent.sourceScript"
label="source script"
:readonly="readOnly"
clearable
variant="outlined"
data-cy="component_property-source_script-text_field"
/>
<v-text-field
v-if="isStorage"
v-model="copySelectedComponent.storagePath"
Expand Down Expand Up @@ -810,16 +826,31 @@ export default {
}
const JS = currentHostSetting.jobScheduler;
return JS ? this.jobScheduler[JS].submit : null;
},
remoteFileSettingPanelIndex() {
//Remote file setting panel only appears for task, bulkjobTask, and stepjobTask
//For these component types, it is always at index 3
if (this.isTask || this.isBulkjobTask || this.isStepjobTask) {
return 3;
}
return null;
}
},
watch: {
retryByJS() {
this.copySelectedComponent.retryCondition = null;
},
"copySelectedComponent.host"(newValue) {
"copySelectedComponent.host"(newValue, oldValue) {
if (newValue === "localhost" && !this.isBulkjobTask && !this.isStepjobTask && this.isStepjob) {
this.copySelectedComponent.useJobScheduler = false;
}
//Close remote file setting panel if changing to localhost
if (newValue === "localhost") {
//Remove remote file setting panel from openPanels
this.openPanels = this.openPanels.filter((idx)=>{
return idx !== this.remoteFileSettingPanelIndex;
});
}
},
open(newValue) {
//another component is selected while componentProperty is open
Expand Down
54 changes: 54 additions & 0 deletions documentMD/user_guide/_reference/4_component/01_Task.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,36 @@ Therefore, it cannot be changed here.
### submit option
Sets additional options to be specified when the job is submitted.

### source script
Specifies an environment configuration file to be loaded before executing the script on the remote host.
The specified script is loaded using the `source` command.

This is useful when you need to set specific environment variables or use module systems (such as Environment Modules).

Example:
```bash
# Contents of setup.sh
module load intel/2021
export MY_VAR=value
```

### checker script
Specifies a dedicated script to determine the success/failure of the Task component.
The checker script is executed after the Task component finishes, and its return value (0: success, non-zero: failure) determines the final status of the Task.

When a checker script is set, the return value of the script specified in the script property is ignored, and the checker script's return value is used instead.

Example:
```bash
#!/bin/bash
# Check if output file exists
if [ -f output.dat ]; then
exit 0
else
exit 1
fi
```

### number of retry
Specifies the number of times the Task component automatically reruns if it fails to run.
If none is specified, the command is not re-executed.
Expand All @@ -79,6 +109,30 @@ The expression you enter here is evaluated after the Task component has finished

If both the script name and the javascript expression are not set and you set only the number of retry values, repeat the retry until the script terminates normally or reaches the number of retry settings.

__Available Environment Variables__
The following environment variables are available in the script or javascript expression used to determine whether to retry:
- For shell scripts: `WHEEL_TASK_RT`
- For javascript expressions: `wheelTaskRT`

These variables contain the return value of the script specified in the script property.
However, if the checker property is set, the return value of the checker script takes precedence.

Example: Retry only if the return value is 10 (shell script)
```bash
#!/bin/bash
if [ "$WHEEL_TASK_RT" = "10" ]; then
exit 0
else
exit 1
fi
```

Example: Retry only if the return value is less than 5 (javascript expression)
```javascript
wheelTaskRT < 5
```
{: .notice--info}

### include, exclude

![img](./img/include_exclude.png "include, exclude")
Expand Down
54 changes: 54 additions & 0 deletions documentMD/user_guide/_reference/4_component/01_Task.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,36 @@ use job schedulerを有効にしたときのみ、次のqueue, submit optionプ
### submit option
ジョブ投入時に追加で指定するオプションを設定します。

### source script
リモートホストでスクリプトを実行する前に読み込む環境設定ファイルを指定します。
ここで指定したスクリプトは`source`コマンドで読み込まれます。

例えば、特定の環境変数を設定したり、モジュールシステム(Environment Modules等)を使用する場合に利用します。

例:
```bash
# setup.sh の内容
module load intel/2021
export MY_VAR=value
```

### checker script
Taskコンポーネントの成功/失敗を判定するための専用スクリプトを指定します。
checkerスクリプトはTaskコンポーネント実行終了後に実行され、その戻り値(0:成功、0以外:失敗)でTaskの最終的な成否が決定されます。

checkerスクリプトが設定されている場合、scriptプロパティで指定したスクリプトの戻り値は無視され、checkerスクリプトの戻り値が使用されます。

例:
```bash
#!/bin/bash
# 出力ファイルの存在確認
if [ -f output.dat ]; then
exit 0
else
exit 1
fi
```

### number of retry
Taskコンポーネントの実行に失敗したときに、自動的に再実行する回数を指定します。
無指定時は再実行しません。
Expand All @@ -79,6 +109,30 @@ Taskコンポーネントの成功 / 失敗を判定するのにjavascript式を

スクリプト名、javascript式ともに未設定で、number of retryの値のみを設定していた場合は、スクリプトが正常終了するか、retryに設定した回数に達するまで再実行を繰り返します。

__利用可能な環境変数について__
再実行の判定を行うスクリプトやjavascript式では、以下の環境変数を利用できます。
- シェルスクリプトの場合: `WHEEL_TASK_RT`
- javascript式の場合: `wheelTaskRT`

これらの変数には、scriptプロパティで指定されたスクリプトの戻り値が設定されます。
ただし、checkerプロパティが設定されている場合は、checkerスクリプトの戻り値が優先して使用されます。

例: シェルスクリプトで戻り値が10の場合のみ再実行する
```bash
#!/bin/bash
if [ "$WHEEL_TASK_RT" = "10" ]; then
exit 0
else
exit 1
fi
```

例: javascript式で戻り値が5未満の場合のみ再実行する
```javascript
wheelTaskRT < 5
```
{: .notice--info}

### include, exclude

![img](./img/include_exclude.png "include, exclude")
Expand Down
9 changes: 9 additions & 0 deletions server/app/core/dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { exec } from "./executer.js";
import { getDateString, writeJsonWrapper } from "../lib/utility.js";
import { sanitizePath, convertPathSep, replacePathsep } from "./pathUtils.js";
import { readJsonGreedy } from "./fileUtils.js";
import { addX } from "./fileUtils.js";
import { deliverFile, deliverFilesOnRemote, deliverFilesFromRemote, deliverFilesFromHPCISS } from "./deliverFile.js";
import { paramVecGenerator, getParamSize, getFilenames, getParamSpacev2 } from "./parameterParser.js";
import { isLocal } from "../../../common/checkComponent.js";
Expand Down Expand Up @@ -524,6 +525,14 @@ class Dispatcher extends EventEmitter {
this.setEnv(component);
component.parentType = this.cwfJson.type;

//Add execute permission to script and checker
const scriptPath = path.resolve(component.workingDir, component.script);
await addX(scriptPath);
if (component.checker) {
const checkerPath = path.resolve(component.workingDir, component.checker);
await addX(checkerPath);
}

exec(component).catch((e)=>{
logWarn(this.projectRootDir, `${this.cwfDir}/${component.name}`, "failed. rt=", component.rt);
logTrace(this.projectRootDir, component.workingDir, "failed due to", e);
Expand Down
Loading