| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- # ==============================================================================
- # lf_mri_platform -- Pull latest code and rebuild services
- # Usage:
- # .\update.ps1 -- git pull + rebuild all containers
- # .\update.ps1 -Services o,s -- rebuild only listed services (comma-separated)
- # .\update.ps1 -SkipGit -- skip git pull (only rebuild)
- # .\update.ps1 -RestartSpec -- also restart the native spectrometer
- # ==============================================================================
- param(
- [string]$Services = "", # e.g. "orchestrator,seq-interp"
- [switch]$SkipGit,
- [switch]$RestartSpec
- )
- $ErrorActionPreference = "Stop"
- $Root = $PSScriptRoot
- $EnvFile = Join-Path $Root ".env"
- function Write-Step($msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan }
- function Write-OK($msg) { Write-Host " [OK] $msg" -ForegroundColor Green }
- function Write-Warn($msg) { Write-Host " [!!] $msg" -ForegroundColor Yellow }
- function Write-Fail($msg) {
- Write-Host "`n[FAIL] $msg" -ForegroundColor Red
- Write-Host "`n Press Enter to close..." -ForegroundColor DarkGray
- $null = Read-Host
- exit 1
- }
- trap {
- Write-Host "`n[ERROR] $_" -ForegroundColor Red
- Write-Host "`n Press Enter to close..." -ForegroundColor DarkGray
- $null = Read-Host
- exit 1
- }
- # -- 1. Git pull ---------------------------------------------------------------
- if (-not $SkipGit) {
- Write-Step "Pulling latest code"
- Push-Location $Root
- try {
- $before = & git rev-parse HEAD 2>$null
- & git pull
- if ($LASTEXITCODE -ne 0) { Write-Fail "git pull failed" }
- $after = & git rev-parse HEAD 2>$null
- if ($before -eq $after) {
- Write-OK "Already up to date ($($after.Substring(0,8)))"
- } else {
- Write-OK "Updated $($before.Substring(0,8)) -> $($after.Substring(0,8))"
- Write-Host ""
- & git log --oneline "$before..$after"
- }
- } finally {
- Pop-Location
- }
- }
- # -- 2. Check Docker -----------------------------------------------------------
- Write-Step "Checking Docker"
- try { & docker info *>$null } catch {
- Write-Fail "Docker is not running. Start Docker Desktop and try again."
- }
- Write-OK "Docker is running"
- # -- 3. Rebuild containers -----------------------------------------------------
- Write-Step "Rebuilding containers"
- $envArgs = if (Test-Path $EnvFile) { @("--env-file", $EnvFile) } else { @() }
- if ($Services) {
- $svcList = $Services -split "," | ForEach-Object { $_.Trim() } | Where-Object { $_ }
- Write-Host " Services: $($svcList -join ', ')" -ForegroundColor DarkGray
- & docker compose @envArgs up --build -d @svcList
- } else {
- Write-Host " Services: all" -ForegroundColor DarkGray
- & docker compose @envArgs up --build -d
- }
- if ($LASTEXITCODE -ne 0) { Write-Fail "docker compose up --build failed" }
- Write-OK "Containers rebuilt and started"
- # -- 4. Optionally restart the native spectrometer ----------------------------
- if ($RestartSpec) {
- Write-Step "Restarting native spectrometer"
- $specProc = Get-Process -Name python* -ErrorAction SilentlyContinue |
- Where-Object { $_.CommandLine -like "*manage.py*runserver*" }
- if ($specProc) {
- Write-Host " Stopping old spectrometer process (PID $($specProc.Id))..." -ForegroundColor DarkGray
- Stop-Process -Id $specProc.Id -Force
- Start-Sleep 1
- Write-OK "Old process stopped"
- } else {
- Write-Warn "No running spectrometer process found -- will start fresh"
- }
- $specDir = Join-Path $Root "services\spectrometer"
- $python = "python"
- # Try project venv first
- $venvPy = Join-Path $Root "apps\gui\.venv\Scripts\python.exe"
- if (Test-Path $venvPy) { $python = $venvPy }
- Write-Host " Starting spectrometer at $specDir ..." -ForegroundColor DarkGray
- Start-Process $python `
- -ArgumentList "manage.py runserver 0.0.0.0:8000" `
- -WorkingDirectory $specDir `
- -WindowStyle Normal
- Write-OK "Spectrometer started in new window"
- }
- # -- 5. Health check -----------------------------------------------------------
- Write-Step "Checking service health"
- function Get-EnvPort($key, $default) {
- if (Test-Path $EnvFile) {
- $line = Get-Content $EnvFile | Select-String "^$key=(\d+)"
- if ($line) { return $line.Matches[0].Groups[1].Value }
- }
- return $default
- }
- $checks = @(
- @{ Name = "Orchestrator"; Url = "http://localhost:$(Get-EnvPort 'ORCHESTRATOR_PORT' '1717')/health"; Native = $false },
- @{ Name = "Seq-Interp"; Url = "http://localhost:$(Get-EnvPort 'SEQ_INTERP_PORT' '7475')/health"; Native = $false },
- @{ Name = "Spectroscopy"; Url = "http://localhost:$(Get-EnvPort 'SPECTROSCOPY_PORT' '8002')/health"; Native = $false },
- @{ Name = "Spectrometer*"; Url = "http://localhost:$(Get-EnvPort 'SPECTROMETER_PORT' '8000')/api/"; Native = $true }
- )
- function Test-Port($url) {
- try {
- $uri = [System.Uri]$url
- $port = if ($uri.Port -gt 0) { $uri.Port } else { 80 }
- $tcp = New-Object System.Net.Sockets.TcpClient
- $ar = $tcp.BeginConnect($uri.Host, $port, $null, $null)
- $ok = $ar.AsyncWaitHandle.WaitOne(1500, $false)
- try { $tcp.Close() } catch {}
- return $ok
- } catch { return $false }
- }
- $maxWait = 60; $interval = 3; $elapsed = 0
- while ($elapsed -lt $maxWait) {
- $pending = @()
- foreach ($c in $checks) {
- if ($c.Native) { continue } # native services not waited on
- if (-not (Test-Port $c.Url)) { $pending += $c.Name }
- }
- if ($pending.Count -eq 0) { break }
- Write-Host (" ... {0}/{1} s waiting: {2}" -f $elapsed, $maxWait, ($pending -join ", ")) -ForegroundColor DarkGray
- Start-Sleep $interval; $elapsed += $interval
- }
- Write-Host ""
- foreach ($c in $checks) {
- $ok = Test-Port $c.Url
- $icon = if ($ok) { "[OK]" } else { "[--]" }
- $color = if ($ok) { "Green" } elseif ($c.Native) { "DarkGray" } else { "Yellow" }
- $suffix = if ($c.Native) { " (native -- start manually if needed)" } else { "" }
- Write-Host (" {0,-6} {1,-16} {2}{3}" -f $icon, $c.Name, $c.Url, $suffix) -ForegroundColor $color
- }
- # -- 6. Summary ----------------------------------------------------------------
- Write-Host ""
- Write-Host "============================================================" -ForegroundColor Green
- Write-Host " Update complete" -ForegroundColor Green
- Write-Host "============================================================" -ForegroundColor Green
- Write-Host ""
- Write-Host " To rebuild only specific services next time:"
- Write-Host " .\update.ps1 -Services orchestrator,seq-interp"
- Write-Host ""
- Write-Host " To also restart the native spectrometer:"
- Write-Host " .\update.ps1 -RestartSpec"
- Write-Host ""
- Write-Host " Press Enter to close this window..." -ForegroundColor DarkGray
- $null = Read-Host
|