# Remote: publish latest admin dist + switch Nginx /jeecgboot -> 8180 # Do not touch C:\yutongda. On nginx -t failure, restore backup. $ErrorActionPreference = 'Stop' $IncomingZip = 'C:\Users\ytd_extdev_0903\incoming\admin-dist.zip' $IncomingConf = 'C:\Users\ytd_extdev_0903\incoming\ai.conf.cutover-8180' $Root = 'E:\wwwroot' $Nginx = 'C:\nginx-1.18.0' $NginxConf = Join-Path $Nginx 'myconf\ai.conf' $Stamp = Get-Date -Format 'yyyyMMdd-HHmmss' $RelId = 'admin-' + $Stamp $RelDist = Join-Path $Root ('admin\releases\' + $RelId + '\dist') $Current = Join-Path $Root 'admin\current' $PtrPath = Join-Path $Root 'ops\active-release.json' if (-not (Test-Path $IncomingZip)) { throw 'missing admin-dist.zip' } if (-not (Test-Path $IncomingConf)) { throw 'missing ai.conf.cutover-8180' } $ledger = Get-NetTCPConnection -LocalPort 8180 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $ledger) { throw 'CRITICAL: 8180 not listening' } $agent = Get-NetTCPConnection -LocalPort 8910 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $agent) { throw 'CRITICAL: 8910 not listening' } $prod = Get-NetTCPConnection -LocalPort 8080 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $prod) { throw 'CRITICAL: prod 8080 down' } Write-Output '=== backup nginx ===' $bak = $NginxConf + '.bak-before-admin-8180-' + $Stamp Copy-Item $NginxConf $bak -Force Write-Output ('bak=' + $bak) Write-Output '=== install release dist ===' New-Item -ItemType Directory -Force -Path $RelDist | Out-Null Expand-Archive -Path $IncomingZip -DestinationPath $RelDist -Force if (-not (Test-Path (Join-Path $RelDist 'index.html'))) { $inner = Get-ChildItem $RelDist -Directory | Select-Object -First 1 if ($inner -and (Test-Path (Join-Path $inner.FullName 'index.html'))) { $RelDist = $inner.FullName } } if (-not (Test-Path (Join-Path $RelDist 'index.html'))) { throw 'index.html missing' } Write-Output '=== switch admin current junction ===' if (Test-Path $Current) { cmd /c ('rmdir "' + $Current + '"') | Out-Null if (Test-Path $Current) { Remove-Item $Current -Recurse -Force } } cmd /c ('mklink /J "' + $Current + '" "' + $RelDist + '"') if (-not (Test-Path (Join-Path $Current 'index.html'))) { throw 'current index missing' } Write-Output ('CURRENT_OK=' + $Current + ' -> ' + $RelDist) Write-Output '=== nginx conf no BOM ===' $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 $Nginx & .\nginx.exe -t if ($LASTEXITCODE -ne 0) { Copy-Item $bak $NginxConf -Force 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 Write-Output 'SERVICE_STARTED' } catch { Start-Process -FilePath (Join-Path $Nginx 'nginx.exe') -WorkingDirectory $Nginx -WindowStyle Hidden Write-Output 'EXE_STARTED' } Start-Sleep -Seconds 2 New-Item -ItemType Directory -Force -Path (Join-Path $Root 'ops') | Out-Null $prevAgentCurrent = Join-Path $Root 'agent\current' $prevAgentHome = $null if (Test-Path $PtrPath) { try { $old = Get-Content $PtrPath -Raw | ConvertFrom-Json if ($old.agentCurrent) { $prevAgentCurrent = [string]$old.agentCurrent } if ($old.agentHome) { $prevAgentHome = [string]$old.agentHome } } catch {} } $ptr = @{ root = $Root releaseId = $RelId adminRelease = $RelDist adminCurrent = $Current agentCurrent = $prevAgentCurrent agentHome = $prevAgentHome nginxBak = $bak jeecgbootProxy = 'http://127.0.0.1:8180/jeecgboot/' updatedAt = (Get-Date).ToString('o') note = 'admin cutover to Jeecg Vue + ledger 8180' } ($ptr | ConvertTo-Json) | Out-File -FilePath $PtrPath -Encoding utf8 Write-Output '=== smoke ===' try { $h = Invoke-WebRequest -Uri 'http://127.0.0.1:8180/jeecgboot/sys/randomImage/cutover' -UseBasicParsing -TimeoutSec 8 Write-Output ('ledger=' + $h.StatusCode) } catch { Write-Output ('ledger_fail=' + $_.Exception.Message) } Write-Output 'ADMIN_CUTOVER_OK'