127 lines
5.1 KiB
PowerShell
127 lines
5.1 KiB
PowerShell
# Install test agent on server and cut over Nginx wecom callback to 8910
|
|
$ErrorActionPreference = "Stop"
|
|
$ReleaseId = "scaffold-agent-" + (Get-Date -Format "yyyyMMdd-HHmmss")
|
|
$Root = "E:\wwwroot"
|
|
$Release = Join-Path $Root "agent\releases\$ReleaseId"
|
|
$AgentCurrent = Join-Path $Root "agent\current"
|
|
$Python = "C:\yutongda\tools\Python312\python.exe"
|
|
$Nginx = "C:\nginx-1.18.0"
|
|
$Zip = "C:\Users\ytd_extdev_0903\incoming\agent-release.zip"
|
|
$EnvSrc = "C:\Users\ytd_extdev_0903\incoming\env.file"
|
|
$AiConfNew = "C:\Users\ytd_extdev_0903\incoming\ai.conf.cutover-8910"
|
|
|
|
Write-Output "=== create dirs ==="
|
|
New-Item -ItemType Directory -Force -Path $Release, "$Root\logs", "$Root\ops", "$Root\admin\releases", "$Root\agent\releases", "C:\Users\ytd_extdev_0903\incoming" | Out-Null
|
|
if (-not (Test-Path $Zip)) { throw "missing $Zip" }
|
|
if (-not (Test-Path $Python)) { throw "missing $Python" }
|
|
|
|
Write-Output "=== expand release ==="
|
|
Expand-Archive -Path $Zip -DestinationPath $Release -Force
|
|
$AgentHome = Join-Path $Release "agent"
|
|
if (-not (Test-Path (Join-Path $AgentHome "agent\http_app.py"))) {
|
|
throw "http_app.py not found under $AgentHome"
|
|
}
|
|
Write-Output "AgentHome=$AgentHome"
|
|
|
|
Write-Output "=== env ==="
|
|
Copy-Item $EnvSrc (Join-Path $Root ".env") -Force
|
|
Copy-Item $EnvSrc (Join-Path $Release ".env") -Force
|
|
Copy-Item $EnvSrc (Join-Path $AgentHome ".env") -Force
|
|
|
|
Write-Output "=== venv + pip ==="
|
|
$venvDir = Join-Path $AgentHome ".venv"
|
|
$venvPy = Join-Path $venvDir "Scripts\python.exe"
|
|
$venvPip = Join-Path $venvDir "Scripts\pip.exe"
|
|
if (-not (Test-Path $venvPy)) {
|
|
& $Python -m venv $venvDir
|
|
if ($LASTEXITCODE -ne 0) { throw "venv failed" }
|
|
}
|
|
& $venvPip install --default-timeout=180 -i https://pypi.tuna.tsinghua.edu.cn/simple -r (Join-Path $AgentHome "requirements.txt")
|
|
if ($LASTEXITCODE -ne 0) { throw "pip install failed" }
|
|
|
|
Write-Output "=== switch agent\\current junction ==="
|
|
if (Test-Path $AgentCurrent) {
|
|
cmd /c "rmdir `"$AgentCurrent`"" | Out-Null
|
|
if (Test-Path $AgentCurrent) { Remove-Item $AgentCurrent -Recurse -Force }
|
|
}
|
|
cmd /c "mklink /J `"$AgentCurrent`" `"$AgentHome`""
|
|
if (-not (Test-Path (Join-Path $AgentCurrent "agent\http_app.py"))) { throw "agent current missing http_app" }
|
|
|
|
Write-Output "=== stop old listener 8910 ==="
|
|
Get-NetTCPConnection -LocalPort 8910 -ErrorAction SilentlyContinue |
|
|
Select-Object -ExpandProperty OwningProcess -Unique |
|
|
ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }
|
|
Start-Sleep -Seconds 1
|
|
|
|
Write-Output "=== write run-agent-http.cmd ==="
|
|
$runCmd = @"
|
|
@echo off
|
|
cd /d "$AgentCurrent"
|
|
set YTD_ENV=test
|
|
set AGENT_HTTP_PORT=8910
|
|
:loop
|
|
"$AgentCurrent\.venv\Scripts\python.exe" -m agent.http_app >> "$Root\logs\agent-http.out.log" 2>> "$Root\logs\agent-http.err.log"
|
|
echo agent exited, restart in 3s >> "$Root\logs\agent-http.err.log"
|
|
timeout /t 3 /nobreak >nul
|
|
goto loop
|
|
"@
|
|
Set-Content -Path (Join-Path $Root "ops\run-agent-http.cmd") -Value $runCmd -Encoding ASCII
|
|
|
|
Write-Output "=== start agent via WMI ==="
|
|
$wmi = Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{
|
|
CommandLine = "cmd.exe /c `"$(Join-Path $Root 'ops\run-agent-http.cmd')`""
|
|
}
|
|
Write-Output "WMI_Return=$($wmi.ReturnValue) ProcessId=$($wmi.ProcessId)"
|
|
Start-Sleep -Seconds 6
|
|
try {
|
|
$h = Invoke-WebRequest -Uri "http://127.0.0.1:8910/health" -UseBasicParsing -TimeoutSec 8
|
|
Write-Output "HEALTH=$($h.StatusCode) $($h.Content)"
|
|
} catch {
|
|
Get-Content (Join-Path $Root "logs\agent-http.err.log") -Tail 50 -ErrorAction SilentlyContinue
|
|
throw "agent health failed: $_"
|
|
}
|
|
|
|
$listenPid = 0
|
|
$listen = Get-NetTCPConnection -LocalPort 8910 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
if ($listen) { $listenPid = $listen.OwningProcess }
|
|
|
|
Write-Output "=== pointer ==="
|
|
@{
|
|
root = $Root
|
|
releaseId = $ReleaseId
|
|
releaseRoot = $Release
|
|
agentHome = $AgentHome
|
|
agentCurrent = $AgentCurrent
|
|
adminCurrent = (Join-Path $Root "admin\current")
|
|
pid = $listenPid
|
|
updatedAt = (Get-Date).ToString("o")
|
|
} | ConvertTo-Json | Set-Content (Join-Path $Root "ops\active-release.json") -Encoding UTF8
|
|
|
|
Write-Output "=== nginx cutover (no BOM, hard restart) ==="
|
|
$ai = Join-Path $Nginx "myconf\ai.conf"
|
|
$bak = Join-Path $Nginx ("myconf\ai.conf.bak-before-cutover-" + (Get-Date -Format "yyyyMMdd-HHmmss"))
|
|
Copy-Item $ai $bak -Force
|
|
$bytes = [System.IO.File]::ReadAllBytes($AiConfNew)
|
|
if ($bytes.Length -ge 3 -and $bytes[0] -eq 239 -and $bytes[1] -eq 187 -and $bytes[2] -eq 191) {
|
|
$list = New-Object System.Collections.Generic.List[byte]
|
|
for ($i = 3; $i -lt $bytes.Length; $i++) { [void]$list.Add($bytes[$i]) }
|
|
$bytes = $list.ToArray()
|
|
}
|
|
[System.IO.File]::WriteAllBytes($ai, $bytes)
|
|
$old = Get-Location
|
|
Set-Location $Nginx
|
|
& .\nginx.exe -t
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Copy-Item $bak $ai -Force
|
|
Set-Location $old
|
|
throw "nginx -t failed, restored"
|
|
}
|
|
Get-Process nginx -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
|
Start-Sleep -Seconds 1
|
|
try { Start-Service Nginx1.18 -ErrorAction Stop } catch {
|
|
Start-Process -FilePath (Join-Path $Nginx "nginx.exe") -WorkingDirectory $Nginx -WindowStyle Hidden
|
|
}
|
|
Set-Location $old
|
|
Write-Output "NGINX_RESTARTED bak=$bak"
|
|
Write-Output "DONE release=$ReleaseId"
|