1、增加执行间隔
2、添加推送进度流程
This commit is contained in:
parent
7b53d02e0e
commit
f90bccd0ad
@ -56,7 +56,7 @@ description: 面向 PAM HOME/NODE 的智能部署 Skill。由 Skill 负责理解
|
|||||||
### 3.1 必填业务参数
|
### 3.1 必填业务参数
|
||||||
|
|
||||||
| 规范字段 | 脚本字段 | 必填 | 说明 |
|
| 规范字段 | 脚本字段 | 必填 | 说明 |
|
||||||
| --- | --- | --- | --- |
|
| ----------------- | ---------------- | --- | ------------------ |
|
||||||
| `HOME_BASE_URL` | `HOME_BASE_URL` | 是 | PAM HOME 基础地址 |
|
| `HOME_BASE_URL` | `HOME_BASE_URL` | 是 | PAM HOME 基础地址 |
|
||||||
| `client_id` | `CLIENT_ID` | 是 | OAuth 客户端 ID |
|
| `client_id` | `CLIENT_ID` | 是 | OAuth 客户端 ID |
|
||||||
| `client_secret` | `CLIENT_SECRET` | 是 | OAuth 客户端密钥 |
|
| `client_secret` | `CLIENT_SECRET` | 是 | OAuth 客户端密钥 |
|
||||||
@ -197,6 +197,7 @@ description: 面向 PAM HOME/NODE 的智能部署 Skill。由 Skill 负责理解
|
|||||||
15. 调用 `poll-download-progress`,直到下载完成、失败或超时。
|
15. 调用 `poll-download-progress`,直到下载完成、失败或超时。
|
||||||
16. 按在线 IP 或过滤后的目标 IP 列表逐台执行:
|
16. 按在线 IP 或过滤后的目标 IP 列表逐台执行:
|
||||||
- `upgrade-ip`
|
- `upgrade-ip`
|
||||||
|
- `poll-upgrade-progress`
|
||||||
- `start-ip`
|
- `start-ip`
|
||||||
- `verify-ip`
|
- `verify-ip`
|
||||||
- `download-log`
|
- `download-log`
|
||||||
@ -210,7 +211,8 @@ description: 面向 PAM HOME/NODE 的智能部署 Skill。由 Skill 负责理解
|
|||||||
2. 全局 action 与下一 action 之间,按 `stepIntervalSec` 等待。
|
2. 全局 action 与下一 action 之间,按 `stepIntervalSec` 等待。
|
||||||
3. `create-download-task` 成功后,到首次 `poll-download-progress` 前,按 `firstPollDelaySec` 等待。
|
3. `create-download-task` 成功后,到首次 `poll-download-progress` 前,按 `firstPollDelaySec` 等待。
|
||||||
4. 同一台 IP 内部:
|
4. 同一台 IP 内部:
|
||||||
- `upgrade-ip -> start-ip`
|
- `upgrade-ip -> poll-upgrade-progress`
|
||||||
|
- `poll-upgrade-progress -> start-ip`
|
||||||
- `start-ip -> verify-ip`
|
- `start-ip -> verify-ip`
|
||||||
- `verify-ip -> download-log`
|
- `verify-ip -> download-log`
|
||||||
之间按 `perIpStepIntervalSec` 等待。
|
之间按 `perIpStepIntervalSec` 等待。
|
||||||
@ -323,7 +325,8 @@ description: 面向 PAM HOME/NODE 的智能部署 Skill。由 Skill 负责理解
|
|||||||
- 在线 IP 列表
|
- 在线 IP 列表
|
||||||
- 过滤后的目标 IP 列表
|
- 过滤后的目标 IP 列表
|
||||||
- 每台 IP 的执行状态:
|
- 每台 IP 的执行状态:
|
||||||
- `upgrade`
|
- `upgrade-ip`
|
||||||
|
- `poll-upgrade-progress`
|
||||||
- `start`
|
- `start`
|
||||||
- `verify`
|
- `verify`
|
||||||
- `download-log`
|
- `download-log`
|
||||||
@ -412,7 +415,7 @@ description: 面向 PAM HOME/NODE 的智能部署 Skill。由 Skill 负责理解
|
|||||||
### 4.5 主流程逐步说明
|
### 4.5 主流程逐步说明
|
||||||
|
|
||||||
| 步骤 | 目标 | 调用或动作 | 成功判定 | 失败处理 |
|
| 步骤 | 目标 | 调用或动作 | 成功判定 | 失败处理 |
|
||||||
| --- | --- | --- | --- | --- |
|
| ---- | ----------- | -------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------- |
|
||||||
| 1 | 识别意图 | 判断是否为真实部署 | 意图明确为真实部署 | 若不是,转入分支流程,不执行真实部署 |
|
| 1 | 识别意图 | 判断是否为真实部署 | 意图明确为真实部署 | 若不是,转入分支流程,不执行真实部署 |
|
||||||
| 2 | 归一化参数 | 整理用户输入、补齐默认值 | 参数结构完整 | 参数不清时先追问,不猜测 |
|
| 2 | 归一化参数 | 整理用户输入、补齐默认值 | 参数结构完整 | 参数不清时先追问,不猜测 |
|
||||||
| 3 | 参数确认 | 输出参数确认单 | 用户明确确认 | 未确认前停止 |
|
| 3 | 参数确认 | 输出参数确认单 | 用户明确确认 | 未确认前停止 |
|
||||||
@ -428,10 +431,11 @@ description: 面向 PAM HOME/NODE 的智能部署 Skill。由 Skill 负责理解
|
|||||||
| 13 | 过滤目标 IP | 按用户指定 IP 与在线 IP 交集过滤 | 过滤结果明确 | 过滤后为空时停止;范围变化需确认 |
|
| 13 | 过滤目标 IP | 按用户指定 IP 与在线 IP 交集过滤 | 过滤结果明确 | 过滤后为空时停止;范围变化需确认 |
|
||||||
| 14 | 创建云下载任务 | `create-download-task` | 返回 `RESULT=TASK_CREATED` | 停止并报告 `CREATE_DOWNLOAD_TASK` 失败 |
|
| 14 | 创建云下载任务 | `create-download-task` | 返回 `RESULT=TASK_CREATED` | 停止并报告 `CREATE_DOWNLOAD_TASK` 失败 |
|
||||||
| 15 | 轮询下载进度 | `poll-download-progress` | `STEP=DONE` 或 `MSG=success` 且 `RATE_OF_PROGRESS=100` | 停止并报告 `POLL_DOWNLOAD_PROGRESS` 失败或超时 |
|
| 15 | 轮询下载进度 | `poll-download-progress` | `STEP=DONE` 或 `MSG=success` 且 `RATE_OF_PROGRESS=100` | 停止并报告 `POLL_DOWNLOAD_PROGRESS` 失败或超时 |
|
||||||
| 16.1 | 升级单 IP | `upgrade-ip --ip ...` | 返回 `SUCCESS=true` | 记录失败,标记 `PENDING_AGENT_CONFIRMATION(stopFirst=false)` |
|
| 16.1 | 创建单 IP 推送任务 | `upgrade-ip --ip ...` | 返回 `RESULT=TASK_CREATED` | 记录失败,标记 `PENDING_AGENT_CONFIRMATION(stopFirst=false)` |
|
||||||
| 16.2 | 启动单 IP | `start-ip --ip ...` | action 成功返回 | 记录失败,标记 `PENDING_AGENT_CONFIRMATION(stopFirst=true)` |
|
| 16.2 | 轮询单 IP 推送进度 | `poll-upgrade-progress --ip ...` | `STEP=DONE` 或 `FINISH=true` 或 `MSG=success` 且 `RATE_OF_PROGRESS=100` | 记录失败,标记 `PENDING_AGENT_CONFIRMATION(stopFirst=false)` |
|
||||||
| 16.3 | 校验单 IP | `verify-ip --ip ...` | 返回 `SUCCESS=true` | 记录失败,标记 `PENDING_AGENT_CONFIRMATION(stopFirst=true)` |
|
| 16.3 | 启动单 IP | `start-ip --ip ...` | action 成功返回 | 记录失败,标记 `PENDING_AGENT_CONFIRMATION(stopFirst=true)` |
|
||||||
| 16.4 | 下载日志 | `download-log --ip ...` | 返回 `LOG_FILE=...` | 记录日志下载失败,但不覆盖原主失败原因 |
|
| 16.4 | 校验单 IP | `verify-ip --ip ...` | 返回 `SUCCESS=true` | 记录失败,标记 `PENDING_AGENT_CONFIRMATION(stopFirst=true)` |
|
||||||
|
| 16.5 | 下载日志 | `download-log --ip ...` | 返回 `LOG_FILE=...` | 记录日志下载失败,但不覆盖原主失败原因 |
|
||||||
| 17 | 汇总结果 | 汇总每台 IP 的阶段、失败原因、回滚状态、日志路径 | 报告内容完整 | 若汇总失败,至少保留原始 action 输出 |
|
| 17 | 汇总结果 | 汇总每台 IP 的阶段、失败原因、回滚状态、日志路径 | 报告内容完整 | 若汇总失败,至少保留原始 action 输出 |
|
||||||
| 18 | 回滚确认分支 | 发现 `PENDING_AGENT_CONFIRMATION(...)` 时进入回滚确认 | 用户明确是否回滚 | 未确认时停止,不自动回滚 |
|
| 18 | 回滚确认分支 | 发现 `PENDING_AGENT_CONFIRMATION(...)` 时进入回滚确认 | 用户明确是否回滚 | 未确认时停止,不自动回滚 |
|
||||||
| 19 | 最终报告 | 输出最终报告 | 报告包含模式、入口、阶段结果、日志、回滚状态 | 不省略失败细节 |
|
| 19 | 最终报告 | 输出最终报告 | 报告包含模式、入口、阶段结果、日志、回滚状态 | 不省略失败细节 |
|
||||||
@ -461,7 +465,7 @@ description: 面向 PAM HOME/NODE 的智能部署 Skill。由 Skill 负责理解
|
|||||||
### 6.1 Shell 入口
|
### 6.1 Shell 入口
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash ./deploy.sh --config ./config.txt --action <action-name> [--ip 192.168.1.10] [--hash-code xxx] [--stop-first]
|
bash ./deploy.sh --config ./config.txt --action <action-name> [--ip 192.168.1.10] [--hash-code xxx] [--stop-first] [--trace-file ./logs/api_trace_xxx.log]
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.2 PowerShell 入口
|
### 6.2 PowerShell 入口
|
||||||
@ -473,7 +477,7 @@ powershell -File .\deploy.ps1 -ConfigPath .\config.txt -Action <ActionName> [-Ip
|
|||||||
### 6.3 可用 action
|
### 6.3 可用 action
|
||||||
|
|
||||||
| action | 用途 | 额外参数 |
|
| action | 用途 | 额外参数 |
|
||||||
| --- | --- | --- |
|
| ------------------------ | ------------------------------ | ------------------------------------------------------- |
|
||||||
| `get-token` | 获取访问令牌 | 无 |
|
| `get-token` | 获取访问令牌 | 无 |
|
||||||
| `create-version` | 新建版本记录 | 无 |
|
| `create-version` | 新建版本记录 | 无 |
|
||||||
| `upload-package` | 上传软件包 | 无 |
|
| `upload-package` | 上传软件包 | 无 |
|
||||||
@ -483,7 +487,8 @@ powershell -File .\deploy.ps1 -ConfigPath .\config.txt -Action <ActionName> [-Ip
|
|||||||
| `create-download-task` | 创建云下载任务 | 无 |
|
| `create-download-task` | 创建云下载任务 | 无 |
|
||||||
| `poll-download-progress` | 轮询下载进度 | 无 |
|
| `poll-download-progress` | 轮询下载进度 | 无 |
|
||||||
| `download-cloud-to-node` | 创建下载任务并轮询至完成,仅调试使用,不得进入正式主流程 | 无 |
|
| `download-cloud-to-node` | 创建下载任务并轮询至完成,仅调试使用,不得进入正式主流程 | 无 |
|
||||||
| `upgrade-ip` | 升级指定 IP | `--ip` / `-Ip` |
|
| `upgrade-ip` | 为指定 IP 创建推送任务,固定使用 `timeOut=0` | `--ip` / `-Ip` |
|
||||||
|
| `poll-upgrade-progress` | 轮询指定 IP 的推送进度 | `--ip` / `-Ip` |
|
||||||
| `start-ip` | 启动指定 IP 应用 | `--ip` / `-Ip` |
|
| `start-ip` | 启动指定 IP 应用 | `--ip` / `-Ip` |
|
||||||
| `stop-ip` | 停止指定 IP 应用 | `--ip` / `-Ip` |
|
| `stop-ip` | 停止指定 IP 应用 | `--ip` / `-Ip` |
|
||||||
| `verify-ip` | 校验指定 IP | `--ip` / `-Ip` |
|
| `verify-ip` | 校验指定 IP | `--ip` / `-Ip` |
|
||||||
|
|||||||
@ -30,8 +30,9 @@
|
|||||||
- 仅在用户明确要求时再提供 `deploy.bat`
|
- 仅在用户明确要求时再提供 `deploy.bat`
|
||||||
7. NODE 侧接口路径统一使用 `node-proxy`;`download-cloud/progress` 需额外携带 `versionNumber`,并以异步轮询方式持续展示下载进度。
|
7. NODE 侧接口路径统一使用 `node-proxy`;`download-cloud/progress` 需额外携带 `versionNumber`,并以异步轮询方式持续展示下载进度。
|
||||||
8. `download-cloud/progress` 的完成判定优先读取 `msg`、`step`、`rateOfProgress`;当 `msg=success`、`step=DONE`、`rateOfProgress=100` 时代表下载完成,其中 `rateOfProgress` 即下载进度值。
|
8. `download-cloud/progress` 的完成判定优先读取 `msg`、`step`、`rateOfProgress`;当 `msg=success`、`step=DONE`、`rateOfProgress=100` 时代表下载完成,其中 `rateOfProgress` 即下载进度值。
|
||||||
9. 正式部署脚本不会自动执行回滚;发现需要回滚时,只输出 `PENDING_AGENT_CONFIRMATION(stopFirst=...)`,由 Agent 先和用户确认,再调用手动回滚入口。
|
9. `upgrade-ip` 固定传 `timeOut=0`,只负责创建推送任务;后续必须通过 `upgrade/progress` 异步轮询指定 IP 的推送进度。
|
||||||
10. `POST /api/mcp/version/upgrade` 和 `POST /api/mcp/version/upgrade/start-stop` 的业务参数都直接放在 URL query 中,不再使用 body 表单;启停接口参数名使用 `runStart`;`download-cloud` 固定传 `timeOut=0` 创建任务。
|
10. 正式部署脚本不会自动执行回滚;发现需要回滚时,只输出 `PENDING_AGENT_CONFIRMATION(stopFirst=...)`,由 Agent 先和用户确认,再调用手动回滚入口。
|
||||||
|
11. `POST /api/mcp/version/upgrade` 和 `POST /api/mcp/version/upgrade/start-stop` 的业务参数都直接放在 URL query 中,不再使用 body 表单;启停接口参数名使用 `runStart`;`download-cloud` 固定传 `timeOut=0` 创建任务。
|
||||||
11. 脚本同时提供主流程入口与 `action` 入口;建议 Agent 优先调用 `action` 入口,由 Skill 负责主流程编排。
|
11. 脚本同时提供主流程入口与 `action` 入口;建议 Agent 优先调用 `action` 入口,由 Skill 负责主流程编排。
|
||||||
12. 当前目录中的真实 `deploy.sh` 已去除 `jq` 依赖,统一使用 Bash 原生兼容 JSON 解析;若本文中的历史代码块仍出现 `jq`,以真实脚本文件为准。
|
12. 当前目录中的真实 `deploy.sh` 已去除 `jq` 依赖,统一使用 Bash 原生兼容 JSON 解析;若本文中的历史代码块仍出现 `jq`,以真实脚本文件为准。
|
||||||
|
|
||||||
@ -748,6 +749,7 @@ bash ./deploy.sh --config ./config.txt --action get-online-ips
|
|||||||
bash ./deploy.sh --config ./config.txt --action create-download-task
|
bash ./deploy.sh --config ./config.txt --action create-download-task
|
||||||
bash ./deploy.sh --config ./config.txt --action poll-download-progress
|
bash ./deploy.sh --config ./config.txt --action poll-download-progress
|
||||||
bash ./deploy.sh --config ./config.txt --action upgrade-ip --ip 192.168.1.10
|
bash ./deploy.sh --config ./config.txt --action upgrade-ip --ip 192.168.1.10
|
||||||
|
bash ./deploy.sh --config ./config.txt --action poll-upgrade-progress --ip 192.168.1.10
|
||||||
```
|
```
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
|
|||||||
@ -39,6 +39,18 @@ $script:DownloadProgressState = [ordered]@{
|
|||||||
RateOfProgress = ''
|
RateOfProgress = ''
|
||||||
RawResponse = ''
|
RawResponse = ''
|
||||||
}
|
}
|
||||||
|
$script:UpgradeProgressState = [ordered]@{
|
||||||
|
Status = ''
|
||||||
|
Success = ''
|
||||||
|
Step = ''
|
||||||
|
Msg = ''
|
||||||
|
Message = ''
|
||||||
|
RateOfProgress = ''
|
||||||
|
Code = ''
|
||||||
|
Finish = ''
|
||||||
|
LastModify = ''
|
||||||
|
RawResponse = ''
|
||||||
|
}
|
||||||
|
|
||||||
function Write-ResultLine([string]$Key, [AllowEmptyString()][string]$Value) {
|
function Write-ResultLine([string]$Key, [AllowEmptyString()][string]$Value) {
|
||||||
if ($null -eq $Value) {
|
if ($null -eq $Value) {
|
||||||
@ -78,6 +90,20 @@ function Write-DownloadProgressResult([string]$ActionName = 'poll-download-progr
|
|||||||
Write-ResultLine -Key 'MESSAGE' -Value ([string]$script:DownloadProgressState.Message)
|
Write-ResultLine -Key 'MESSAGE' -Value ([string]$script:DownloadProgressState.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Write-UpgradeProgressResult([string]$Ip) {
|
||||||
|
Write-ResultLine -Key 'ACTION' -Value 'poll-upgrade-progress'
|
||||||
|
Write-ResultLine -Key 'IP' -Value $Ip
|
||||||
|
Write-ResultLine -Key 'STEP' -Value ([string]$script:UpgradeProgressState.Step)
|
||||||
|
Write-ResultLine -Key 'MSG' -Value ([string]$script:UpgradeProgressState.Msg)
|
||||||
|
Write-ResultLine -Key 'RATE_OF_PROGRESS' -Value ([string]$script:UpgradeProgressState.RateOfProgress)
|
||||||
|
Write-ResultLine -Key 'STATUS' -Value ([string]$script:UpgradeProgressState.Status)
|
||||||
|
Write-ResultLine -Key 'SUCCESS' -Value ([string]$script:UpgradeProgressState.Success)
|
||||||
|
Write-ResultLine -Key 'CODE' -Value ([string]$script:UpgradeProgressState.Code)
|
||||||
|
Write-ResultLine -Key 'FINISH' -Value ([string]$script:UpgradeProgressState.Finish)
|
||||||
|
Write-ResultLine -Key 'LAST_MODIFY' -Value ([string]$script:UpgradeProgressState.LastModify)
|
||||||
|
Write-ResultLine -Key 'MESSAGE' -Value ([string]$script:UpgradeProgressState.Message)
|
||||||
|
}
|
||||||
|
|
||||||
function Write-FlowStart([string]$Name, [string]$Detail = '') {
|
function Write-FlowStart([string]$Name, [string]$Detail = '') {
|
||||||
if ($Detail) {
|
if ($Detail) {
|
||||||
Write-Info "[FLOW][START] $Name | $Detail"
|
Write-Info "[FLOW][START] $Name | $Detail"
|
||||||
@ -233,6 +259,78 @@ function Get-ResponseValue {
|
|||||||
return $null
|
return $null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Get-PrimaryResponseMessage {
|
||||||
|
param($Response)
|
||||||
|
|
||||||
|
$message = Get-ResponseValue -Response $Response -Candidates @('message')
|
||||||
|
if (-not $message) {
|
||||||
|
$message = Get-ResponseValue -Response $Response -Candidates @('msg')
|
||||||
|
}
|
||||||
|
|
||||||
|
return $message
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-ResponseFailure {
|
||||||
|
param($Response)
|
||||||
|
|
||||||
|
$successFlag = Get-ResponseValue -Response $Response -Candidates @('success')
|
||||||
|
$code = Get-ResponseValue -Response $Response -Candidates @('code')
|
||||||
|
$status = Get-ResponseValue -Response $Response -Candidates @('status')
|
||||||
|
$message = Get-PrimaryResponseMessage -Response $Response
|
||||||
|
|
||||||
|
if ($successFlag -eq 'false') {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($code -and $code -ne '0') {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((@($status, $message) -join ' ') -match '(?i)fail|error') {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-ScopedResponseObject {
|
||||||
|
param(
|
||||||
|
$Response,
|
||||||
|
[string]$ScopeKey
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not $ScopeKey -or $null -eq $Response -or $Response -is [string]) {
|
||||||
|
return $Response
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Response -is [System.Collections.IDictionary]) {
|
||||||
|
if ($Response.Contains($ScopeKey)) {
|
||||||
|
return $Response[$ScopeKey]
|
||||||
|
}
|
||||||
|
return $Response
|
||||||
|
}
|
||||||
|
|
||||||
|
$property = $Response.PSObject.Properties | Where-Object { $_.Name -eq $ScopeKey } | Select-Object -First 1
|
||||||
|
if ($property) {
|
||||||
|
return $property.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Response
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-ProgressStateMessage {
|
||||||
|
param(
|
||||||
|
[System.Collections.IDictionary]$State,
|
||||||
|
[string]$DefaultMessage
|
||||||
|
)
|
||||||
|
|
||||||
|
$message = [string]$State.Message
|
||||||
|
if (-not $message) { $message = [string]$State.Msg }
|
||||||
|
if (-not $message) { $message = [string]$State.Step }
|
||||||
|
if (-not $message) { $message = $DefaultMessage }
|
||||||
|
return $message
|
||||||
|
}
|
||||||
|
|
||||||
function Get-PamConfig {
|
function Get-PamConfig {
|
||||||
param([string]$Path)
|
param([string]$Path)
|
||||||
|
|
||||||
@ -626,6 +724,109 @@ function Download-CloudToNode {
|
|||||||
Wait-DownloadProgress -Config $Config -Token $Token -NodeUrl $NodeUrl
|
Wait-DownloadProgress -Config $Config -Token $Token -NodeUrl $NodeUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Wait-UpgradeProgress {
|
||||||
|
param(
|
||||||
|
$Config,
|
||||||
|
[string]$Token,
|
||||||
|
[string]$NodeUrl,
|
||||||
|
[string]$Ip
|
||||||
|
)
|
||||||
|
|
||||||
|
$query = Join-RequestPairs ([ordered]@{
|
||||||
|
applicationName = $Config.APP_NAME
|
||||||
|
moduleName = $Config.MODULE_NAME
|
||||||
|
airportCode = $Config.AIRPORT_CODE
|
||||||
|
versionNumber = $Config.VERSION_NUMBER
|
||||||
|
})
|
||||||
|
$progressUrl = "$($Config.HOME_BASE_URL)/node-proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/progress?$query"
|
||||||
|
$script:UpgradeProgressState = [ordered]@{
|
||||||
|
Status = ''
|
||||||
|
Success = ''
|
||||||
|
Step = ''
|
||||||
|
Msg = ''
|
||||||
|
Message = ''
|
||||||
|
RateOfProgress = ''
|
||||||
|
Code = ''
|
||||||
|
Finish = ''
|
||||||
|
LastModify = ''
|
||||||
|
RawResponse = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($attempt = 0; $attempt -lt 60; $attempt++) {
|
||||||
|
$response = Invoke-PamWebRequest -Method GET -Url $progressUrl -Token $Token -Headers @{
|
||||||
|
'Target-Node' = $NodeUrl
|
||||||
|
}
|
||||||
|
$progressResponse = Get-ScopedResponseObject -Response $response -ScopeKey $Ip
|
||||||
|
|
||||||
|
$status = Get-ResponseValue -Response $progressResponse -Candidates @('status')
|
||||||
|
$successFlag = Get-ResponseValue -Response $progressResponse -Candidates @('success')
|
||||||
|
$step = Get-ResponseValue -Response $progressResponse -Candidates @('step')
|
||||||
|
$msg = Get-ResponseValue -Response $progressResponse -Candidates @('msg')
|
||||||
|
$progressValue = Get-ResponseValue -Response $progressResponse -Candidates @('rateOfProgress', 'progress', 'percent', 'data.rateOfProgress', 'data.progress', 'data.percent')
|
||||||
|
$message = Get-ResponseValue -Response $progressResponse -Candidates @('message')
|
||||||
|
$code = Get-ResponseValue -Response $progressResponse -Candidates @('code')
|
||||||
|
$finish = Get-ResponseValue -Response $progressResponse -Candidates @('finish')
|
||||||
|
$lastModify = Get-ResponseValue -Response $progressResponse -Candidates @('lastModify')
|
||||||
|
if (-not $message) { $message = $msg }
|
||||||
|
|
||||||
|
$script:UpgradeProgressState = [ordered]@{
|
||||||
|
Status = [string]$status
|
||||||
|
Success = [string]$successFlag
|
||||||
|
Step = [string]$step
|
||||||
|
Msg = [string]$msg
|
||||||
|
Message = [string]$message
|
||||||
|
RateOfProgress = [string]$progressValue
|
||||||
|
Code = [string]$code
|
||||||
|
Finish = [string]$finish
|
||||||
|
LastModify = [string]$lastModify
|
||||||
|
RawResponse = [string]$response
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressParts = [System.Collections.Generic.List[string]]::new()
|
||||||
|
$progressParts.Add("ip=$Ip")
|
||||||
|
if ($msg) { $progressParts.Add("msg=$msg") }
|
||||||
|
if ($step) { $progressParts.Add("step=$step") }
|
||||||
|
if ($progressValue) { $progressParts.Add("rateOfProgress=$progressValue") }
|
||||||
|
if ($code) { $progressParts.Add("code=$code") }
|
||||||
|
if ($finish) { $progressParts.Add("finish=$finish") }
|
||||||
|
if ($status) { $progressParts.Add("status=$status") }
|
||||||
|
if ($successFlag) { $progressParts.Add("success=$successFlag") }
|
||||||
|
if ($lastModify) { $progressParts.Add("lastModify=$lastModify") }
|
||||||
|
if ($message -and $message -ne $msg) { $progressParts.Add("message=$message") }
|
||||||
|
|
||||||
|
if ($progressParts.Count -gt 1) {
|
||||||
|
Write-Info ("Step 3.4a: async upgrade progress -> {0}" -f ($progressParts -join ', '))
|
||||||
|
} else {
|
||||||
|
Write-Info ("Step 3.4a: async upgrade progress polling... ip={0} ({1}/60)" -f $Ip, ($attempt + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($step -eq 'DONE' -or $finish -eq 'true' -or $status -eq 'completed' -or $successFlag -eq 'true') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($msg -eq 'success') -and ($progressValue -eq '100') -and ((-not $code) -or $code -eq '0')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($code -and $code -ne '0') {
|
||||||
|
if (-not $message) { $message = $msg }
|
||||||
|
if (-not $message) { $message = $step }
|
||||||
|
if (-not $message) { $message = "code=$code" }
|
||||||
|
throw "Node upgrade failed: ip=$Ip, message=$message"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((@($step, $message, $msg, $status) -join ' ') -match '(?i)fail|error') {
|
||||||
|
if (-not $message) { $message = $step }
|
||||||
|
if (-not $message) { $message = $msg }
|
||||||
|
throw "Node upgrade failed: ip=$Ip, message=$message"
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "Node upgrade timed out: ip=$Ip"
|
||||||
|
}
|
||||||
|
|
||||||
function Invoke-UpgradeRequest {
|
function Invoke-UpgradeRequest {
|
||||||
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip)
|
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip)
|
||||||
|
|
||||||
@ -637,7 +838,7 @@ function Invoke-UpgradeRequest {
|
|||||||
versionNumber = $Config.VERSION_NUMBER
|
versionNumber = $Config.VERSION_NUMBER
|
||||||
action = $Config.ACTION_TYPE
|
action = $Config.ACTION_TYPE
|
||||||
autoStart = 'false'
|
autoStart = 'false'
|
||||||
timeOut = $Config.TIMEOUT
|
timeOut = '0'
|
||||||
})
|
})
|
||||||
|
|
||||||
Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/node-proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade?$query" -Token $Token -Headers @{
|
Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/node-proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade?$query" -Token $Token -Headers @{
|
||||||
@ -802,9 +1003,9 @@ function Invoke-IpDeploy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Get-ResponseValue -Response $upgrade -Candidates @('success')) -ne 'true') {
|
if (Test-ResponseFailure -Response $upgrade) {
|
||||||
$message = Get-ResponseValue -Response $upgrade -Candidates @('message')
|
$message = Get-PrimaryResponseMessage -Response $upgrade
|
||||||
if (-not $message) { $message = 'Upgrade failed' }
|
if (-not $message) { $message = 'Upgrade task creation failed' }
|
||||||
$rollback = Get-PendingRollbackStatus -Ip $Ip -Stage 'UPGRADE' -StopFirst:$false -Reason $message
|
$rollback = Get-PendingRollbackStatus -Ip $Ip -Stage 'UPGRADE' -StopFirst:$false -Reason $message
|
||||||
$logFile = Invoke-FlowStep -Name "Download-DeployLog[$Ip]" -Action {
|
$logFile = Invoke-FlowStep -Name "Download-DeployLog[$Ip]" -Action {
|
||||||
Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
|
Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
|
||||||
@ -819,6 +1020,26 @@ function Invoke-IpDeploy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Invoke-FlowStep -Name "Wait-UpgradeProgress[$Ip]" -Action {
|
||||||
|
Wait-UpgradeProgress -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
|
||||||
|
} | Out-Null
|
||||||
|
} catch {
|
||||||
|
$message = Get-ProgressStateMessage -State $script:UpgradeProgressState -DefaultMessage 'Upgrade progress polling failed'
|
||||||
|
$rollback = Get-PendingRollbackStatus -Ip $Ip -Stage 'UPGRADE_PROGRESS' -StopFirst:$false -Reason $message
|
||||||
|
$logFile = Invoke-FlowStep -Name "Download-DeployLog[$Ip]" -Action {
|
||||||
|
Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
|
||||||
|
}
|
||||||
|
return [pscustomobject]@{
|
||||||
|
Ip = $Ip
|
||||||
|
Status = 'FAILED'
|
||||||
|
Stage = 'UPGRADE_PROGRESS'
|
||||||
|
Message = $message
|
||||||
|
Rollback = $rollback
|
||||||
|
LogFile = $logFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Invoke-FlowStep -Name "Start-Application[$Ip]" -Action {
|
Invoke-FlowStep -Name "Start-Application[$Ip]" -Action {
|
||||||
Start-Application -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
|
Start-Application -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
|
||||||
@ -1062,15 +1283,29 @@ function Invoke-PamAction {
|
|||||||
Write-DownloadProgressResult -ActionName 'download-cloud-to-node'
|
Write-DownloadProgressResult -ActionName 'download-cloud-to-node'
|
||||||
Write-ResultLine -Key 'RESULT' -Value 'DONE'
|
Write-ResultLine -Key 'RESULT' -Value 'DONE'
|
||||||
}
|
}
|
||||||
|
'poll-upgrade-progress' {
|
||||||
|
Require-IpArgument -TargetIp $Ip
|
||||||
|
$token = Invoke-FlowStep -Name 'Get-Token' -Action { Get-Token -Config $config }
|
||||||
|
$nodeUrl = Invoke-FlowStep -Name 'Get-NodeUrl' -Action { Get-NodeUrl -Config $config -Token $token }
|
||||||
|
Invoke-FlowStep -Name "Wait-UpgradeProgress[$Ip]" -Action { Wait-UpgradeProgress -Config $config -Token $token -NodeUrl $nodeUrl -Ip $Ip } | Out-Null
|
||||||
|
Write-UpgradeProgressResult -Ip $Ip
|
||||||
|
}
|
||||||
'upgrade-ip' {
|
'upgrade-ip' {
|
||||||
Require-IpArgument -TargetIp $Ip
|
Require-IpArgument -TargetIp $Ip
|
||||||
$token = Invoke-FlowStep -Name 'Get-Token' -Action { Get-Token -Config $config }
|
$token = Invoke-FlowStep -Name 'Get-Token' -Action { Get-Token -Config $config }
|
||||||
$nodeUrl = Invoke-FlowStep -Name 'Get-NodeUrl' -Action { Get-NodeUrl -Config $config -Token $token }
|
$nodeUrl = Invoke-FlowStep -Name 'Get-NodeUrl' -Action { Get-NodeUrl -Config $config -Token $token }
|
||||||
$response = Invoke-FlowStep -Name "Invoke-UpgradeRequest[$Ip]" -Action { Invoke-UpgradeRequest -Config $config -Token $token -NodeUrl $nodeUrl -Ip $Ip }
|
$response = Invoke-FlowStep -Name "Invoke-UpgradeRequest[$Ip]" -Action { Invoke-UpgradeRequest -Config $config -Token $token -NodeUrl $nodeUrl -Ip $Ip }
|
||||||
|
if (Test-ResponseFailure -Response $response) {
|
||||||
|
$message = Get-PrimaryResponseMessage -Response $response
|
||||||
|
if (-not $message) { $message = 'Upgrade task creation failed' }
|
||||||
|
throw "Upgrade task creation failed: ip=$Ip, message=$message"
|
||||||
|
}
|
||||||
Write-ResultLine -Key 'ACTION' -Value 'upgrade-ip'
|
Write-ResultLine -Key 'ACTION' -Value 'upgrade-ip'
|
||||||
Write-ResultLine -Key 'IP' -Value $Ip
|
Write-ResultLine -Key 'IP' -Value $Ip
|
||||||
|
Write-ResultLine -Key 'TIME_OUT' -Value '0'
|
||||||
|
Write-ResultLine -Key 'RESULT' -Value 'TASK_CREATED'
|
||||||
Write-ResultLine -Key 'SUCCESS' -Value (Get-ResponseValue -Response $response -Candidates @('success'))
|
Write-ResultLine -Key 'SUCCESS' -Value (Get-ResponseValue -Response $response -Candidates @('success'))
|
||||||
Write-ResultLine -Key 'MESSAGE' -Value (Get-ResponseValue -Response $response -Candidates @('message'))
|
Write-ResultLine -Key 'MESSAGE' -Value (Get-PrimaryResponseMessage -Response $response)
|
||||||
Write-ResultLine -Key 'RAW_RESPONSE' -Value ([string]$response)
|
Write-ResultLine -Key 'RAW_RESPONSE' -Value ([string]$response)
|
||||||
}
|
}
|
||||||
'start-ip' {
|
'start-ip' {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# PAM 部署主脚本(Shell 入口)。
|
# PAM deployment main script (Shell entry).
|
||||||
|
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
@ -27,6 +27,16 @@ DOWNLOAD_PROGRESS_MSG=""
|
|||||||
DOWNLOAD_PROGRESS_MESSAGE=""
|
DOWNLOAD_PROGRESS_MESSAGE=""
|
||||||
DOWNLOAD_PROGRESS_RATE=""
|
DOWNLOAD_PROGRESS_RATE=""
|
||||||
DOWNLOAD_PROGRESS_RESPONSE=""
|
DOWNLOAD_PROGRESS_RESPONSE=""
|
||||||
|
UPGRADE_PROGRESS_STATUS=""
|
||||||
|
UPGRADE_PROGRESS_SUCCESS=""
|
||||||
|
UPGRADE_PROGRESS_STEP=""
|
||||||
|
UPGRADE_PROGRESS_MSG=""
|
||||||
|
UPGRADE_PROGRESS_MESSAGE=""
|
||||||
|
UPGRADE_PROGRESS_RATE=""
|
||||||
|
UPGRADE_PROGRESS_CODE=""
|
||||||
|
UPGRADE_PROGRESS_FINISH=""
|
||||||
|
UPGRADE_PROGRESS_LAST_MODIFY=""
|
||||||
|
UPGRADE_PROGRESS_RESPONSE=""
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
@ -437,6 +447,21 @@ print_progress_result() {
|
|||||||
result_line "MESSAGE" "$DOWNLOAD_PROGRESS_MESSAGE"
|
result_line "MESSAGE" "$DOWNLOAD_PROGRESS_MESSAGE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_upgrade_progress_result() {
|
||||||
|
local ip="$1"
|
||||||
|
result_line "ACTION" "poll-upgrade-progress"
|
||||||
|
result_line "IP" "$ip"
|
||||||
|
result_line "STEP" "$UPGRADE_PROGRESS_STEP"
|
||||||
|
result_line "MSG" "$UPGRADE_PROGRESS_MSG"
|
||||||
|
result_line "RATE_OF_PROGRESS" "$UPGRADE_PROGRESS_RATE"
|
||||||
|
result_line "STATUS" "$UPGRADE_PROGRESS_STATUS"
|
||||||
|
result_line "SUCCESS" "$UPGRADE_PROGRESS_SUCCESS"
|
||||||
|
result_line "CODE" "$UPGRADE_PROGRESS_CODE"
|
||||||
|
result_line "FINISH" "$UPGRADE_PROGRESS_FINISH"
|
||||||
|
result_line "LAST_MODIFY" "$UPGRADE_PROGRESS_LAST_MODIFY"
|
||||||
|
result_line "MESSAGE" "$UPGRADE_PROGRESS_MESSAGE"
|
||||||
|
}
|
||||||
|
|
||||||
json_value() {
|
json_value() {
|
||||||
local input="$1"
|
local input="$1"
|
||||||
local query="$2"
|
local query="$2"
|
||||||
@ -454,6 +479,15 @@ json_value() {
|
|||||||
'.message')
|
'.message')
|
||||||
json_get_string_by_key "$input" "message"
|
json_get_string_by_key "$input" "message"
|
||||||
;;
|
;;
|
||||||
|
'.code')
|
||||||
|
json_get_scalar_by_key "$input" "code"
|
||||||
|
;;
|
||||||
|
'.finish')
|
||||||
|
json_get_scalar_by_key "$input" "finish"
|
||||||
|
;;
|
||||||
|
'.lastModify')
|
||||||
|
json_get_scalar_by_key "$input" "lastModify"
|
||||||
|
;;
|
||||||
'.msg')
|
'.msg')
|
||||||
json_get_string_by_key "$input" "msg"
|
json_get_string_by_key "$input" "msg"
|
||||||
;;
|
;;
|
||||||
@ -503,6 +537,11 @@ json_compact() {
|
|||||||
printf '%s' "$input"
|
printf '%s' "$input"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regex_escape_ere() {
|
||||||
|
local text="$1"
|
||||||
|
printf '%s' "$text" | sed -E 's/[][(){}.^$*+?|\\]/\\&/g'
|
||||||
|
}
|
||||||
|
|
||||||
json_unescape_basic() {
|
json_unescape_basic() {
|
||||||
local value="$1"
|
local value="$1"
|
||||||
value="${value//\\\\/\\}"
|
value="${value//\\\\/\\}"
|
||||||
@ -518,9 +557,11 @@ json_get_string_by_key() {
|
|||||||
local key="$2"
|
local key="$2"
|
||||||
local compact
|
local compact
|
||||||
local value
|
local value
|
||||||
|
local pattern_key
|
||||||
|
|
||||||
compact="$(json_compact "$input")"
|
compact="$(json_compact "$input")"
|
||||||
value="$(printf '%s' "$compact" | sed -nE 's/.*"'$key'"[[:space:]]*:[[:space:]]*"(([^"\\]|\\.)*)".*/\1/p')"
|
pattern_key="$(regex_escape_ere "$key")"
|
||||||
|
value="$(printf '%s' "$compact" | sed -nE 's/.*"'$pattern_key'"[[:space:]]*:[[:space:]]*"(([^"\\]|\\.)*)".*/\1/p')"
|
||||||
[[ -n "$value" ]] && json_unescape_basic "$value"
|
[[ -n "$value" ]] && json_unescape_basic "$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,9 +570,11 @@ json_get_scalar_by_key() {
|
|||||||
local key="$2"
|
local key="$2"
|
||||||
local compact
|
local compact
|
||||||
local value
|
local value
|
||||||
|
local pattern_key
|
||||||
|
|
||||||
compact="$(json_compact "$input")"
|
compact="$(json_compact "$input")"
|
||||||
value="$(printf '%s' "$compact" | sed -nE 's/.*"'$key'"[[:space:]]*:[[:space:]]*([^,}]+).*/\1/p')"
|
pattern_key="$(regex_escape_ere "$key")"
|
||||||
|
value="$(printf '%s' "$compact" | sed -nE 's/.*"'$pattern_key'"[[:space:]]*:[[:space:]]*([^,}]+).*/\1/p')"
|
||||||
value="$(trim "$value")"
|
value="$(trim "$value")"
|
||||||
value="${value%\"}"
|
value="${value%\"}"
|
||||||
value="${value#\"}"
|
value="${value#\"}"
|
||||||
@ -544,12 +587,35 @@ json_get_nested_string_by_key() {
|
|||||||
local child_key="$3"
|
local child_key="$3"
|
||||||
local compact
|
local compact
|
||||||
local value
|
local value
|
||||||
|
local pattern_parent_key
|
||||||
|
local pattern_child_key
|
||||||
|
|
||||||
compact="$(json_compact "$input")"
|
compact="$(json_compact "$input")"
|
||||||
value="$(printf '%s' "$compact" | sed -nE 's/.*"'$parent_key'"[[:space:]]*:[[:space:]]*\{[^}]*"'$child_key'"[[:space:]]*:[[:space:]]*"(([^"\\]|\\.)*)".*/\1/p')"
|
pattern_parent_key="$(regex_escape_ere "$parent_key")"
|
||||||
|
pattern_child_key="$(regex_escape_ere "$child_key")"
|
||||||
|
value="$(printf '%s' "$compact" | sed -nE 's/.*"'$pattern_parent_key'"[[:space:]]*:[[:space:]]*\{[^}]*"'$pattern_child_key'"[[:space:]]*:[[:space:]]*"(([^"\\]|\\.)*)".*/\1/p')"
|
||||||
[[ -n "$value" ]] && json_unescape_basic "$value"
|
[[ -n "$value" ]] && json_unescape_basic "$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_get_nested_scalar_by_key() {
|
||||||
|
local input="$1"
|
||||||
|
local parent_key="$2"
|
||||||
|
local child_key="$3"
|
||||||
|
local compact
|
||||||
|
local value
|
||||||
|
local pattern_parent_key
|
||||||
|
local pattern_child_key
|
||||||
|
|
||||||
|
compact="$(json_compact "$input")"
|
||||||
|
pattern_parent_key="$(regex_escape_ere "$parent_key")"
|
||||||
|
pattern_child_key="$(regex_escape_ere "$child_key")"
|
||||||
|
value="$(printf '%s' "$compact" | sed -nE 's/.*"'$pattern_parent_key'"[[:space:]]*:[[:space:]]*\{[^}]*"'$pattern_child_key'"[[:space:]]*:[[:space:]]*([^,}]+).*/\1/p')"
|
||||||
|
value="$(trim "$value")"
|
||||||
|
value="${value%\"}"
|
||||||
|
value="${value#\"}"
|
||||||
|
printf '%s' "$value"
|
||||||
|
}
|
||||||
|
|
||||||
json_first_key() {
|
json_first_key() {
|
||||||
local input="$1"
|
local input="$1"
|
||||||
|
|
||||||
@ -572,6 +638,94 @@ json_array_items() {
|
|||||||
| sed -E 's/^[[:space:]]*"//; s/"[[:space:]]*$//; s/"[[:space:]]*,[[:space:]]*"/\n/g'
|
| sed -E 's/^[[:space:]]*"//; s/"[[:space:]]*$//; s/"[[:space:]]*,[[:space:]]*"/\n/g'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_scoped_value() {
|
||||||
|
local input="$1"
|
||||||
|
local scope_key="$2"
|
||||||
|
local query="$3"
|
||||||
|
local value=""
|
||||||
|
|
||||||
|
if [[ -n "$scope_key" ]]; then
|
||||||
|
case "$query" in
|
||||||
|
'.status')
|
||||||
|
value="$(json_get_nested_string_by_key "$input" "$scope_key" "status")"
|
||||||
|
;;
|
||||||
|
'.success')
|
||||||
|
value="$(json_get_nested_scalar_by_key "$input" "$scope_key" "success")"
|
||||||
|
;;
|
||||||
|
'.message')
|
||||||
|
value="$(json_get_nested_string_by_key "$input" "$scope_key" "message")"
|
||||||
|
;;
|
||||||
|
'.msg')
|
||||||
|
value="$(json_get_nested_string_by_key "$input" "$scope_key" "msg")"
|
||||||
|
;;
|
||||||
|
'.step')
|
||||||
|
value="$(json_get_nested_string_by_key "$input" "$scope_key" "step")"
|
||||||
|
;;
|
||||||
|
'.rateOfProgress')
|
||||||
|
value="$(json_get_nested_scalar_by_key "$input" "$scope_key" "rateOfProgress")"
|
||||||
|
;;
|
||||||
|
'.progress')
|
||||||
|
value="$(json_get_nested_scalar_by_key "$input" "$scope_key" "progress")"
|
||||||
|
;;
|
||||||
|
'.percent')
|
||||||
|
value="$(json_get_nested_scalar_by_key "$input" "$scope_key" "percent")"
|
||||||
|
;;
|
||||||
|
'.code')
|
||||||
|
value="$(json_get_nested_scalar_by_key "$input" "$scope_key" "code")"
|
||||||
|
;;
|
||||||
|
'.finish')
|
||||||
|
value="$(json_get_nested_scalar_by_key "$input" "$scope_key" "finish")"
|
||||||
|
;;
|
||||||
|
'.lastModify')
|
||||||
|
value="$(json_get_nested_scalar_by_key "$input" "$scope_key" "lastModify")"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$value" ]]; then
|
||||||
|
printf '%s' "$value"
|
||||||
|
else
|
||||||
|
json_value "$input" "$query"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
response_message() {
|
||||||
|
local input="$1"
|
||||||
|
local message
|
||||||
|
|
||||||
|
message="$(json_value "$input" '.message')"
|
||||||
|
[[ -z "$message" ]] && message="$(json_value "$input" '.msg')"
|
||||||
|
printf '%s' "$message"
|
||||||
|
}
|
||||||
|
|
||||||
|
response_indicates_failure() {
|
||||||
|
local input="$1"
|
||||||
|
local success_flag
|
||||||
|
local code_value
|
||||||
|
local status
|
||||||
|
local message
|
||||||
|
local error_regex='[Ff]ail|[Ee]rror'
|
||||||
|
|
||||||
|
success_flag="$(json_value "$input" '.success')"
|
||||||
|
code_value="$(json_value "$input" '.code')"
|
||||||
|
status="$(json_value "$input" '.status')"
|
||||||
|
message="$(response_message "$input")"
|
||||||
|
|
||||||
|
if [[ "$success_flag" == "false" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$code_value" && "$code_value" != "0" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${status} ${message}" =~ $error_regex ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
http_request() {
|
http_request() {
|
||||||
local method="$1"
|
local method="$1"
|
||||||
local url="$2"
|
local url="$2"
|
||||||
@ -899,10 +1053,113 @@ download_cloud_to_node() {
|
|||||||
poll_download_progress
|
poll_download_progress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
poll_upgrade_progress() {
|
||||||
|
local ip="$1"
|
||||||
|
local progress_url="${HOME_BASE_URL}/node-proxy/${AIRPORT_CODE}/api/mcp/version/upgrade/progress?applicationName=${APP_NAME}&moduleName=${MODULE_NAME}&airportCode=${AIRPORT_CODE}&versionNumber=${VERSION_NUMBER}"
|
||||||
|
local attempt=0
|
||||||
|
local max_attempts=600
|
||||||
|
local error_regex='[Ff]ail|[Ee]rror'
|
||||||
|
|
||||||
|
UPGRADE_PROGRESS_STATUS=""
|
||||||
|
UPGRADE_PROGRESS_SUCCESS=""
|
||||||
|
UPGRADE_PROGRESS_STEP=""
|
||||||
|
UPGRADE_PROGRESS_MSG=""
|
||||||
|
UPGRADE_PROGRESS_MESSAGE=""
|
||||||
|
UPGRADE_PROGRESS_RATE=""
|
||||||
|
UPGRADE_PROGRESS_CODE=""
|
||||||
|
UPGRADE_PROGRESS_FINISH=""
|
||||||
|
UPGRADE_PROGRESS_LAST_MODIFY=""
|
||||||
|
UPGRADE_PROGRESS_RESPONSE=""
|
||||||
|
|
||||||
|
while (( attempt < max_attempts )); do
|
||||||
|
local response
|
||||||
|
response=$(http_request "GET" "$progress_url" "" "" "Target-Node: ${NODE_URL}") || return 1
|
||||||
|
|
||||||
|
local status
|
||||||
|
status="$(json_scoped_value "$response" "$ip" '.status')"
|
||||||
|
local success_flag
|
||||||
|
success_flag="$(json_scoped_value "$response" "$ip" '.success')"
|
||||||
|
local step_value
|
||||||
|
step_value="$(json_scoped_value "$response" "$ip" '.step')"
|
||||||
|
local msg_value
|
||||||
|
msg_value="$(json_scoped_value "$response" "$ip" '.msg')"
|
||||||
|
local message
|
||||||
|
message="$(json_scoped_value "$response" "$ip" '.message')"
|
||||||
|
local progress_value
|
||||||
|
progress_value="$(json_scoped_value "$response" "$ip" '.rateOfProgress')"
|
||||||
|
[[ -z "$progress_value" ]] && progress_value="$(json_scoped_value "$response" "$ip" '.progress')"
|
||||||
|
[[ -z "$progress_value" ]] && progress_value="$(json_scoped_value "$response" "$ip" '.percent')"
|
||||||
|
local code_value
|
||||||
|
code_value="$(json_scoped_value "$response" "$ip" '.code')"
|
||||||
|
local finish_value
|
||||||
|
finish_value="$(json_scoped_value "$response" "$ip" '.finish')"
|
||||||
|
local last_modify_value
|
||||||
|
last_modify_value="$(json_scoped_value "$response" "$ip" '.lastModify')"
|
||||||
|
[[ -z "$message" ]] && message="$msg_value"
|
||||||
|
|
||||||
|
UPGRADE_PROGRESS_STATUS="$status"
|
||||||
|
UPGRADE_PROGRESS_SUCCESS="$success_flag"
|
||||||
|
UPGRADE_PROGRESS_STEP="$step_value"
|
||||||
|
UPGRADE_PROGRESS_MSG="$msg_value"
|
||||||
|
UPGRADE_PROGRESS_MESSAGE="$message"
|
||||||
|
UPGRADE_PROGRESS_RATE="$progress_value"
|
||||||
|
UPGRADE_PROGRESS_CODE="$code_value"
|
||||||
|
UPGRADE_PROGRESS_FINISH="$finish_value"
|
||||||
|
UPGRADE_PROGRESS_LAST_MODIFY="$last_modify_value"
|
||||||
|
UPGRADE_PROGRESS_RESPONSE="$response"
|
||||||
|
|
||||||
|
if [[ -n "$msg_value" || -n "$step_value" || -n "$progress_value" || -n "$status" || -n "$success_flag" || -n "$message" || -n "$code_value" || -n "$finish_value" || -n "$last_modify_value" ]]; then
|
||||||
|
local -a progress_parts=()
|
||||||
|
progress_parts+=("ip=${ip}")
|
||||||
|
[[ -n "$msg_value" ]] && progress_parts+=("msg=${msg_value}")
|
||||||
|
[[ -n "$step_value" ]] && progress_parts+=("step=${step_value}")
|
||||||
|
[[ -n "$progress_value" ]] && progress_parts+=("rateOfProgress=${progress_value}")
|
||||||
|
[[ -n "$code_value" ]] && progress_parts+=("code=${code_value}")
|
||||||
|
[[ -n "$finish_value" ]] && progress_parts+=("finish=${finish_value}")
|
||||||
|
[[ -n "$status" ]] && progress_parts+=("status=${status}")
|
||||||
|
[[ -n "$success_flag" ]] && progress_parts+=("success=${success_flag}")
|
||||||
|
[[ -n "$last_modify_value" ]] && progress_parts+=("lastModify=${last_modify_value}")
|
||||||
|
[[ -n "$message" && "$message" != "$msg_value" ]] && progress_parts+=("message=${message}")
|
||||||
|
log_info "Step 3.4a: async push progress -> ${progress_parts[*]}"
|
||||||
|
else
|
||||||
|
log_info "Step 3.4a: async push progress polling... ip=${ip} ($((attempt + 1))/${max_attempts})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$step_value" == "DONE" || "$finish_value" == "true" || "$status" == "completed" || "$success_flag" == "true" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$msg_value" == "success" && "$progress_value" == "100" ]] && [[ -z "$code_value" || "$code_value" == "0" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$code_value" && "$code_value" != "0" ]]; then
|
||||||
|
[[ -z "$message" ]] && message="$msg_value"
|
||||||
|
[[ -z "$message" ]] && message="$step_value"
|
||||||
|
[[ -z "$message" ]] && message="code=${code_value}"
|
||||||
|
log_error "Node push failed: ip=${ip}, message=${message}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${step_value} ${message} ${msg_value} ${status}" =~ $error_regex ]]; then
|
||||||
|
[[ -z "$message" ]] && message="$step_value"
|
||||||
|
[[ -z "$message" ]] && message="$msg_value"
|
||||||
|
log_error "Node push failed: ip=${ip}, message=${message}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
log_error "Node push timed out: ip=${ip}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
upgrade_ip() {
|
upgrade_ip() {
|
||||||
local ip="$1"
|
local ip="$1"
|
||||||
http_request "POST" \
|
http_request "POST" \
|
||||||
"${HOME_BASE_URL}/node-proxy/${AIRPORT_CODE}/api/mcp/version/upgrade?airportCode=${AIRPORT_CODE}&targetIp=${ip}&applicationName=${APP_NAME}&moduleName=${MODULE_NAME}&versionNumber=${VERSION_NUMBER}&action=${ACTION_TYPE}&autoStart=false&timeOut=${TIMEOUT}" \
|
"${HOME_BASE_URL}/node-proxy/${AIRPORT_CODE}/api/mcp/version/upgrade?airportCode=${AIRPORT_CODE}&targetIp=${ip}&applicationName=${APP_NAME}&moduleName=${MODULE_NAME}&versionNumber=${VERSION_NUMBER}&action=${ACTION_TYPE}&autoStart=false&timeOut=0" \
|
||||||
"" \
|
"" \
|
||||||
"" \
|
"" \
|
||||||
"Target-Node: ${NODE_URL}"
|
"Target-Node: ${NODE_URL}"
|
||||||
@ -1130,15 +1387,31 @@ run_action() {
|
|||||||
print_progress_result "download-cloud-to-node"
|
print_progress_result "download-cloud-to-node"
|
||||||
result_line "RESULT" "DONE"
|
result_line "RESULT" "DONE"
|
||||||
;;
|
;;
|
||||||
|
poll-upgrade-progress)
|
||||||
|
require_ip_arg "$ip" || return 1
|
||||||
|
run_flow_step "get_token" get_token || return 1
|
||||||
|
run_flow_step "get_node_url" get_node_url || return 1
|
||||||
|
run_flow_step "poll_upgrade_progress[${ip}]" poll_upgrade_progress "$ip" || return 1
|
||||||
|
print_upgrade_progress_result "$ip"
|
||||||
|
;;
|
||||||
upgrade-ip)
|
upgrade-ip)
|
||||||
require_ip_arg "$ip" || return 1
|
require_ip_arg "$ip" || return 1
|
||||||
run_flow_step "get_token" get_token || return 1
|
run_flow_step "get_token" get_token || return 1
|
||||||
run_flow_step "get_node_url" get_node_url || return 1
|
run_flow_step "get_node_url" get_node_url || return 1
|
||||||
run_flow_capture response "upgrade_ip[${ip}]" upgrade_ip "$ip" || return 1
|
run_flow_capture response "upgrade_ip[${ip}]" upgrade_ip "$ip" || return 1
|
||||||
|
if response_indicates_failure "$response"; then
|
||||||
|
local message
|
||||||
|
message="$(response_message "$response")"
|
||||||
|
[[ -z "$message" ]] && message="Upgrade task creation failed"
|
||||||
|
log_error "Upgrade task creation failed: ip=${ip}, message=${message}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
result_line "ACTION" "upgrade-ip"
|
result_line "ACTION" "upgrade-ip"
|
||||||
result_line "IP" "$ip"
|
result_line "IP" "$ip"
|
||||||
|
result_line "TIME_OUT" "0"
|
||||||
|
result_line "RESULT" "TASK_CREATED"
|
||||||
result_line "SUCCESS" "$(json_value "$response" '.success')"
|
result_line "SUCCESS" "$(json_value "$response" '.success')"
|
||||||
result_line "MESSAGE" "$(json_value "$response" '.message')"
|
result_line "MESSAGE" "$(response_message "$response")"
|
||||||
result_line "RAW_RESPONSE" "$(sanitize_field "$response")"
|
result_line "RAW_RESPONSE" "$(sanitize_field "$response")"
|
||||||
;;
|
;;
|
||||||
start-ip)
|
start-ip)
|
||||||
@ -1237,10 +1510,10 @@ deploy_one_ip() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$(json_value "$upgrade_response" '.success')" != "true" ]]; then
|
if response_indicates_failure "$upgrade_response"; then
|
||||||
local message
|
local message
|
||||||
message="$(json_value "$upgrade_response" '.message')"
|
message="$(response_message "$upgrade_response")"
|
||||||
[[ -z "$message" ]] && message="Upgrade failed"
|
[[ -z "$message" ]] && message="Upgrade task creation failed"
|
||||||
local rollback_result
|
local rollback_result
|
||||||
rollback_result="$(pending_rollback_status "$ip" "UPGRADE" "$message" "false")"
|
rollback_result="$(pending_rollback_status "$ip" "UPGRADE" "$message" "false")"
|
||||||
local log_file=""
|
local log_file=""
|
||||||
@ -1249,6 +1522,20 @@ deploy_one_ip() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! run_flow_step "poll_upgrade_progress[${ip}]" poll_upgrade_progress "$ip"; then
|
||||||
|
local message
|
||||||
|
message="$UPGRADE_PROGRESS_MESSAGE"
|
||||||
|
[[ -z "$message" ]] && message="$UPGRADE_PROGRESS_MSG"
|
||||||
|
[[ -z "$message" ]] && message="$UPGRADE_PROGRESS_STEP"
|
||||||
|
[[ -z "$message" ]] && message="Upgrade progress polling failed"
|
||||||
|
local rollback_result
|
||||||
|
rollback_result="$(pending_rollback_status "$ip" "UPGRADE_PROGRESS" "$message" "false")"
|
||||||
|
local log_file=""
|
||||||
|
run_flow_capture log_file "download_log[${ip}]" download_log "$ip" || true
|
||||||
|
add_result "$ip" "FAILED" "UPGRADE_PROGRESS" "$message" "$rollback_result" "$log_file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
if ! run_flow_step "start_application[${ip}]" start_application "$ip"; then
|
if ! run_flow_step "start_application[${ip}]" start_application "$ip"; then
|
||||||
local rollback_result
|
local rollback_result
|
||||||
rollback_result="$(pending_rollback_status "$ip" "START" "Application start failed" "true")"
|
rollback_result="$(pending_rollback_status "$ip" "START" "Application start failed" "true")"
|
||||||
|
|||||||
@ -203,13 +203,19 @@ function Invoke-PamFullTest {
|
|||||||
foreach ($ip in $testIps) {
|
foreach ($ip in $testIps) {
|
||||||
try {
|
try {
|
||||||
$upgradeResponse = Invoke-UpgradeRequest -Config $config -Token $token -NodeUrl $nodeUrl -Ip $ip
|
$upgradeResponse = Invoke-UpgradeRequest -Config $config -Token $token -NodeUrl $nodeUrl -Ip $ip
|
||||||
$upgradeSuccess = Get-ResponseValue -Response $upgradeResponse -Candidates @('success')
|
if (Test-ResponseFailure -Response $upgradeResponse) {
|
||||||
$upgradeMessage = Get-ResponseValue -Response $upgradeResponse -Candidates @('message')
|
$upgradeMessage = Get-PrimaryResponseMessage -Response $upgradeResponse
|
||||||
if ($upgradeSuccess -eq 'true') {
|
if (-not $upgradeMessage) { $upgradeMessage = 'task creation failed' }
|
||||||
Add-TestResult -Results $results -Step "UPGRADE [$ip]" -Status 'PASS' -Detail 'success=true'
|
|
||||||
} else {
|
|
||||||
if (-not $upgradeMessage) { $upgradeMessage = 'success != true' }
|
|
||||||
Add-TestResult -Results $results -Step "UPGRADE [$ip]" -Status 'FAIL' -Detail $upgradeMessage
|
Add-TestResult -Results $results -Step "UPGRADE [$ip]" -Status 'FAIL' -Detail $upgradeMessage
|
||||||
|
} else {
|
||||||
|
Add-TestResult -Results $results -Step "UPGRADE [$ip]" -Status 'PASS' -Detail 'task created'
|
||||||
|
try {
|
||||||
|
Wait-UpgradeProgress -Config $config -Token $token -NodeUrl $nodeUrl -Ip $ip
|
||||||
|
Add-TestResult -Results $results -Step "UPGRADE_PROGRESS [$ip]" -Status 'PASS' -Detail ("rateOfProgress={0}" -f $script:UpgradeProgressState.RateOfProgress)
|
||||||
|
} catch {
|
||||||
|
$upgradeMessage = Get-ProgressStateMessage -State $script:UpgradeProgressState -DefaultMessage 'progress polling failed'
|
||||||
|
Add-TestResult -Results $results -Step "UPGRADE_PROGRESS [$ip]" -Status 'FAIL' -Detail $upgradeMessage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
Add-TestResult -Results $results -Step "UPGRADE [$ip]" -Status 'FAIL' -Detail $_.Exception.Message
|
Add-TestResult -Results $results -Step "UPGRADE [$ip]" -Status 'FAIL' -Detail $_.Exception.Message
|
||||||
|
|||||||
@ -207,13 +207,20 @@ run_full_test() {
|
|||||||
local rollback_result=""
|
local rollback_result=""
|
||||||
|
|
||||||
if upgrade_response="$(upgrade_ip "$ip")"; then
|
if upgrade_response="$(upgrade_ip "$ip")"; then
|
||||||
upgrade_success="$(json_value "$upgrade_response" '.success')"
|
if response_indicates_failure "$upgrade_response"; then
|
||||||
upgrade_message="$(json_value "$upgrade_response" '.message')"
|
upgrade_message="$(response_message "$upgrade_response")"
|
||||||
if [[ "$upgrade_success" == "true" ]]; then
|
[[ -z "$upgrade_message" ]] && upgrade_message="task creation failed"
|
||||||
add_test_result "UPGRADE [$ip]" "PASS" "success=true"
|
|
||||||
else
|
|
||||||
[[ -z "$upgrade_message" ]] && upgrade_message="success != true"
|
|
||||||
add_test_result "UPGRADE [$ip]" "FAIL" "$upgrade_message"
|
add_test_result "UPGRADE [$ip]" "FAIL" "$upgrade_message"
|
||||||
|
else
|
||||||
|
add_test_result "UPGRADE [$ip]" "PASS" "task created"
|
||||||
|
if poll_upgrade_progress "$ip"; then
|
||||||
|
add_test_result "UPGRADE_PROGRESS [$ip]" "PASS" "rateOfProgress=${UPGRADE_PROGRESS_RATE}"
|
||||||
|
else
|
||||||
|
upgrade_message="$UPGRADE_PROGRESS_MESSAGE"
|
||||||
|
[[ -z "$upgrade_message" ]] && upgrade_message="$UPGRADE_PROGRESS_MSG"
|
||||||
|
[[ -z "$upgrade_message" ]] && upgrade_message="progress polling failed"
|
||||||
|
add_test_result "UPGRADE_PROGRESS [$ip]" "FAIL" "$upgrade_message"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
add_test_result "UPGRADE [$ip]" "FAIL" "request failed"
|
add_test_result "UPGRADE [$ip]" "FAIL" "request failed"
|
||||||
|
|||||||
@ -52,6 +52,7 @@
|
|||||||
- `/api/mcp/version/upgrade` 使用 query 参数,不再使用 body 表单。
|
- `/api/mcp/version/upgrade` 使用 query 参数,不再使用 body 表单。
|
||||||
- `/api/mcp/version/upgrade/start-stop` 使用 query 参数,不再使用 body 表单,且参数名使用 `runStart`。
|
- `/api/mcp/version/upgrade/start-stop` 使用 query 参数,不再使用 body 表单,且参数名使用 `runStart`。
|
||||||
- `download-cloud` 固定传 `timeOut=0`,仅用于创建下载任务;后续进度通过 `download-cloud/progress` 异步查询。
|
- `download-cloud` 固定传 `timeOut=0`,仅用于创建下载任务;后续进度通过 `download-cloud/progress` 异步查询。
|
||||||
|
- `upgrade-ip` 固定传 `timeOut=0`,仅用于创建推送任务;后续进度通过 `upgrade/progress` 异步查询,对外新增 `poll-upgrade-progress` action。
|
||||||
- Shell 侧 action 调用现在支持复用统一的 trace 文件,不再要求每次 action 各自生成单独的 trace 日志。
|
- Shell 侧 action 调用现在支持复用统一的 trace 文件,不再要求每次 action 各自生成单独的 trace 日志。
|
||||||
- `log-download` 下载结果按 zip 压缩包保存,不再按纯文本日志处理。
|
- `log-download` 下载结果按 zip 压缩包保存,不再按纯文本日志处理。
|
||||||
|
|
||||||
@ -75,10 +76,11 @@
|
|||||||
7. `api/mcp/version/upgrade/download-cloud`
|
7. `api/mcp/version/upgrade/download-cloud`
|
||||||
8. `api/mcp/version/upgrade/download-cloud/progress`
|
8. `api/mcp/version/upgrade/download-cloud/progress`
|
||||||
9. `api/mcp/version/upgrade`
|
9. `api/mcp/version/upgrade`
|
||||||
10. `api/mcp/version/upgrade/start-stop`
|
10. `api/mcp/version/upgrade/progress`
|
||||||
11. `api/mcp/version/upgrade/verify`
|
11. `api/mcp/version/upgrade/start-stop`
|
||||||
12. `api/mcp/version/upgrade/log-download`
|
12. `api/mcp/version/upgrade/verify`
|
||||||
13. `api/mcp/version/upgrade/rollback`
|
13. `api/mcp/version/upgrade/log-download`
|
||||||
|
14. `api/mcp/version/upgrade/rollback`
|
||||||
|
|
||||||
正式部署脚本当前不会自动执行 `rollback`,而是输出待确认状态;需要实际回滚时,应由 Agent 与用户确认后,再调用手动回滚入口:
|
正式部署脚本当前不会自动执行 `rollback`,而是输出待确认状态;需要实际回滚时,应由 Agent 与用户确认后,再调用手动回滚入口:
|
||||||
|
|
||||||
@ -95,11 +97,13 @@ powershell -File .\deploy.ps1 -ConfigPath .\config.txt -RollbackIp 192.168.1.10
|
|||||||
```bash
|
```bash
|
||||||
bash ./deploy.sh --config ./config.txt --action get-online-ips
|
bash ./deploy.sh --config ./config.txt --action get-online-ips
|
||||||
bash ./deploy.sh --config ./config.txt --action upgrade-ip --ip 192.168.1.10
|
bash ./deploy.sh --config ./config.txt --action upgrade-ip --ip 192.168.1.10
|
||||||
|
bash ./deploy.sh --config ./config.txt --action poll-upgrade-progress --ip 192.168.1.10
|
||||||
```
|
```
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell -File .\deploy.ps1 -ConfigPath .\config.txt -Action GetOnlineIps
|
powershell -File .\deploy.ps1 -ConfigPath .\config.txt -Action GetOnlineIps
|
||||||
powershell -File .\deploy.ps1 -ConfigPath .\config.txt -Action UpgradeIp -Ip 192.168.1.10
|
powershell -File .\deploy.ps1 -ConfigPath .\config.txt -Action UpgradeIp -Ip 192.168.1.10
|
||||||
|
powershell -File .\deploy.ps1 -ConfigPath .\config.txt -Action poll-upgrade-progress -Ip 192.168.1.10
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 当前运行方式
|
## 3. 当前运行方式
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user