198 lines
5.1 KiB
PowerShell
198 lines
5.1 KiB
PowerShell
param(
|
||
[Parameter(Position = 0)]
|
||
[string]$Action = "help"
|
||
)
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
|
||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||
$rootDir = (Resolve-Path (Join-Path $scriptDir "..")).Path
|
||
$exePath = Join-Path $rootDir "managerd.exe"
|
||
$configPath = Join-Path $rootDir "managerd.json"
|
||
$logPath = Join-Path $rootDir "managerd.local.log"
|
||
$errLogPath = Join-Path $rootDir "managerd.local.err.log"
|
||
|
||
function Write-Info {
|
||
param([string]$Message)
|
||
Write-Host "[managerd] $Message"
|
||
}
|
||
|
||
function Get-ManagerdProcess {
|
||
$all = Get-CimInstance Win32_Process -Filter "name = 'managerd.exe'"
|
||
$matched = $all | Where-Object { $_.ExecutablePath -eq $exePath }
|
||
return $matched | Select-Object -First 1
|
||
}
|
||
|
||
function Get-HealthInfo {
|
||
$listen = "127.0.0.1:18080"
|
||
if (Test-Path $configPath) {
|
||
$cfg = Get-Content -Raw $configPath | ConvertFrom-Json
|
||
if ($cfg.listen -and -not [string]::IsNullOrWhiteSpace([string]$cfg.listen)) {
|
||
$listen = [string]$cfg.listen
|
||
}
|
||
}
|
||
|
||
$parts = $listen.Split(":")
|
||
$hostName = $parts[0]
|
||
$port = $parts[-1]
|
||
if ([string]::IsNullOrWhiteSpace($hostName) -or $hostName -in @("0.0.0.0", "::")) {
|
||
$hostName = "127.0.0.1"
|
||
}
|
||
|
||
$url = "http://{0}:{1}/health" -f $hostName, $port
|
||
try {
|
||
$resp = Invoke-WebRequest -UseBasicParsing $url -TimeoutSec 3
|
||
if ($resp.StatusCode -eq 200 -and $resp.Content -match "ok") {
|
||
return [pscustomobject]@{ State = "ok"; Url = $url }
|
||
}
|
||
return [pscustomobject]@{ State = "bad"; Url = $url }
|
||
} catch {
|
||
return [pscustomobject]@{ State = "down"; Url = $url }
|
||
}
|
||
}
|
||
|
||
function Wait-ForHealthOk {
|
||
param([int]$Retries = 8)
|
||
for ($i = 0; $i -lt $Retries; $i++) {
|
||
$health = Get-HealthInfo
|
||
if ($health.State -eq "ok") {
|
||
return $true
|
||
}
|
||
Start-Sleep -Seconds 1
|
||
}
|
||
return $false
|
||
}
|
||
|
||
function Wait-ForStop {
|
||
param([int]$Retries = 8)
|
||
for ($i = 0; $i -lt $Retries; $i++) {
|
||
if (-not (Get-ManagerdProcess)) {
|
||
return $true
|
||
}
|
||
Start-Sleep -Seconds 1
|
||
}
|
||
return $false
|
||
}
|
||
|
||
function Show-Health {
|
||
$health = Get-HealthInfo
|
||
switch ($health.State) {
|
||
"ok" { Write-Info ("健康检查: ok ({0})" -f $health.Url) }
|
||
"bad" { Write-Info ("健康检查: 响应异常 ({0})" -f $health.Url) }
|
||
default { Write-Info ("健康检查: down ({0})" -f $health.Url) }
|
||
}
|
||
}
|
||
|
||
function Invoke-Build {
|
||
Write-Info "编译 managerd.exe ..."
|
||
Push-Location $rootDir
|
||
try {
|
||
& go build -o $exePath .\cmd\managerd
|
||
if ($LASTEXITCODE -ne 0) {
|
||
throw "go build failed with exit code $LASTEXITCODE"
|
||
}
|
||
} finally {
|
||
Pop-Location
|
||
}
|
||
Write-Info "编译完成: $exePath"
|
||
}
|
||
|
||
function Invoke-Start {
|
||
if (-not (Test-Path $exePath)) {
|
||
throw "未找到 managerd.exe,请先执行 build"
|
||
}
|
||
|
||
$proc = Get-ManagerdProcess
|
||
if ($proc) {
|
||
Write-Info ("已在运行,PID={0}" -f $proc.ProcessId)
|
||
Show-Health
|
||
return
|
||
}
|
||
|
||
Write-Info "启动 managerd.exe ..."
|
||
Start-Process -FilePath $exePath `
|
||
-ArgumentList $configPath `
|
||
-WorkingDirectory $rootDir `
|
||
-RedirectStandardOutput $logPath `
|
||
-RedirectStandardError $errLogPath `
|
||
-WindowStyle Hidden
|
||
|
||
$null = Wait-ForHealthOk
|
||
$proc = Get-ManagerdProcess
|
||
if (-not $proc) {
|
||
throw "进程未启动成功"
|
||
}
|
||
|
||
Write-Info ("已启动,PID={0}" -f $proc.ProcessId)
|
||
Show-Health
|
||
}
|
||
|
||
function Invoke-Stop {
|
||
$proc = Get-ManagerdProcess
|
||
if (-not $proc) {
|
||
Write-Info "当前未运行"
|
||
return
|
||
}
|
||
|
||
Write-Info ("停止 managerd.exe,PID={0} ..." -f $proc.ProcessId)
|
||
Stop-Process -Id $proc.ProcessId -Force
|
||
if (-not (Wait-ForStop)) {
|
||
throw "进程停止超时"
|
||
}
|
||
Write-Info "已停止"
|
||
}
|
||
|
||
function Invoke-Restart {
|
||
Invoke-Stop
|
||
Invoke-Start
|
||
}
|
||
|
||
function Show-Status {
|
||
$proc = Get-ManagerdProcess
|
||
if ($proc) {
|
||
Write-Info ("进程状态: running (PID={0})" -f $proc.ProcessId)
|
||
} else {
|
||
Write-Info "进程状态: stopped"
|
||
}
|
||
Show-Health
|
||
}
|
||
|
||
function Show-Usage {
|
||
@(
|
||
"用法:"
|
||
" managerd.bat build"
|
||
" managerd.bat start"
|
||
" managerd.bat stop"
|
||
" managerd.bat restart"
|
||
" managerd.bat status"
|
||
" managerd.bat help"
|
||
""
|
||
"说明:"
|
||
" build 编译 .\cmd\managerd 到 managerd.exe"
|
||
" start 启动现有 managerd.exe,并做健康检查"
|
||
" stop 停止当前仓库对应的 managerd.exe"
|
||
" restart 先 stop 再 start"
|
||
" status 查看进程状态与 /health"
|
||
" help 显示帮助"
|
||
) | ForEach-Object { Write-Host $_ }
|
||
}
|
||
|
||
try {
|
||
switch ($Action.ToLowerInvariant()) {
|
||
"build" { Invoke-Build }
|
||
"start" { Invoke-Start }
|
||
"stop" { Invoke-Stop }
|
||
"restart" { Invoke-Restart }
|
||
"status" { Show-Status }
|
||
"help" { Show-Usage }
|
||
default {
|
||
Write-Host "未知动作: $Action"
|
||
Show-Usage
|
||
exit 1
|
||
}
|
||
}
|
||
} catch {
|
||
Write-Error $_
|
||
exit 1
|
||
}
|