技术架构、接口和运行原理
架构
注解
- 流水线平台依赖着pass平台底层支撑,导出到其他runtime环境将无法正常工作。
- 外部应用部署和helm应用部署比较特殊,其job作业是在devops池中完成,所以在进行外部应用部署和helm应用部署时请保证开发池的充裕。
对外暴露的OpenAPI接口
获取Cookie
可通过token获取对应的Cookie
①获取token(此处token永久生效)
先用相应的租户管理员账号登录平台,并通过get访问以下地址,即可获取token
https://域名/entry/uaa/userinfo?type=token
{
"userId": null,
"username": null,
"name": null,
"phoneNumber": null,
"email": null,
"previousLogonTime": null,
"sub": null,
"token": "duanyl@brAvKvgFIXfY8B2Q3Pfgzey5IGiIS2Rm5wtYEGSTiOQ%3D", // 该用户token永久无限期
"given_name": null,
"phone_number": null,
"user_name": null,
"user_id": null,
"previous_logon_time": null
}
②获取Cookie
- 可以通过postman获取Cookie
后续接口的调用都需要在请求头中带上Cookie
请求头:
参数名 | 必填 | 说明 |
---|---|---|
Cookie | 是 | 调用用户的Cookie,可通过Token进行获取 |
示例:
{
"Cookie":"user_session=eyJ1c2VybmFtZSI6ImR1YW55bCIsImhtYWMiOiJcclx1MDAxZdo%2BXbT03q075Fx1MDAxZVx1MDAxY1xitpmi7mfIIiwidXNlcmlkIjoiZTIzRTBVT3NrSHFLcVM3VHloUCIsInRva2VuIjoiMTIxMjI5OGMtY2Q4Yi00YjY3LTkwYWItN2Y4NjhhMjQ3MmIxIiwiZXhwaXJlc19pbiI6MzQyMDYzMTUxMSwiZXhwaXJlIjoxNzEwMzM3MzU2fQ%3D%3D; PHPSESSID=00d1e45865d4c3203e9a91ebff49e64d; api=32afed59ffe88ff2538cccc3bf55ab64; default=32afed59ffe88ff2538cccc3bf55ab64"
}
- 也可以通过 curl 获取cookie
curl -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'token=chensc1@Od00uDg7%2B%2F3yGNk9hXmdYLuZEZevWiJPrdl8eTXtrOc%3D' https://www.trunk.xcaas.com/entry/login -i
- cookie如何使用,以下以查询流水线为例
curl -X GET -H "Content-Type: application/json" -H 'Cookie: user_session=eyJ1c2VybmFtZSI6ImNoZW5zYzEiLCJleHBpcmVzX2luIjozNDIxNTAwNTUyLCJ1c2VyaWQiOiJpUWtuOFpGdjAwVmp0Q2VYMWtFIiwidG9rZW4iOiJkMGZiNzY4OC0yN2IyLTRjYTMtOTYyYi05NTg3ZDUxN2E0OTEiLCJleHBpcmUiOjE3MTA3NzE4NzYsImhtYWMiOiKpXHLwlFq4b10neE5iXW1cZmRcdTAwN2b7rlx1MDAwMSJ9; PHPSESSID=33ad6e658cc403f409d0f8c7fbc20826; api=3fac1a1c35acd15db30ea8c4ea7e817a; default=3fac1a1c35acd15db30ea8c4ea7e817a' \ https://www.trunk.xcaas.com/devops/main/api/getpipeline?code=message
上传文件至minio
可通过接口将文件上传至minio存储中
请求地址: 控制台域名/devops/storage/postObject
请求方式: POST
请求参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
userfile | byte[] | 是 | 文件二进制流 |
storeFileName | String | 是 | 存储文件名 |
示例:
// request body(multipart/form-data)
{
"userfile": "(binary)",
"storeFileName": "C9FA9B1E22700001A6148AC0728B1FD5.jpeg"
}
新建流水线并执行
请求地址: 控制台域名/devops/main/api/createpipelineandrun
请求方式: POST
请求body参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 流水线编码 |
name | String | 是 | 流水线名称 |
templateCode | String | 是 | 流水线模板编码 |
conf | JSONObject | 是 | 流水线配置 |
注:
1. conf字段在版本中可能会灵活多变,建议开发者可以到到流水线管理页上进行抓包获取参考,如下:
2. templateCode字段可在流水线模版中获取
3. 整个body示例,(以下字段并不代表最终版,conf字段细节请参考上方抓包方式):
{
"code":"", //流水线编码
"name":"", //流水线名称
"templateCode":"", //流水线模板
"conf": {
"pipeOrigin": { //流水线来源设置
"fid": "CA99F27CF6900001EE2AE4F418301ADD", //id,必填
"codeOrigin": "upload", //需部署代码来源方式 upload:上传 ext_git:git拉取
"srcFileUrl": "[{ \"storeFileName\":\"/2024/1/23/anoy_CA99F28420900001F2B0FEFB1CA11C29pythontest.py\",\"realFileName\":\"pythontest.py\",\"uploadTime\":1706015679253,\"size\":424}]", //上传代码minio地址,可选
"gitUrl": null, //git仓库地址,可选
"branch": null, //git分支名称,可选
"gitUser": null, //git账号,可选
"gitPassword": null, //git密码,可选
"gitToken": null, //git账号token,可选
"codeType": "Python", //代码类型,必填
"codeTypeCode": "Python", //代码类型编码,必填
"codeVersion": "3.7", //代码版本,必填
"projectName": "pythongettest", //发布项目名称,必填
"releasePath": null //发布工程所在目录 适用于多层级的项目,可选
},
"structInfo": { //构建编译设置
"fid": "CA99F2858050000176E91A9019711933", //id,必填
"toolName": "python-3.7", //编译构建工具名称,必填
"toolType": "Python", //编译构建工具类型,必填
"toolVersion": "3.7", //编译构建工具版本,必填
"buildCommand": "#!/bin/bash", //代码编译脚本,可选,如果为空则采用默认脚本
"startCommand": "#!/bin/bash\r\n\r\ncd $(dirname $(readlink -f \"$0\"))\r\n\r\nsource \"${JUSTEP_HOME}/conf/env.sh\"\r\n\r\npython3 pythongettest.py", //代码运行脚本,可选,如果为空则采用默认脚本
"settings": null //Maven settings配置文件,可选
},
"confTemplateCode": "流水线参数模板的code,如果配置了它将为基础,用户的配置将以打补丁的方式进行覆盖,可选"
}
}
上方conf内容中需要注意的点
- srcFileUrl字段需要先调用上传文件至minio接口。返回结果里即可得到
- confTemplateCode 是流水线参数模板的code,如果配置了它将为基础,用户的配置将以打补丁的方式进行覆盖,可选。功能如下图
- 参数模板里还可以有conf内容参考
返回结果
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 请求结果编码,200为成功,其他的为错误码 |
msg | String | 是 | 请求结果提示内容 |
data | JSONObject | 否 | 请求结果返回的数据,这里为流水线的信息 |
示例:
{
"code":"200",
"msg":"流水线创建并执行成功",
"data":"此字段为json字符串,详见下面说明"
}
Data:
{
"code": "pythonurl", //流水线编码
"orgName": "duanyl租户组织$/", //流水线所属组织
"lastRunDate": "2024-01-23T13:17:11.000Z", //最后一次运行时间
"conf": {
"pipeOrigin": { //流水线来源设置
"fid": "CA99F27CF6900001EE2AE4F418301ADD", //id,必填
"codeOrigin": "upload", //需部署代码来源方式 upload:上传 ext_git:git拉取
"srcFileUrl": "[{ \"storeFileName\":\"/2024/1/23/anoy_CA99F28420900001F2B0FEFB1CA11C29pythontest.py\",\"realFileName\":\"pythontest.py\",\"uploadTime\":1706015679253,\"size\":424}]", //上传代码minio地址,可选
"gitUrl": null, //git仓库地址,可选
"branch": null, //git分支名称,可选
"gitUser": null, //git账号,可选
"gitPassword": null, //git密码,可选
"gitToken": null, //git账号token,可选
"codeType": "Python", //代码类型,必填
"codeTypeCode": "Python", //代码类型编码,必填
"codeVersion": "3.7", //代码版本,必填
"projectName": "pythongettest", //发布项目名称,必填
"releasePath": null, //发布工程所在目录 适用于多层级的项目,可选
},
"structInfo": { //构建编译设置
"fid": "CA99F2858050000176E91A9019711933", //id,必填
"toolName": "python-3.7", //编译构建工具名称,必填
"toolType": "Python", //编译构建工具类型,必填
"toolVersion": "3.7", //编译构建工具版本,必填
"buildCommand": "#!/bin/bash", //代码编译脚本,可选,如果为空则采用默认脚本
"startCommand": "#!/bin/bash\r\n\r\ncd $(dirname $(readlink -f \"$0\"))\r\n\r\nsource \"${JUSTEP_HOME}/conf/env.sh\"\r\n\r\npython3 pythongettest.py", //代码运行脚本,可选,如果为空则采用默认脚本
"settings": null, //Maven settings配置文件,可选
}
},
"appCode": "plpythonurl", //流水线对应应用编码
"userName": null, //流水线创建人名称
"deployId": null, //流水线部署任务id
"orgId": "3251bde0-85d7-4e3a-bf98-86006f749d21", //流水线所属组织id
"template_code": "ea_pipe", //流水线模板编码
"jobId": "bd383b78-7547-4ca0-9374-0f70d7304c7f", //流水线总体任务调度id
"prodAppId": "408a4a45-6339-4c0f-b6c4-443e73615148", //流水线部署应用id
"createdDate": "2024-01-23T13:13:33.000Z", //流水线创建时间
"processId": "CA99F27429300001C71BB8C0D38D1E4D", //流水线流程实例id
"createdBy": "duanyl", //流水线创建人
"domainPrefix": "plpythonurlduanyl6", //流水线对应应用标识
"appId": "8525dd25-4b8f-4b40-a61f-0f11ce8db894", //流水线对应
"tempate_name": "外部应用部署模板", //流水线模板名称
"name": "python请求测试", //流水线名称
"template_id": "5EA5234E6B3C4037A68147A5FFFAF5EA", //流水线模板id
"id": "CA99F27429300001C71BB8C0D38D1E4D", //流水线id
"createdById": "e23E0UOskHqKqS7TyhP", //流水线创建人id
"status": "发布完成" //流水线状态
}
修改流水线
与新增接口类似,但去请求方式改为update,且参数中多传一个id参数
请求地址: 控制台域名/devops/main/api/updatepipeline
请求方式: POST
请求参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
id | String | Id与code至少要存在一个 | 流水线id |
code | String | Id与code至少要存在一个 | 流水线code |
name | String | 可为空 | 流水线名称 |
templateCode | String | 可为空 | 流水线模板编码 |
conf | JSONObject | 以补丁的形式更新,也就是包含的字段才更新 | 流水线配置 |
示例:
{
"code":"", //流水线编码
"name":"", //流水线名称
"templateCode":"", //流水线模板
"conf": {
"pipeOrigin": { //流水线来源设置
"fid": "CA99F27CF6900001EE2AE4F418301ADD", //id,必填
"codeOrigin": "upload", //需部署代码来源方式 upload:上传 ext_git:git拉取
"srcFileUrl": "[{ \"storeFileName\":\"/2024/1/23/anoy_CA99F28420900001F2B0FEFB1CA11C29pythontest.py\",\"realFileName\":\"pythontest.py\",\"uploadTime\":1706015679253,\"size\":424}]", //上传代码minio地址,可选
"gitUrl": null, //git仓库地址,可选
"branch": null, //git分支名称,可选
"gitUser": null, //git账号,可选
"gitPassword": null, //git密码,可选
"gitToken": null, //git账号token,可选
"codeType": "Python", //代码类型,必填
"codeTypeCode": "Python", //代码类型编码,必填
"codeVersion": "3.7", //代码版本,必填
"projectName": "pythongettest", //发布项目名称,必填
"releasePath": null, //发布工程所在目录 适用于多层级的项目,可选
},
"structInfo": { //构建编译设置
"fid": "CA99F2858050000176E91A9019711933", //id,必填
"toolName": "python-3.7", //编译构建工具名称,必填
"toolType": "Python", //编译构建工具类型,必填
"toolVersion": "3.7", //编译构建工具版本,必填
"buildCommand": "#!/bin/bash", //代码编译脚本,可选,如果为空则采用默认脚本
"startCommand": "#!/bin/bash\r\n\r\ncd $(dirname $(readlink -f \"$0\"))\r\n\r\nsource \"${JUSTEP_HOME}/conf/env.sh\"\r\n\r\npython3 pythongettest.py", //代码运行脚本,可选,如果为空则采用默认脚本
"settings": null, //Maven settings配置文件,可选
},
"confTemplateCode": "流水线配置模板的code,如果配置了它将为基础,用户的配置将以打补丁的方式进行覆盖,可选"
}
}
返回结果
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 请求结果编码,200为成功,其他的为错误码 |
msg | String | 是 | 请求结果提示内容 |
data | JSONObject | 否 | 请求结果返回的数据,这里为流水线的信息 |
示例:
{
"code":"200",
"msg":"流水线修改成功",
"data":null
}
删除流水线
请求地址: 控制台域名/devops/main/api/deletepipeline
请求方式: DELETE
内部逻辑:需要按顺序删除:已部署的应用、已创建的应用、流水线记录、任务调度任务
请求参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
id | String | Id与code至少要存在一个 | 流水线id |
code | String | Id与code至少要存在一个 | 流水线编码 |
示例:
{
"id":"CAA9E2E09C2000016D5F1BC010701D16", //流水线编码
}
返回结果
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 请求结果编码,200为成功,其他的为错误码 |
msg | String | 是 | 请求结果提示内容 |
data | String | 否 | 请求结果返回的数据,这里为流水线的信息 |
示例:
{
"code":"200",
"msg":"流水线创建并执行成功",
"data":null
}
查询流水线
请求地址: 控制台域名/devops/main/api/getpipeline
请求方式: GET
请求参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
id | String | Id与code至少要存在一个 | 流水线id |
code | String | Id与code至少要存在一个 | 流水线编码 |
示例:
{
"id":"CAA9E2E09C2000016D5F1BC010701D16", //流水线编码
}
返回结果
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 请求结果编码,200为成功,其他的为错误码 |
msg | String | 是 | 请求结果提示内容 |
data | JSONObject | 否 | 请求结果返回的数据,这里为流水线的信息 |
示例:
{
"code":"200",
"msg":"流水线创建并执行成功",
"data":"此字段为json字符串,详见下面说明"
}
Data:
{
"code": "pythonurl", //流水线编码
"orgName": "duanyl租户组织$/", //流水线所属组织
"lastRunDate": "2024-01-23T13:17:11.000Z", //最后一次运行时间
"conf": "{\"pipeOrigin\":{\"fid\":\"CA99F27CF6900001EE2AE4F418301ADD\",\"srcFileUrl\":\"[{\\\"storeFileName\\\":\\\"/2024/1/23/anoy_CA99F28420900001F2B0FEFB1CA11C29pythontest.py\\\",\\\"realFileName\\\":\\\"pythontest.py\\\",\\\"uploadTime\\\":1706015679253,\\\"size\\\":424}]\",\"gitPassword\":null,\"codeType\":\"Python\",\"gitToken\":null,\"branch\":null,\"gitCode\":null,\"productName\":null,\"ia_domainPrefix\":null,\"codeOrigin\":\"upload\",\"codeTypeCode\":\"Python\",\"projectID\":null,\"targetDir\":null,\"codeVersion\":\"3.7\",\"gitUser\":null,\"productId\":null,\"gitName\":null,\"pathList\":null,\"pathFilter\":null,\"isStructure\":\"true\",\"gitRepoUrl\":null,\"srcDir\":null,\"releasePath\":null,\"projectName\":\"pythongettest\",\"gitUrl\":null},\"structInfo\":{\"fid\":\"CA99F2858050000176E91A9019711933\",\"toolVersion\":\"3.7\",\"isCache\":null,\"settings\":null,\"buildCommand\":\"#!/bin/bash\",\"repo\":null,\"isDep2repo\":null,\"startCommand\":\"#!/bin/bash\\r\\n\\r\\ncd $(dirname $(readlink -f \\\"$0\\\"))\\r\\n\\r\\nsource \\\"${JUSTEP_HOME}/conf/env.sh\\\"\\r\\n\\r\\npython3 pythongettest.py\",\"toolType\":\"Python\",\"toolName\":\"python-3.7\"},\"deploySettings\":{\"fid\":\"CA99F2866AE0000158BC1B608FF0117E\",\"useRoot\":\"true\",\"upstreamPath\":\"/\",\"skyWalking\":\"false\",\"stripRequestPath\":\"true\",\"nginxSettings\":null,\"requestPath\":\"/\"},\"releaseSetings\":{\"fid\":\"CA99F286D3B000018CB584281900162E\",\"small\":null,\"submitter\":\"duanyl\",\"registryHost\":null,\"domainprefix\":\"plpythonurlduanyl6\",\"ingressSettings\":null,\"helmmuseumName\":null,\"dockerImagePrefix\":null,\"paasNamespaceDeploymentType\":\"pool\",\"title\":\"plpythonurl\",\"marketType\":null,\"k8sNamespace\":null,\"mode\":null,\"k8sName\":null,\"kubeCa\":null,\"registryPasswd\":null,\"kubeToken\":null,\"registryUser\":null,\"registryName\":null,\"valuesYaml\":null,\"paasNamespaceName\":\"池共享集群\",\"registryIsHttp\":null,\"paasNamespaceId\":\"3f15c030-e98b-4760-b598-370671096ae2\",\"k8sPvc\":null,\"helmmuseumUrl\":null,\"releaseMode\":\"production\",\"kubeApiserver\":null}}", //流水线配置
"appCode": "plpythonurl", //流水线对应应用编码
"userName": null, //流水线创建人名称
"deployId": null, //流水线部署任务id
"orgId": "3251bde0-85d7-4e3a-bf98-86006f749d21", //流水线所属组织id
"template_code": "ea_pipe", //流水线模板编码
"jobId": "bd383b78-7547-4ca0-9374-0f70d7304c7f", //流水线总体任务调度id
"prodAppId": "408a4a45-6339-4c0f-b6c4-443e73615148", //流水线部署应用id
"createdDate": "2024-01-23T13:13:33.000Z", //流水线创建时间
"processId": "CA99F27429300001C71BB8C0D38D1E4D", //流水线流程实例id
"createdBy": "duanyl", //流水线创建人
"domainPrefix": "plpythonurlduanyl6", //流水线对应应用标识
"appId": "8525dd25-4b8f-4b40-a61f-0f11ce8db894", //流水线对应
"tempate_name": "外部应用部署模板", //流水线模板名称
"name": "python请求测试", //流水线名称
"template_id": "5EA5234E6B3C4037A68147A5FFFAF5EA", //流水线模板id
"id": "CA99F27429300001C71BB8C0D38D1E4D", //流水线id
"createdById": "e23E0UOskHqKqS7TyhP", //流水线创建人id
"status": "发布完成" //流水线状态
}
执行流水线
请求地址: 控制台域名/devops/main/api/excutepipeline
请求方式: GET
请求参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
id | String | Id与code至少要存在一个 | 流水线id |
code | String | Id与code至少要存在一个 | 流水线编码 |
示例:
{
"id":"CAA9E2E09C2000016D5F1BC010701D16", //流水线编码
}
返回结果
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 请求结果编码,200为成功,其他的为错误码 |
msg | String | 是 | 请求结果提示内容 |
data | String | 否 | 请求结果返回的数据,这里为流水线的信息 |
示例:
{
"code":"200",
"msg":"流水线执行成功",
"data":null
}
查询流水线日志列表接口
请求地址: 控制台域名/devops/main/api/getpipelineloglist
请求方式: GET
请求参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
jobId | String | 是 | 流水线总体任务调度id,可通过查询流水线得到相应的jobId |
示例:
{
"jobId":"CAA9E2E09C2000016D5F1BC010701D16", //流水线总体任务调度id
}
返回结果
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 请求结果编码,200为成功,其他的为错误码 |
msg | String | 是 | 请求结果提示内容 |
data | JSONObject | 否 | 请求结果返回的数据,这里为流水线的信息 |
示例:
{
"code":"200",
"msg":"流水线执行成功",
"data":"此字段为json字符串,详见下面说明"
}
data
[
{
"id": "6b609921-d054-4581-a17b-aa8773f8e75c", //
"jobId": "bd383b78-7547-4ca0-9374-0f70d7304c7f", //流水线总体任务调度id
"execution": "0", //执行次数
"startTime": "2024-01-23T13:14:55.000+00:00", //执行开始时间
"endTime": "2024-01-23T13:14:56.000+00:00", //执行结束时间
"requestCount": "1", //请求次数
"requestResults": "[{\"1\":{\"response\":{\"data\":\"[{\\\"process\\\":\\\"/SA/wf/default/CA99F27429300001C71BB8C0D38D1E4D\\\",\\\"task\\\":\\\"78BA1695D867443AA9FE0AAB089E77B4\\\",\\\"activity\\\":\\\"serviceActivity1\\\",\\\"pi\\\":\\\"B93A2B1B76514074B1D996EAD3ACCA43\\\"}, {\\\"pi\\\":\\\"B93A2B1B76514074B1D996EAD3ACCA43\\\"}]\"},\"httpStatus\":200}}]", //请求结果
"notifyResults": "[{\"1\":{\"response\":{\"data\":{\"data\":\"[{\\\"process\\\":\\\"/SA/wf/default/CA99F27429300001C71BB8C0D38D1E4D\\\",\\\"task\\\":\\\"78BA1695D867443AA9FE0AAB089E77B4\\\",\\\"activity\\\":\\\"serviceActivity1\\\",\\\"pi\\\":\\\"B93A2B1B76514074B1D996EAD3ACCA43\\\"}, {\\\"pi\\\":\\\"B93A2B1B76514074B1D996EAD3ACCA43\\\"}]\"},\"progress\":\"100%\",\"message\":\"同步调用request成功...\",\"status\":\"finalSucceed\"},\"httpStatus\":200}}]", //通知结果
"notifiedFinalStatus": null, //通知状态
"notifyRetryFailed": "0", //通知重试次数
"notifyRetryInfo": null, //
"childJobs": "[\"bd383b78-7547-4ca0-9374-0f70d7304c7f-0-initPipeline\",\"bd383b78-7547-4ca0-9374-0f70d7304c7f-0-checkInitPipelineFinish\",\"bd383b78-7547-4ca0-9374-0f70d7304c7f-0-pullCode\",\"bd383b78-7547-4ca0-9374-0f70d7304c7f-0-quickDeploy\"]" //子任务id数组
}
]
查询流水线日志详情接口
请求地址: 控制台域名/devops/main/api/getpipelinelog
请求方式: GET
请求参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
parentJobId | String | 是 | 流水线总体任务调度id,可通过查询流水线得到相应的jobId |
execution | String | 是 | 执行次数(第几次执行) |
示例:
{
"id":"CAA9E2E09C2000016D5F1BC010701D16", //流水线编码
}
返回结果
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | String | 是 | 请求结果编码,200为成功,其他的为错误码 |
msg | String | 是 | 请求结果提示内容 |
data | JSONObject | 否 | 请求结果返回的数据,这里为流水线的信息 |
示例:
{
"code":"200",
"msg":"流水线执行成功",
"data":"此字段为json字符串,详见下面说明"
}
data
{
"fid": "bd383b78-7547-4ca0-9374-0f70d7304c7f", //总体任务调度id
"pipeLineID": "CAA9E2E09C2000016D5F1BC010701D16", //流水线id
"jobID": "bd383b78-7547-4ca0-9374-0f70d7304c7f", //总任务调度id
"excutionNum": "0", //第几次执行
"logs": "[{\"jobName\":\"生成配置文件\",\"createTime\":\"2024-01-23T13:15:03.000Z\",\"message\":\"异步调用request成功...\"},{\"jobName\":\"生成配置文件\",\"createTime\":\"2024-01-23T13:15:06.000Z\"}].............." //执行日志
}
如果是流水线api发布
在新增或者修改流水线的conf字段里加入如下api doc内容即可
// conf字段里加入 apiContent 字段进行承载
{
"pipeOrigin": {
// ......
},
"releaseSetings": {
// ......
},
"apiContent": {
"name": "", //api名称, 必填
"code": "", //api编码, 必填且必须唯一
"requestPath": "", //请求路径, 必填
"serverUrl": "", //服务地址,可选,如果没有将会自动api文档中的servers中的第一个
"tenantCode": "", //网关租户编码, 必填
"ownerOrgCode": "", //api所属组织编码, 可选
"apiDoc": {}, //api文档内容
"apiDocUrl": "", //api文档地址,apiDoc和apiDocUrl二选一, 优先使用apiDoc, 没有就根据apiDocUrl获取
"coverUrl": "", //封面地址, 可选
"category": "" //分类标识,多值时使用","分隔,例如"106,190"
}
}
流水线、流程、任务调度job三者关系
- 创建流水线时会关联上一个流水线模板(流程定义模板),此刻流水线关联的流程只是模板。
- 当点击执行流水线时,如果此流水线未执行过是初次执行时,那么将创建一个流程定义实例,并且该流程定义实例的id会组装关联给任务调度的job里。接下来进行创建任务调度job,在这个过程中每执行一次job就start一次流程定义实例(相当于创建一条流程实例),而任务调度的job既可以配置调度策略进行周期性执行,也可以单次触发执行,流水线初次执行之后的每次点击执行的逻辑就是单次触发任务调度job而已。
- 流水线与流程定义模板一对一关系。
- 流程定义模板与流程定义一对一关系。
- 流程定义与任务调度job一对一关系。
- 任务调度job与流程实例一对多关系,所以流程定义与流程实例一对多关系。
- 任务调度job与job执行记录一对一关系。
用户自定义开发流水线
有两种方案
- 一种是定制ent_devops、devops池、devops组件等基础,该方案对开发者要求比较高,需要开发者理解pass平台的知识点。
- 另一种是基于流水线OpenAPI来进行开发,对开发者要求比较低,理解基本原理及应用场景即可。推荐使用该方案,该方案在以后的章节会详细写一篇。
流水线模板细节剖析
流水线模板即流水线流程,这里以外部应用部署为例往下讲解,剖析的流程:流水线总任务job——》流水线流程定义模板——》流程定义的每一个服务环节——》最终落实到具体的任务job
事先需参考文档:
- 任务调度接口文档:开发手册——》业务中间件——》任务调度——》技术架构、接口和运行原理
- 企业工作流的接口文档:开发手册——》业务模型体系——》流程模型——》附录——》任务API 流程动作API
xxx流水线总任务
将job导出进行细节剖析:
[
{
"active": 1,
"async": false,
"checkRateSeconds": 1,
"createTime": 1739782279000,
"creator": "chensc1",
"creatorName": "chensc1",
"jobDescription": "流水线30d66e12-17cf-4ec5-a7d6-b0613f3e6fbc",
"jobId": "30d66e12-17cf-4ec5-a7d6-b0613f3e6fbc",
"jobName": "ruoyiservice1流水线总任务",
"maxRetries": 5,
"notification": [
// Notify通知:主要通知到创建者当前作业的执行状况,如这里通知到devops管理服务的消息处理接口上
{
"body": {
"data": "${schedulingNotifyBody}|json",
"taskName": "ruoyiservice1流水线总任务"
},
"method": "POST",
"url": "service://devops/main/wfmanage/callbackmsg?taskCode=startOverallJob&pipelineId=CB0ACBAE1F9000018EF1484AC6506100&pipelineExecuteId=30d66e12-17cf-4ec5-a7d6-b0613f3e6fbc&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}"
}
],
"qos": 0,
"request": [
// 此处的request是启动CB0ACBAE1F9000018EF1484AC6506100流程,该流程定义是在初次点击执行流水线按钮时进行创建
{
"body": {
"process": "CB0ACBAE1F9000018EF1484AC6506100",
// 这里携带两个流程参数,目的是为以后该流程实例里的各服务环节上提供流程参数引用
"attributes": {
"sData2": "${schedulingExecuteNumber}", // 当前的执行次数
"sData1": "${schedulingJobId}" // 当前的总jobid
}
},
"formCommit": false,
"headers": {
"X-Credential-Token": "TAboLjVy_69"
},
"method": "POST",
"responseHeader": false,
// 指定流程服务接口,此处语义是进行启动流程定义创建流程实例
"url": "service://wf/biz/process/start"
}
],
"retry": [
{
"backoffRate": 1.5,
"errorEquals": "500",
"intervalSeconds": 2,
"maxAttempts": 2
}
],
"timeoutSeconds": 60,
"timer": {}
}
]
流程模板定义
标签
{
"pipeLineTemplate": true, // 标记该流程定义是流水线模板
"createAppIde": true // 创建应用的ide,像外部应用部署模板和helm部署模板都需要在ide内进行作业
}
ide初始化
注释:
- 是否等待:流水线服务环节这里必须设置等待,不然流水线环节执行不会根据执行状态等待,会一串到底。
- 重试次数:执行到该流水线环节时如果发生服务调用异常,那么就使用此处的重试次数进行重试
- 服务请求:以 requests(文档位置在 开发手册——》业务中间——》任务调度——》requests 使用文档) 的方式进行调用
- 可以通过选择服务来快速创建
- requests内容
[ { "body": { "jobName": "IDE初始化", // ${sData1}和${sData2}从上方流水线总任务可得,${sData1}——》总jobId、${sData2}——》总job当前的执行次数 // 他们的替换逻辑时机走工作流服务wf "jobDescription": "IDE初始化-IDEInit-${sData1}-${sData2}", "request": [ { "method": "GET", // 调用devops获取能打开ide的url地址,因为必须得用该地址才能进行ide绑定 // ${devopsURL}、${pipeLineId}将在ent_devops服务中基于该流程定义模板创建流程定义时进行替换 "url": "${devopsURL}/main/pipeline/ideurl?pipeLineId=${pipeLineId}" }, { "method": "GET", // ${$.data} 此处走任务调度服务编排替换逻辑,逻辑是:当前request第一个请求的请求结果可以为第二个请求提供使用,引用方式请参考任务调度的文档 "url": "${$.data}" } ], "active": 1, "async": true, "jobId": "${sData1}-${sData2}-IDEInit", "parentJob": "${sData1}", "parentJobExecution": "${sData2}", // ${creator} 将在ent_devops服务中基于该流程定义模板创建流程定义时进行替 "creator": "${creator}", // ${creatorName} 将在ent_devops服务中基于该流程定义模板创建流程定义时进行替 "creatorName": "${creatorName}", "notification": [ { "headers": { // ${credentialToken} 服务之间通讯认证的匿名token,将在ent_devops服务中基于该流程定义模板创建流程定义时进行替 "X-Credential-Token": "${credentialToken}" }, "method": "POST", "body": { // ${task} 该流程实例当前服务环节的任务id,替换机制走wf服务 "task": "${task}" }, "stateEquals": "finalFailed", // 当时是 finalFailed 状态时,调用流程服务终止环节终止整个流程 "url": "service://wf/biz/process/abort" }, { "headers": { "X-Credential-Token": "${credentialToken}" }, "method": "POST", "body": { // JSON 简化写法,语义即上方的 "task": "${task}" "$ref": "$[0].body.notification[0].body" }, "stateEquals": "finalSucceed", // 当时是 finalSucceed 状态时,调用流程服务通过此环节,进入下一个环节 "url": "service://wf/biz/process/advance" }, { "method": "POST", "body": { // ${schedulingNotifyBody} 当前任务调度job 的通知内容,使用语法参考任务调度开发手册 "data": "${schedulingNotifyBody}|json", "taskName": "IDE初始化" }, // 回调通知devops /callbackmsg接口,此处没设置stateEquals,将会进行所有job状态通知 // ${schedulingJobId} 当前任务调度jobId、${schedulingExecuteNumber}当前任务调度执行次数,使用语法参考任务调度开发手册 // finalTask=false 表示当前不是最终服务环节 "url": "${devopsURL}/main/wfmanage/callbackmsg?taskCode=IDEInit&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}&finalTask=false" } ], "qos": 0, "timeoutSeconds": 300, "checkRateSeconds": 4, "checkUrl": { "method": "GET", // 检查当前应用ide健康状况 // ${ideURL} 将在ent_devops服务中基于该流程定义模板创建流程定义时进行替 "url": "${ideURL}/devops/check/health" }, "retry": [ { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "500", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "502", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "501", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "timeout", "intervalSeconds": 3 } ] }, "method": "POST", // 调用任务调度创建job "url": "service://scheduling/jobs/${sData1}-${sData2}-IDEInit" } ]
生成配置文件
requests内容[ { "body": { "jobName": "生成配置文件", "jobDescription": "生成配置文件-initPipeline-${sData1}-${sData2}", "request": [ { "method": "GET", // 从devops服务上获取控制台session,用于devops池中使用 "url": "${devopsURL}/main/pipeline/getconsolesession?pipeLineId=${pipeLineId}" }, { "method": "POST", "body": { "jobId": "${schedulingJobId}", "executeNumber": "${schedulingExecuteNumber}", "requestCounts": "${schedulingRequestCounts}", "pipelineId": "${pipeLineId}", "pipelineExecuteId": "${sData1}", "feedbackUrl": "${schedulingFeedbackUrl}", // 从第一个请求上返回的控制台session值,在此处进行引用 "consoleSession": "${$.data}", "devopsManagerAddress": "${devopsManagerAddress}" }, // 调用devops ide池初始化流水线接口,进行生成配置文件 "url": "${ideURL}/devops/initPipeline" } ], "active": 1, "async": true, "jobId": "${sData1}-${sData2}-initPipeline", "parentJob": "${sData1}", "parentJobExecution": "${sData2}", "creator": "${creator}", "creatorName": "${creatorName}", "notification": [ { "headers": { "X-Credential-Token": "${credentialToken}" }, "method": "POST", "body": { "task": "${task}" }, "stateEquals": "finalFailed", "url": "service://wf/biz/process/abort" }, { "headers": { "X-Credential-Token": "${credentialToken}" }, "method": "POST", "body": { "$ref": "$[0].body.notification[0].body" }, "stateEquals": "finalSucceed", "url": "service://wf/biz/process/advance" }, { "method": "POST", "body": { "data": "${schedulingNotifyBody}|json", "taskName": "生成配置文件" }, "url": "${devopsURL}/main/wfmanage/callbackmsg?taskCode=initPipeline&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}&finalTask=false" } ], "qos": 0, "timeoutSeconds": 180, "checkRateSeconds": 4, "retry": [ { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "500", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "timeout", "intervalSeconds": 3 } ] }, "method": "POST", // "url": "service://scheduling/jobs/${sData1}-${sData2}-initPipeline" } ]
IDE重启
[ { "body": { "jobName": "IDE重启1", "jobDescription": "IDE重启1-ideRestart-${sData1}-${sData2}", "request": [ { "method": "GET", "url": "${devopsURL}/main/pipeline/getconsolesession?pipeLineId=${pipeLineId}" }, { "method": "POST", "body": { "jobId": "${schedulingJobId}", "executeNumber": "${schedulingExecuteNumber}", "requestCounts": "${schedulingRequestCounts}", "pipelineId": "${pipeLineId}", "pipelineExecuteId": "${sData1}", "feedbackUrl": "${schedulingFeedbackUrl}", "consoleSession": "${$.data}", "devopsManagerAddress": "${devopsManagerAddress}" }, // 调用devops 池重启接口 "url": "${ideURL}/devops/ideRestart" } ], "active": 1, "async": true, "jobId": "${sData1}-${sData2}-ideRestart1", "parentJob": "${sData1}", "parentJobExecution": "${sData2}", "creator": "${creator}", "creatorName": "${creatorName}", "notification": [ { "headers": { "X-Credential-Token": "${credentialToken}" }, "method": "POST", "body": { "task": "${task}" }, "stateEquals": "finalFailed", "url": "service://wf/biz/process/abort" }, { "headers": { "X-Credential-Token": "${credentialToken}" }, "method": "POST", "body": { "$ref": "$[0].body.notification[0].body" }, "stateEquals": "finalSucceed", "url": "service://wf/biz/process/advance" }, { "method": "POST", "body": { "data": "${schedulingNotifyBody}|json", "taskName": "IDE重启1" }, "url": "${devopsURL}/main/wfmanage/callbackmsg?taskCode=ideRestart1&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}&finalTask=false" } ], "qos": 0, "timeoutSeconds": 60, "checkRateSeconds": 4, "retry": [ { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "500", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "502", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "501", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "404", "intervalSeconds": 3 }, { "maxAttempts": 3, "backoffRate": 1, "errorEquals": "timeout", "intervalSeconds": 3 } ] }, "method": "POST", "url": "service://scheduling/jobs/${sData1}-${sData2}-ideRestart1" } ]
- 可以通过选择服务来快速创建
ide重启检查
[
{
"body": {
"jobName": "ide重启检查1",
"jobDescription": "ide重启检查1-checkIdeRestart-${sData1}-${sData2}",
"request": [
{
"method": "GET",
"url": "${devopsURL}/main/pipeline/getconsolesession?pipeLineId=${pipeLineId}"
},
{
"method": "POST",
"body": {
"jobId": "${schedulingJobId}",
"executeNumber": "${schedulingExecuteNumber}",
"requestCounts": "${schedulingRequestCounts}",
"pipelineId": "${pipeLineId}",
"pipelineExecuteId": "${sData1}",
"feedbackUrl": "${schedulingFeedbackUrl}",
"consoleSession": "${$.data}",
"devopsManagerAddress": "${devopsManagerAddress}"
},
// 调devops池检查ide是否重启成功
"url": "${ideURL}/devops/checkIdeRestart"
}
],
"active": 1,
"async": true,
"jobId": "${sData1}-${sData2}-checkIdeRestart1",
"parentJob": "${sData1}",
"parentJobExecution": "${sData2}",
"creator": "${creator}",
"creatorName": "${creatorName}",
"notification": [
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"task": "${task}"
},
"stateEquals": "finalFailed",
"url": "service://wf/biz/process/abort"
},
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"$ref": "$[0].body.notification[0].body"
},
"stateEquals": "finalSucceed",
"url": "service://wf/biz/process/advance"
},
{
"method": "POST",
"body": {
"data": "${schedulingNotifyBody}|json",
"taskName": "ide重启检查1"
},
"url": "${devopsURL}/main/wfmanage/callbackmsg?taskCode=checkIdeRestart1&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}&finalTask=false"
}
],
"qos": 0,
"timeoutSeconds": 30,
"checkRateSeconds": 4,
"checkUrl": {
"method": "GET",
"url": "${ideURL}/devops/check?jobId=${schedulingJobId}&executeNumber=${schedulingExecuteNumber}&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}"
},
"retry": [
{
"maxAttempts": 6,
"backoffRate": 1,
"errorEquals": "500",
"intervalSeconds": 3
},
{
"maxAttempts": 6,
"backoffRate": 1,
"errorEquals": "502",
"intervalSeconds": 3
},
{
"maxAttempts": 6,
"backoffRate": 1,
"errorEquals": "timeout",
"intervalSeconds": 3
},
{
"maxAttempts": 6,
"backoffRate": 1,
"errorEquals": "404",
"intervalSeconds": 3
}
]
},
"method": "POST",
"url": "service://scheduling/jobs/${sData1}-${sData2}-checkIdeRestart1"
}
]
拉取代码
[
{
"body": {
"jobName": "拉取代码",
"jobDescription": "拉取代码-pullCode-${sData1}-${sData2}",
"request": [
{
"method": "GET",
"url": "${devopsURL}/main/pipeline/getconsolesession?pipeLineId=${pipeLineId}"
},
{
"method": "POST",
"body": {
"jobId": "${schedulingJobId}",
"executeNumber": "${schedulingExecuteNumber}",
"requestCounts": "${schedulingRequestCounts}",
"pipelineId": "${pipeLineId}",
"pipelineExecuteId": "${sData1}",
"feedbackUrl": "${schedulingFeedbackUrl}",
"consoleSession": "${$.data}",
"devopsManagerAddress": "${devopsManagerAddress}"
},
// 调用devops池拉取代码
"url": "${ideURL}/devops/pullCode"
}
],
"active": 1,
"async": true,
"jobId": "${sData1}-${sData2}-pullCode",
"parentJob": "${sData1}",
"parentJobExecution": "${sData2}",
"creator": "${creator}",
"creatorName": "${creatorName}",
"notification": [
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"task": "${task}"
},
"stateEquals": "finalFailed",
"url": "service://wf/biz/process/abort"
},
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"$ref": "$[0].body.notification[0].body"
},
"stateEquals": "finalSucceed",
"url": "service://wf/biz/process/advance"
},
{
"method": "POST",
"body": {
"data": "${schedulingNotifyBody}|json",
"taskName": "拉取代码"
},
"url": "${devopsURL}/main/wfmanage/callbackmsg?taskCode=pullCode&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}&finalTask=false"
}
],
"qos": 0,
"timeoutSeconds": 60,
"checkRateSeconds": 4,
"retry": [
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "500",
"intervalSeconds": 3
},
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "timeout",
"intervalSeconds": 3
},
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "404",
"intervalSeconds": 3
}
]
},
"method": "POST",
"url": "service://scheduling/jobs/${sData1}-${sData2}-pullCode",
"extend": [
{
"formType": "url",
"formUrl": "$UI/pcx/pipeLine/waibu_lsxly.w",
"formName": "代码拉取设置"
}
]
}
]
快速部署
[
{
"body": {
"jobName": "快速部署",
"jobDescription": "快速部署-quickDeploy-${sData1}-${sData2}",
"request": [
{
"method": "GET",
"url": "${devopsURL}/main/pipeline/getconsolesession?pipeLineId=${pipeLineId}"
},
{
"method": "POST",
"body": {
"jobId": "${schedulingJobId}",
"executeNumber": "${schedulingExecuteNumber}",
"requestCounts": "${schedulingRequestCounts}",
"pipelineId": "${pipeLineId}",
"pipelineExecuteId": "${sData1}",
"feedbackUrl": "${schedulingFeedbackUrl}",
"consoleSession": "${$.data}",
"devopsManagerAddress": "${devopsManagerAddress}"
},
// 调用devops池执行快速部署逻辑
"url": "${ideURL}/devops/quickDeploy"
}
],
"active": 1,
"async": true,
"jobId": "${sData1}-${sData2}-quickDeploy",
"parentJob": "${sData1}",
"parentJobExecution": "${sData2}",
"creator": "${creator}",
"creatorName": "${creatorName}",
"notification": [
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"task": "${task}"
},
"stateEquals": "finalFailed",
"url": "service://wf/biz/process/abort"
},
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"$ref": "$[0].body.notification[0].body"
},
"stateEquals": "finalSucceed",
"url": "service://wf/biz/process/advance"
},
{
"method": "POST",
"body": {
"data": "${schedulingNotifyBody}|json",
"taskName": "快速部署"
},
// finalTask=true 代表该流程环节是最后一个服务环节,devops收到通知后会将该条流水线标记为已完成
"url": "${devopsURL}/main/wfmanage/callbackmsg?taskCode=quickDeploy&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}&finalTask=true"
}
],
"qos": 0,
"timeoutSeconds": 300,
"checkRateSeconds": 4,
"retry": [
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "500",
"intervalSeconds": 1
},
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "timeout",
"intervalSeconds": 1
}
]
},
"method": "POST",
"url": "service://scheduling/jobs/${sData1}-${sData2}-quickDeploy",
"extend": [
{
"formType": "url",
"formUrl": "$UI/pcx/pipeLine/goujian_xx.w",
"formName": "构建编译"
},
{
"formType": "url",
"formUrl": "$UI/pcx/pipeLine/bushu_sz.w",
"formName": "应用配置"
},
{
"formType": "url",
"formUrl": "$UI/pcx/pipeLine/fabu_sz.w",
"formName": "发布部署"
}
]
}
]
服务环节抽取为任务模板
流水线流程定义的每个服务环节都可以抽取为任务模板,以下我们以ide重启服务环节为例
- 定义内容:是request
- 参数格式(FormRender原理):对request抽取一些变量,通过参数格式功能动态设置进去
示例:
// 内容
[
{
"body": {
// 即是定义的动态变量
"jobName": "IDE重启",
"jobDescription": "IDE重启-ideRestart-${sData1}-${sData2}",
"request": [
{
"method": "GET",
"url": "${devopsURL}/main/pipeline/getconsolesession?pipeLineId=${pipeLineId}"
},
{
"method": "POST",
"body": {
"jobId": "${schedulingJobId}",
"executeNumber": "${schedulingExecuteNumber}",
"requestCounts": "${schedulingRequestCounts}",
"pipelineId": "${pipeLineId}",
"pipelineExecuteId": "${sData1}",
"feedbackUrl": "${schedulingFeedbackUrl}",
"consoleSession": "${$.data}",
"devopsManagerAddress": "${devopsManagerAddress}"
},
"url": "${ideURL}/devops/ideRestart"
}
],
"active": 1,
"async": true,
"jobId": "${sData1}-${sData2}-ideRestart",
"parentJob": "${sData1}",
"parentJobExecution": "${sData2}",
"creator": "${creator}",
"creatorName": "${creatorName}",
"notification": [
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"task": "${task}"
},
"stateEquals": "finalFailed",
"url": "service://wf/biz/process/abort"
},
{
"headers": {
"X-Credential-Token": "${credentialToken}"
},
"method": "POST",
"body": {
"$ref": "$[0].body.notification[0].body"
},
"stateEquals": "finalSucceed",
"url": "service://wf/biz/process/advance"
},
{
"method": "POST",
"body": {
"data": "${schedulingNotifyBody}|json",
"taskName": "IDE重启"
},
// 即是定义的动态变量
"url": "${devopsURL}/main/wfmanage/callbackmsg?taskCode=ideRestart&pipelineId=${pipeLineId}&pipelineExecuteId=${sData1}&schedulingJobId=${schedulingJobId}&schedulingExecuteNumber=${schedulingExecuteNumber}&finalTask="
}
],
"qos": 0,
"timeoutSeconds": 60,
"checkRateSeconds": 4,
"retry": [
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "500",
"intervalSeconds": 3
},
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "502",
"intervalSeconds": 3
},
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "501",
"intervalSeconds": 3
},
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "404",
"intervalSeconds": 3
},
{
"maxAttempts": 3,
"backoffRate": 1,
"errorEquals": "timeout",
"intervalSeconds": 3
}
]
},
"method": "POST",
"url": "service://scheduling/jobs/${sData1}-${sData2}-ideRestart"
}
]
// 参数格式 FormRender 如下:
{
"ui:labelWidth": 180,
"type": "object",
"properties": {
// 此处替换上面的
"finalTask": {
"title": "是否为最终环节",
"type": "boolean",
"default": false,
"enum": [
true,
false
],
"enumNames": [
"是",
"否"
],
"widget": "select"
},
// 此处替换上面的
"tag": {
"title": "打tag(不允许有中文和特殊字符)",
"type": "string",
"default": "1"
}
}
}
配置模板管理
配置模板管理主要是配置外部应用部署脚本模板
模板脚本常用到的几个变量
发布工程所在目录 releasePath
目标目录 targetDir
发布项目名称 projectName
发布项目名称全大写 projectNameUpperCase
举例如何使用这些变量,以下以Java Maven buildCommand为例
build.sh
#!/bin/bash
set -e
# 此处为模块的根目录 如:/usr/local/x5/model/service/ruoyiservice
CURRENT_DIR=$(cd $(dirname $0); pwd)
# 如果界面上设置了目标目录,整个git上的代码也会移动到此处,替换机制,这里也会将${targetDir}替换为目标目录
TARGET_DIR="${targetDir}"
if [ -n "$TARGET_DIR" ];then
TARGET_DIR_WORK=$CURRENT_DIR/$TARGET_DIR
else
TARGET_DIR_WORK=$CURRENT_DIR
fi
# 一般工作目录下都会存在pom.xml文件
pomDir=$TARGET_DIR_WORK/pom.xml
# Maven命令
mavenCommand="package -Dmaven.test.skip=true"
# 以下逻辑主要是将打包好的target目录下的可执行jar复制到模块目录下的dist文件里,为发布部署提供资源
if [ -f "$pomDir" ]; then
$JUSTEP_HOME/tools/maven/bin/mvn -B -f $pomDir $mavenCommand
# ${releasePath} 发布工程所在的目录,主要在Maven多模块的场景下管用,这里的目的是从主模块下复制jar
workspace=$(cd $TARGET_DIR_WORK/${releasePath}; pwd)
fileName=$(cd $workspace/target && ls *.jar 2>/dev/null) || true
fileName=${fileName%.*}
mkdir -p $CURRENT_DIR/dist
# ${projectName} 发布项目的名称,这里将工作目录下的jar复制并重命名成项目名的jar
cp -r $workspace/target/$fileName.jar $CURRENT_DIR/dist/${projectName}.jar
else
echo "Maven构建文件 $pomDir 不存在,忽略构建..."
fi
buildCommand
构建脚本:主要负责构建工作,java、node等这些语言,生命周期只在ide阶段,而不是运行时。
installCommand
安装脚本:主要负责安装程序工作,一般是编译好的包安装(将startCommand委派给supervisord管理)和系统依赖安装,运行时生命周期执行时序 1
initedCommand
初始化脚本:应用运行前做一些初始化工作,如调用门户初始化,运行时生命周期执行时序 2
startCommand
启动脚本:由supervisord管理,他是一个独立的进程,里面是真正运行二进制的命令,生命周期由supervisord管理
settings
Maven setting 里面管理Maven的本地仓库和中央仓库,为Java模式下为buildCommand阶段提供Maven依赖
nginx_settings
nginx conf 配置文件:当Node模式下运行时的nginx配置