任务模板
任务模板是FCP平台提供的一种标准化作业配置方案。它将复杂的命令行参数、运行环境变量、计算资源规格等关键配置参数,封装为可重复使用的标准化模板,并通过直观的可视化操作界面呈现给用户。这一功能显著降低了高性能计算任务的使用门槛和学习成本,使研发人员能够快速上手、高效提交任务。
权限说明
相关说明,请查看权限说明文档
字段说明
在创建或编辑任务模板时,您需要配置以下信息:
- 名称:模板的唯一标识名称,便于识别和管理。
- 图标:(可选)为模板设置视觉标识。其图标支持PNG、JPG、SVG、webp等类型的文件,大小不超过5M,建议使用 72px × 72px 的正方形图标,以获得最佳显示效果。
- 视频:(可选)关联操作演示。
- 手册:(可选)关联详细使用文档。
- 标签:(可选)为模板添加一个或多个分类标 签,便于后续筛选。标签在任务新建时被用于关联和筛选模板。
- 描述:(可选)详细说明模板的用途、适用场景与注意事项。
- 定义:配置模板的核心执行逻辑,包括命令、脚本、输入输出定义等。详细语法请参阅 任务模板语法 章节。
使用步骤
1. 创建任务模板
前提条件:
- 拥有创建任务模板的系统权限。
- 拥有计划关联的目标集群的使用权限(如果您打算在模板中关联集群)。
操作流程:
2. 管理与使用模板
- 模板列表:所有模板集中展示,信息包括图标、名称、标签和描述,方便浏览查找。
- 搜索与筛选:
- 关键词搜索:在列表顶部的搜索框中输入模板名称或标签名称中的关键词,可实时筛选相关模板。
- 标签筛选:点击已有的标签,可快速筛选出所有关联了该标签的模板。
- 模板操作:
- 详情:点击模板名称可进入详情页,查看完整配置。
- 编辑:修改模板的各项配置信息。
- 删除:从系统中移除该模板。
- 访问控制:管理员可为模板设置细粒度权限,将读取(查看/使用)或更新(修改)权限授予指定的用户或用户组。
关联集群
通过配置模板与集群的关联关系,可以限定用户通过该模板提交任务时可选择的资源范围。
- 默认状态:新创建的模板默认不关联任何集群。
- 如何配置关联:
- 在模板的编辑或详情页面,进入“关联集群”配置项。
- 未关联集群列表:展示所有可关联的、状态正常(系统自动过滤“释放中”、“已释放”、“错误”状态)的集群。支持通过集群状态和集群名称进行搜索。
- 已关联集群列表:展示已与此模板关联的、状态正常的集群。
- 您可以从“未关联列表”中选择集群添加至“已关联列表”,或进行移除操作。
- 对用户任务提交的影响:
- 模板未关联集群:用户使用此模板新建任务并选择“现有集群”时,可看到其个人拥有权限的所有集群。
- 模板已关联集群:用户使用此模板新建任务并选择“现有集群”时,仅能看见模板“已关联集群列表”中状态为“运行中”或“更新中”的集群。若用户对这些集群均无访问权限,则列表为空。
标签管理
标签用于对任务模板进行分类,是实现快速筛选和组织模板的重要工具。
- 核心功能:
- 创建/编辑标签:定义标签的名称、图标和描述。图标规范与模板图标类似。
- 标签列表:集中管理所有标签,并展示每个标签所关联的模板数量。
- 查询与删除:支持搜索标签,并可执行单个或批量删除操作。
- 使用流程:主要在任务新建时发挥作用。用户在提交任务选择模板的环节,可以通过筛选标签来快速定位所需类型的模板。
任务模板语法
注:此语法仅限“直接面向调度器的任务模式”下使用
parameters: # 参数列表, 可能有多个
- name: param1 # 取值范围: [a-zA-Z0-9_]
display: 显示名称 # 界面显示用的名称
description: 描述 # 用于生成帮助文档
type: 类型 # INT | FLOAT | PATH | ENUM | STRING | BOOL | PATH_ARRAY | STRING_ARRAY | ENUM_SCRIPT 注:不区分大小写,但是要有下划线_
required: bool # 该参数是否为必填参数, 默认是false
usage: 用途 # SCRIPT | SCHEDULER, 默认为SCRIPT
schedPrefix: 前缀 # 如果是SCHEDULER类型, 则会在前缀后面加上参数值
value: string # 表示默认值,例:'0', '0.3', 'true', 'abc', '/abc/def', 对于PATH_ARRAY和STRING_ARRAY类型,使用','号分割即可,例:'/abc/def,/ghi/jkl',注意:对于PATH、PATH_ARRAY表示路径时,始终为相对路径,并且不要以"/"结尾
option:
# 通过浏览器原生支持的fetch函数提供远程调用的能力,fetch的使用说明见:https://developer.mozilla.org/zh-CN/docs/Web/API/fetch
# type为ENUM_SCRIPT时可用
# 注意此处必须返回一个Promise<Response>,fetch的返回值即为Promise<Response>,故return 此fetch即可
# 此处只需写一组javascript表达式即可,函数中以下为一个示例:
enumScript: |-
// 此处返回即为'Promise<Response>'中的Promise
return fetch('http://101.126.29.51/api/v1/hostNodes', {
method: 'GET', // 'GET' | 'POST'
headers: {
'Authorization': 'Bearer xxxxxxx'
}
})
.then(res => res.json())
.then(res => {
// 此处返回即为'Promise<Response>'中的Response部分
// 在此处可以自定义逻辑,Response需为:{value: string, label: {title: string}[]的格式;
return res.content.map(item => ({value: item.hostname, label: {title: item.hostname}}))
})
enum: # 当type为ENUM时, 用于定义可选值
- value: 值 # 实际值
display: 描述 # 展示用
path: # 当type为PATH或PATH_ARRAY时, 用于定义文件类型
pattern: 过滤 # 文件名过滤, 缺省时不过滤
directory: bool # true | false, 是否为目录
float:
min: 最小值 # 不存在时不限制
max: 最大值 # 不存在时不限制
int:
min: 最小值 # 不存在时不限制
max: 最大值 # 不存在时不限制
string:
pattern: regex # 过滤用正则表达
# 以下一段是【restrict.resourceCheck】的说明
# 这里用于判断集群分区闲置资源情况,会提供两个变量:
# 1.选中分区的闲置资源情况【partition】
# {
# clusterId?: number; //集群id
# name?: string; //集群名称
# partitionId?: number; //分区id
# partitionName?: string; //分区名称
# idleCpu?: number; // 空闲cpu
# allocCpu?: number; // 已分配cpu
# totalCpu?: number; // cpu总量
# idleMemory?: number; // 空闲内存
# allocMemory?: number; // 已分配内存
# totalMemory?: number; // 总内存
# runningComputeCount?: number; // 运行中计算节点数量
# idleComputeCount?: number; // 空闲的计算节点数量
#}
#
# 2.输入参数中输入的数值(用于动态比较)【data】
# 此数据就是parameters定义的字段实际输入的值,示例如下:
# [
# {
# "name": "count","value": {"float": 3 },
# "def": {
# "name": "count",
# "display": "循环次数",
# "description": "循环次 数",
# "type": "FLOAT",
# "required": true,
# "option": {
# "float": {
# "min": "1",
# "max": "3"
# }
# }
# }
# },
# {"name": "filepath","value": {"path": "/job-1.cwl" },"def": ... // 定义parameter的内容,省略},
# {"name": "filepath_array","value": {"paths": ["/zy4523","/zy56"]},"def": ... // 定义parameter的内容,省略},
# {"name": "String","value": { "string": "asdas"},"def": ... // 定义parameter的内容,省略},
# {"name": "stringarray","value": {"strings": [ "adas"]},"def": ... // 定义parameter的内容,省略},
# {"name": "Bool","value": {"bool": true},"def": ... // 定义parameter的内容,省略},
# {"name": "int","value": {"int": 3},"def": ... // 定义parameter的内容,省略}
# ]
# 【注意】!!!!
# 使用者在自行取参数中输入的数值(用于动态比较)【data】和分区的闲置资源情况【partition】做比较时
# 若遇到单位不同的情况,请自行做计算将单位转化,
# 例如srun提交任务内存默认单位为MiB/MB,而实际集群分区给出idleMemory单位为GiB/GB
# 那么在计算时,可以做这样的修改:
# if(num2 > partition.idleMemory) 改成 if((num2 / 1000) > partition.idleMemory))
# num2是MiB/MB的单位,转成GiB/GB的单位,需要除以1024或100
# 同理还可以做其他类型的计算
#
# return 返回字符串即可,返回字符串则视为有警告提示,没有返回,或返回空,则视为没有警告提示
restrict:
resourceCheck: |-
let num1 = data.filter(item => item.name === 'count')[0].value.float;
let num2 = data.filter(item => item.name === 'int')[0].value.int;
if (partition.idleCpu < num1) {
return '提交任务所需的CPU数量不足,任务创建成功后会处于排队中!';
}
if (partition.idleMemory < num2) {
return "提交任务所需的内存不足,任务创建成功后会处于排队中!";
}
return null
nameExpression: |- ## 用于设置动态任务名称
console.log(formData, key, value) // 不确定给到的数据值是什么的时候,可像这样,打印出来看看。根据实际的数据,调整此处代码, 实际使用不要写注释
setName(value);
## 更多使用示例见下方`nameExpression使用示例`
outputs: # 用于展示的输出
- path: xxx/xxx/output.file # 文件名过滤, 缺省时不过滤
type: 类型 # TEXT | IMAGE | VIDEO | AUDIO | FILE
script: |-
#!/bin/bash
# 脚本内容
echo {{ param1 }} # 引用参数param1
我们为您准备了一系列常用工程仿真软件的任务模板示例,您可以根据实际需要参考或直接使用:
nameExpression使用示例
例如使用以下
parameters:
- name: stringInput
display: string测试
description: string测试的description
type: sTrinG # 不区分大小写
required: true
- name: stringArrayInput
display: stringArray测试
description: stringArray测试的description
type: STRING_ARRAY
required: true
- name: pathInput
display: PATHInput测试
description: PATHInput测试的description
type: PATH
required: true
option:
path:
directory: false
- name: pathArrayInput
display: 运行任务需要内存
description: 输入内存数
type: PATH_ARRAY
required: true
option:
path:
directory: false
nameExpression:
console.log(formData, key, value); // 不确定给到的数据值是什么的时候,可像这样,打印出来看看。根据实际的数据,调整此处代码, 实际使用不要写注释
setName(value);
outputs:
- name: output
description: 输出
path: output
type: text
script: |-
#!/bin/bash
{{ stringput }}
在此种yaml配置下可以看到formData数据结构为
{
"jobName":"atxttxt",
"stringput":"aaaa",
"stringArrayInput":[
"bbbb",
"cccc"
],
"pathInput":[
{
"type":"FILE",
"size":166,
"name":"atxt.txt",
"path":"/atxt.txt",
"parent_path":"/",
"mime":"text/plain; charset=utf-8",
"last_modified_time":1739432273501,
"storage_id":-1
}
],
"pathArrayInput":[
{
"type":"FILE",
"size":166,
"name":"atxt.txt",
"path":"/atxt.txt",
"parent_path":"/",
"mime":"text/plain; charset=utf-8",
"last_modified_time":1739432273501,
"storage_id":-1
},
{
"type":"FILE",
"size":9,
"name":"a.txt",
"path":"/a.txt",
"parent_path":"/",
"mime":"text/plain; charset=utf-8",
"last_modified_time":1739347355456,
"storage_id":-1
}
]
}
在此种yaml配置分别看key、value的数据情况:
首先,参数key,value指的是,每一次inputs的id对应的表单控件的值发生改变(在此例中即:stringInput、stringArrayInput、pathInput、pathArrayInput)
- 当stringInput发生变化时:得到的
key即stringInput,value为一个字符串/aaaa - 当stringArrayInput发生变化时:得到的
key即stringArrayInput,value为一个数组['bbbb', 'cccc'] - 当pathInput发生变化时:得到的
key即pathInput,value为一个字符串/atxt.txt - 当pathArrayInput发生变化时:得到的
key即pathArrayInput,value为一个数组['/atxt.txt', '/a.txt']
注意:
- 从
formData中看到的数据,和使用formData[key]的方式取的值和不同控件类型(PATH,STRING,PATH_ARRAY,STRING_ARRAY)给出的value是不一样的,通过比对上面的打印可以看出 - 所以在实际使用时,需要注意数据结构,若写的代码与预期不一致时,请仔细检查,并调试代码