Files
inquiry_robot/deploy/_remote_reorg_wwwroot_layout.ps1
T

184 lines
7.3 KiB
PowerShell

# Reorganize E:\wwwroot into admin\current and agent\current
# Do not touch C:\yutongda. Keep ports 8080. Only recycle test agent 8910.
$ErrorActionPreference = "Stop"
$Root = "E:\wwwroot"
$Stamp = Get-Date -Format "yyyyMMdd-HHmmss"
$OldReleaseId = "scaffold-agent-20260912-152641"
$OldAgentHome = Join-Path $Root "releases\$OldReleaseId\agent"
$NginxConf = "C:\nginx-1.18.0\myconf\ai.conf"
$IncomingConf = "C:\Users\ytd_extdev_0903\incoming\ai.conf.cutover-8910"
function Step([string]$m) { Write-Output "=== $m ===" }
if (-not (Test-Path $Root)) { throw "missing $Root" }
Step "stop 8910"
Get-NetTCPConnection -LocalPort 8910 -State Listen -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty OwningProcess -Unique |
ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }
Get-CimInstance Win32_Process -Filter "Name='cmd.exe'" -ErrorAction SilentlyContinue |
Where-Object { $_.CommandLine -and $_.CommandLine -like '*run-agent-http*' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
Start-Sleep -Seconds 2
Step "create layout"
New-Item -ItemType Directory -Force -Path @(
"$Root\admin\releases",
"$Root\agent\releases",
"$Root\ops",
"$Root\logs"
) | Out-Null
# --- admin: dist -> releases/<id>/dist + current junction ---
$AdminRelId = "admin-$Stamp"
$AdminRelDist = Join-Path $Root "admin\releases\$AdminRelId\dist"
if (Test-Path "$Root\admin\dist") {
New-Item -ItemType Directory -Force -Path (Split-Path $AdminRelDist) | Out-Null
Move-Item "$Root\admin\dist" $AdminRelDist
Write-Output "MOVED_ADMIN_DIST=$AdminRelDist"
} elseif (Test-Path "$Root\admin\current") {
# already current; ensure releases copy exists
if (-not (Test-Path $AdminRelDist)) {
New-Item -ItemType Directory -Force -Path (Split-Path $AdminRelDist) | Out-Null
robocopy "$Root\admin\current" $AdminRelDist /E /NFL /NDL /NJH /NJS /nc /ns /np | Out-Null
}
} else {
throw "admin dist/current missing"
}
$AdminCurrent = Join-Path $Root "admin\current"
if (Test-Path $AdminCurrent) {
cmd /c "rmdir `"$AdminCurrent`"" | Out-Null
if (Test-Path $AdminCurrent) { Remove-Item $AdminCurrent -Recurse -Force }
}
cmd /c "mklink /J `"$AdminCurrent`" `"$AdminRelDist`""
if (-not (Test-Path (Join-Path $AdminCurrent "index.html"))) { throw "admin current index missing" }
Write-Output "ADMIN_CURRENT_OK"
# --- agent: old releases -> agent\releases + current junction ---
$AgentRelRoot = Join-Path $Root "agent\releases\$OldReleaseId"
$AgentHome = Join-Path $AgentRelRoot "agent"
if (Test-Path $OldAgentHome) {
if (-not (Test-Path $AgentRelRoot)) {
New-Item -ItemType Directory -Force -Path (Split-Path $AgentRelRoot) | Out-Null
Move-Item (Join-Path $Root "releases\$OldReleaseId") $AgentRelRoot
Write-Output "MOVED_AGENT_RELEASE=$AgentRelRoot"
}
} elseif (-not (Test-Path $AgentHome)) {
throw "agent home missing: $OldAgentHome and $AgentHome"
}
# move leftover top-level releases if empty leftovers
$OldReleases = Join-Path $Root "releases"
if (Test-Path $OldReleases) {
Get-ChildItem $OldReleases -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$dest = Join-Path "$Root\agent\releases" $_.Name
if (-not (Test-Path $dest)) {
Move-Item $_.FullName $dest
Write-Output "MOVED_EXTRA=$($_.Name)"
}
}
$left = @(Get-ChildItem $OldReleases -Force -ErrorAction SilentlyContinue)
if ($left.Count -eq 0) { Remove-Item $OldReleases -Force -ErrorAction SilentlyContinue }
}
$AgentCurrent = Join-Path $Root "agent\current"
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 http_app missing" }
Write-Output "AGENT_CURRENT_OK"
Step "rewrite 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 "$Root\ops\run-agent-http.cmd" -Value $runCmd -Encoding ASCII
$pointer = @{
root = $Root
adminCurrent = $AdminCurrent
adminRelease = $AdminRelDist
agentCurrent = $AgentCurrent
agentHome = $AgentHome
releaseId = $OldReleaseId
updatedAt = (Get-Date).ToString("o")
pid = 0
} | ConvertTo-Json
Set-Content -Path "$Root\ops\active-release.json" -Value $pointer -Encoding UTF8
# ensure .env next to agent current
if ((Test-Path "$Root\.env") -and -not (Test-Path "$AgentCurrent\.env")) {
Copy-Item "$Root\.env" "$AgentCurrent\.env" -Force
}
Step "patch nginx conf (no BOM)"
if (-not (Test-Path $IncomingConf)) { throw "missing $IncomingConf" }
Copy-Item $NginxConf "$NginxConf.bak-before-layout-$Stamp" -Force
$bytes = [System.IO.File]::ReadAllBytes($IncomingConf)
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($NginxConf, $bytes)
Set-Location "C:\nginx-1.18.0"
& .\nginx.exe -t
if ($LASTEXITCODE -ne 0) { throw "nginx -t failed" }
# Prefer reload via nginx.exe -s reload; fallback bounce without hung Restart-Service
$ngxOk = $false
try {
& .\nginx.exe -s reload
Start-Sleep -Seconds 1
if (Get-Process nginx -ErrorAction SilentlyContinue) { $ngxOk = $true; Write-Output "NGINX_RELOADED" }
} catch { Write-Output "RELOAD_FAIL" }
if (-not $ngxOk) {
Get-Process nginx -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
try { Start-Service Nginx1.18 -ErrorAction Stop; Start-Sleep -Seconds 2 } catch { }
if (-not (Get-Process nginx -ErrorAction SilentlyContinue)) {
Start-Process -FilePath "C:\nginx-1.18.0\nginx.exe" -WorkingDirectory "C:\nginx-1.18.0" -WindowStyle Hidden
Start-Sleep -Seconds 2
}
if (-not (Get-Process nginx -ErrorAction SilentlyContinue)) { throw "nginx not running" }
Write-Output "NGINX_RESTARTED_EXE"
}
Step "start agent"
$wmi = Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = "cmd.exe /c `"$Root\ops\run-agent-http.cmd`""
}
Write-Output "WMI_Return=$($wmi.ReturnValue) ProcessId=$($wmi.ProcessId)"
Start-Sleep -Seconds 6
$h = Invoke-WebRequest -Uri "http://127.0.0.1:8910/health" -UseBasicParsing -TimeoutSec 8
Write-Output "HEALTH=$($h.StatusCode) $($h.Content)"
$listen = Get-NetTCPConnection -LocalPort 8910 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1
if ($listen) {
$obj = Get-Content "$Root\ops\active-release.json" -Raw | ConvertFrom-Json
$obj.pid = $listen.OwningProcess
$obj | ConvertTo-Json | Set-Content "$Root\ops\active-release.json" -Encoding UTF8
}
Step "tree top"
Get-ChildItem $Root | Select-Object Mode, Name
Get-Item "$Root\admin\current","$Root\agent\current" | Format-List FullName, LinkType, Target
cmd /c "curl.exe -sk -H `"Host: ai.ytd-scm.com`" https://127.0.0.1/agent/health"
Write-Output ""
cmd /c "curl.exe -sk -o NUL -w root:%{http_code} -H `"Host: ai.ytd-scm.com`" https://127.0.0.1/"
Write-Output ""
Write-Output "LAYOUT_DONE"