mirror of
https://codeberg.org/likwid/likwid.git
synced 2026-02-09 21:13:09 +00:00
dev: harden local dev scripts
This commit is contained in:
parent
c884e9da52
commit
f66f11651d
2 changed files with 243 additions and 86 deletions
|
|
@ -14,11 +14,77 @@ $ErrorActionPreference = 'Stop'
|
||||||
$root = Split-Path -Parent $PSScriptRoot
|
$root = Split-Path -Parent $PSScriptRoot
|
||||||
$stateDir = Join-Path $PSScriptRoot '.dev'
|
$stateDir = Join-Path $PSScriptRoot '.dev'
|
||||||
$stateFile = Join-Path $stateDir 'state.json'
|
$stateFile = Join-Path $stateDir 'state.json'
|
||||||
|
$rootPattern = [regex]::Escape($root)
|
||||||
$backendLog = Join-Path $stateDir 'backend.log'
|
$backendLog = Join-Path $stateDir 'backend.log'
|
||||||
|
$backendErrLog = Join-Path $stateDir 'backend.err.log'
|
||||||
$frontendLog = Join-Path $stateDir 'frontend.log'
|
$frontendLog = Join-Path $stateDir 'frontend.log'
|
||||||
|
$frontendErrLog = Join-Path $stateDir 'frontend.err.log'
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path $stateDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $stateDir | Out-Null
|
||||||
|
|
||||||
|
function Invoke-Compose {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][string[]]$Args
|
||||||
|
)
|
||||||
|
|
||||||
|
$podmanCompose = Get-Command podman-compose -ErrorAction SilentlyContinue
|
||||||
|
if ($podmanCompose) {
|
||||||
|
& podman-compose @Args
|
||||||
|
return $LASTEXITCODE
|
||||||
|
}
|
||||||
|
|
||||||
|
$podman = Get-Command podman -ErrorAction SilentlyContinue
|
||||||
|
if ($podman) {
|
||||||
|
& podman compose @Args
|
||||||
|
return $LASTEXITCODE
|
||||||
|
}
|
||||||
|
|
||||||
|
throw 'Neither podman-compose nor podman was found in PATH.'
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-CommandLine {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][int]$ProcessId
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
$p = Get-CimInstance Win32_Process -Filter "ProcessId=$ProcessId" -ErrorAction Stop
|
||||||
|
return $p.CommandLine
|
||||||
|
} catch {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-ListeningProcessIdsOnPort {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][int]$Port
|
||||||
|
)
|
||||||
|
|
||||||
|
$connections = netstat -ano 2>$null | Select-String ":$Port\s+.*LISTENING"
|
||||||
|
$pids = @()
|
||||||
|
foreach ($conn in $connections) {
|
||||||
|
$parts = ($conn.Line -replace '\s+', ' ').Trim().Split(' ')
|
||||||
|
$listenerPid = 0
|
||||||
|
[int]::TryParse($parts[-1], [ref]$listenerPid) | Out-Null
|
||||||
|
if ($listenerPid -gt 0) { $pids += $listenerPid }
|
||||||
|
}
|
||||||
|
return ($pids | Select-Object -Unique)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-LikwidProcess {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][int]$ProcessId
|
||||||
|
)
|
||||||
|
|
||||||
|
$cmd = Get-CommandLine -ProcessId $ProcessId
|
||||||
|
if (-not $cmd) { return $false }
|
||||||
|
if ($cmd -match $rootPattern) { return $true }
|
||||||
|
if ($cmd -match 'npm run dev') { return $true }
|
||||||
|
if ($cmd -match 'astro') { return $true }
|
||||||
|
if ($cmd -match 'cargo') { return $true }
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
# Environment
|
# Environment
|
||||||
if (-not $env:POSTGRES_USER) { $env:POSTGRES_USER = 'likwid' }
|
if (-not $env:POSTGRES_USER) { $env:POSTGRES_USER = 'likwid' }
|
||||||
if (-not $env:POSTGRES_PASSWORD) { $env:POSTGRES_PASSWORD = 'likwid' }
|
if (-not $env:POSTGRES_PASSWORD) { $env:POSTGRES_PASSWORD = 'likwid' }
|
||||||
|
|
@ -29,22 +95,54 @@ $env:DATABASE_URL = "postgres://$($env:POSTGRES_USER):$($env:POSTGRES_PASSWORD)@
|
||||||
# Check if already running
|
# Check if already running
|
||||||
if (Test-Path $stateFile) {
|
if (Test-Path $stateFile) {
|
||||||
$state = Get-Content -Raw $stateFile | ConvertFrom-Json -ErrorAction SilentlyContinue
|
$state = Get-Content -Raw $stateFile | ConvertFrom-Json -ErrorAction SilentlyContinue
|
||||||
|
$backendAlive = $false
|
||||||
|
$frontendAlive = $false
|
||||||
if ($state -and $state.backendPid) {
|
if ($state -and $state.backendPid) {
|
||||||
$p = Get-Process -Id $state.backendPid -ErrorAction SilentlyContinue
|
$p = Get-Process -Id $state.backendPid -ErrorAction SilentlyContinue
|
||||||
if ($p) {
|
if ($p) { $backendAlive = $true }
|
||||||
Write-Host "Already running (backend PID $($state.backendPid)). Run dev-stop.ps1 first."
|
}
|
||||||
|
if ($state -and $state.frontendPid) {
|
||||||
|
$p = Get-Process -Id $state.frontendPid -ErrorAction SilentlyContinue
|
||||||
|
if ($p) { $frontendAlive = $true }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($backendAlive -or $frontendAlive) {
|
||||||
|
Write-Host "Already running. Run dev-stop.ps1 first."
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Remove-Item -Force $stateFile -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Guard against duplicate starts / port conflicts
|
||||||
|
foreach ($port in @(3000, 4321)) {
|
||||||
|
$pids = Get-ListeningProcessIdsOnPort -Port $port
|
||||||
|
if (-not $pids -or $pids.Count -eq 0) { continue }
|
||||||
|
|
||||||
|
$likwidPid = $pids | Where-Object { Test-LikwidProcess -ProcessId $_ } | Select-Object -First 1
|
||||||
|
if ($likwidPid) {
|
||||||
|
Write-Host "Already running (detected Likwid process PID $likwidPid listening on port $port). Run dev-stop.ps1 first."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
$pidList = ($pids -join ', ')
|
||||||
|
throw "Port $port is already in use by PID(s): $pidList. Stop the process or change ports before starting Likwid."
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start Podman machine if needed
|
# Start Podman machine if needed
|
||||||
try {
|
try {
|
||||||
$machines = podman machine list --format json 2>$null | ConvertFrom-Json
|
$machines = podman machine list --format json 2>$null | ConvertFrom-Json
|
||||||
|
if (-not $machines) {
|
||||||
|
throw 'No Podman machines found.'
|
||||||
|
}
|
||||||
$running = $machines | Where-Object { $_.Running -eq $true }
|
$running = $machines | Where-Object { $_.Running -eq $true }
|
||||||
if (-not $running) {
|
if (-not $running) {
|
||||||
|
$name = ($machines | Select-Object -First 1).Name
|
||||||
|
if (-not $name) {
|
||||||
|
throw 'No Podman machine name found.'
|
||||||
|
}
|
||||||
Write-Host "Starting Podman machine..."
|
Write-Host "Starting Podman machine..."
|
||||||
podman machine start ($machines | Select-Object -First 1).Name 2>$null
|
podman machine start $name 2>$null
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
Write-Host "Podman machine check failed (may already be running)"
|
Write-Host "Podman machine check failed (may already be running)"
|
||||||
|
|
@ -56,8 +154,7 @@ $composeFile = Join-Path $root 'compose/dev.yml'
|
||||||
|
|
||||||
$composeExitCode = 0
|
$composeExitCode = 0
|
||||||
try {
|
try {
|
||||||
podman-compose -f $composeFile up -d 2>$null
|
$composeExitCode = Invoke-Compose -Args @('-f', $composeFile, 'up', '-d')
|
||||||
$composeExitCode = $LASTEXITCODE
|
|
||||||
} catch {
|
} catch {
|
||||||
$composeExitCode = $LASTEXITCODE
|
$composeExitCode = $LASTEXITCODE
|
||||||
}
|
}
|
||||||
|
|
@ -70,22 +167,32 @@ if ($composeExitCode -ne 0) {
|
||||||
$containerExistsExitCode = $LASTEXITCODE
|
$containerExistsExitCode = $LASTEXITCODE
|
||||||
}
|
}
|
||||||
if ($containerExistsExitCode -ne 0) {
|
if ($containerExistsExitCode -ne 0) {
|
||||||
throw "Failed to start PostgreSQL via podman-compose (exit code: $composeExitCode)."
|
throw "Failed to start PostgreSQL via Podman Compose (exit code: $composeExitCode)."
|
||||||
}
|
}
|
||||||
Write-Host "Warning: podman-compose returned exit code $composeExitCode, but likwid-postgres exists. Continuing."
|
Write-Host "Warning: Podman Compose returned exit code $composeExitCode, but likwid-postgres exists. Continuing."
|
||||||
}
|
}
|
||||||
|
|
||||||
# Wait for PostgreSQL to be ready
|
# Wait for PostgreSQL to be ready
|
||||||
$maxWait = 30
|
$maxWait = 30
|
||||||
for ($i = 0; $i -lt $maxWait; $i++) {
|
for ($i = 0; $i -lt $maxWait; $i++) {
|
||||||
$pg = netstat -ano 2>$null | Select-String ':5432.*LISTENING'
|
podman exec likwid-postgres pg_isready -U $env:POSTGRES_USER -d $env:POSTGRES_DB 2>$null | Out-Null
|
||||||
if ($pg) { break }
|
if ($LASTEXITCODE -eq 0) { break }
|
||||||
Start-Sleep -Seconds 1
|
Start-Sleep -Seconds 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
podman exec likwid-postgres pg_isready -U $env:POSTGRES_USER -d $env:POSTGRES_DB 2>$null | Out-Null
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Host "PostgreSQL did not become ready."
|
||||||
|
podman logs --tail 60 likwid-postgres 2>$null
|
||||||
|
throw "PostgreSQL startup timed out."
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Running database migrations..."
|
Write-Host "Running database migrations..."
|
||||||
Push-Location (Join-Path $root 'backend')
|
Push-Location (Join-Path $root 'backend')
|
||||||
try {
|
try {
|
||||||
|
if (-not (Get-Command sqlx -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "sqlx CLI not found in PATH. Install with: cargo install sqlx-cli --no-default-features --features postgres"
|
||||||
|
}
|
||||||
sqlx migrate run --ignore-missing
|
sqlx migrate run --ignore-missing
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
throw "Failed to run database migrations (sqlx migrate run)."
|
throw "Failed to run database migrations (sqlx migrate run)."
|
||||||
|
|
@ -97,18 +204,20 @@ try {
|
||||||
# Start backend
|
# Start backend
|
||||||
Write-Host "Starting backend..."
|
Write-Host "Starting backend..."
|
||||||
$backend = Start-Process -FilePath 'cmd.exe' `
|
$backend = Start-Process -FilePath 'cmd.exe' `
|
||||||
-ArgumentList '/c', 'cargo', 'run', '2>&1' `
|
-ArgumentList '/c', 'cargo', 'run' `
|
||||||
-WorkingDirectory (Join-Path $root 'backend') `
|
-WorkingDirectory (Join-Path $root 'backend') `
|
||||||
-PassThru -WindowStyle Hidden `
|
-PassThru -WindowStyle Hidden `
|
||||||
-RedirectStandardOutput $backendLog
|
-RedirectStandardOutput $backendLog `
|
||||||
|
-RedirectStandardError $backendErrLog
|
||||||
|
|
||||||
# Start frontend
|
# Start frontend
|
||||||
Write-Host "Starting frontend..."
|
Write-Host "Starting frontend..."
|
||||||
$frontend = Start-Process -FilePath 'cmd.exe' `
|
$frontend = Start-Process -FilePath 'cmd.exe' `
|
||||||
-ArgumentList '/c', "set PUBLIC_API_BASE=http://127.0.0.1:3000&& npm run dev", '2>&1' `
|
-ArgumentList '/c', "set PUBLIC_API_BASE=http://127.0.0.1:3000&& npm run dev" `
|
||||||
-WorkingDirectory (Join-Path $root 'frontend') `
|
-WorkingDirectory (Join-Path $root 'frontend') `
|
||||||
-PassThru -WindowStyle Hidden `
|
-PassThru -WindowStyle Hidden `
|
||||||
-RedirectStandardOutput $frontendLog
|
-RedirectStandardOutput $frontendLog `
|
||||||
|
-RedirectStandardError $frontendErrLog
|
||||||
|
|
||||||
# Save state
|
# Save state
|
||||||
@{
|
@{
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,40 @@ $ErrorActionPreference = 'Continue'
|
||||||
$root = Split-Path -Parent $PSScriptRoot
|
$root = Split-Path -Parent $PSScriptRoot
|
||||||
$stateDir = Join-Path $PSScriptRoot '.dev'
|
$stateDir = Join-Path $PSScriptRoot '.dev'
|
||||||
$stateFile = Join-Path $stateDir 'state.json'
|
$stateFile = Join-Path $stateDir 'state.json'
|
||||||
|
$rootPattern = [regex]::Escape($root)
|
||||||
|
|
||||||
|
function Invoke-Compose {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][string[]]$Args
|
||||||
|
)
|
||||||
|
|
||||||
|
$podmanCompose = Get-Command podman-compose -ErrorAction SilentlyContinue
|
||||||
|
if ($podmanCompose) {
|
||||||
|
& podman-compose @Args
|
||||||
|
return $LASTEXITCODE
|
||||||
|
}
|
||||||
|
|
||||||
|
$podman = Get-Command podman -ErrorAction SilentlyContinue
|
||||||
|
if ($podman) {
|
||||||
|
& podman compose @Args
|
||||||
|
return $LASTEXITCODE
|
||||||
|
}
|
||||||
|
|
||||||
|
throw 'Neither podman-compose nor podman was found in PATH.'
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-CommandLine {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][int]$ProcessId
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
$p = Get-CimInstance Win32_Process -Filter "ProcessId=$ProcessId" -ErrorAction Stop
|
||||||
|
return $p.CommandLine
|
||||||
|
} catch {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Stop-ProcessSafely([int]$ProcessId, [string]$Name) {
|
function Stop-ProcessSafely([int]$ProcessId, [string]$Name) {
|
||||||
if (-not $ProcessId) { return $false }
|
if (-not $ProcessId) { return $false }
|
||||||
|
|
@ -37,10 +71,21 @@ function Stop-ProcessOnPort([int]$Port) {
|
||||||
$parts = ($conn.Line -replace '\s+', ' ').Trim().Split(' ')
|
$parts = ($conn.Line -replace '\s+', ' ').Trim().Split(' ')
|
||||||
$procId = [int]$parts[-1]
|
$procId = [int]$parts[-1]
|
||||||
if ($procId -gt 0) {
|
if ($procId -gt 0) {
|
||||||
|
$cmd = Get-CommandLine -ProcessId $procId
|
||||||
|
$looksLikeLikwid = $false
|
||||||
|
if ($cmd) {
|
||||||
|
if ($cmd -match $rootPattern) { $looksLikeLikwid = $true }
|
||||||
|
if ($cmd -match 'npm run dev') { $looksLikeLikwid = $true }
|
||||||
|
if ($cmd -match 'astro') { $looksLikeLikwid = $true }
|
||||||
|
if ($cmd -match 'cargo') { $looksLikeLikwid = $true }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($looksLikeLikwid) {
|
||||||
Stop-ProcessSafely -ProcessId $procId -Name "process on port $Port" | Out-Null
|
Stop-ProcessSafely -ProcessId $procId -Name "process on port $Port" | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "=== Stopping Likwid Dev Environment ==="
|
Write-Host "=== Stopping Likwid Dev Environment ==="
|
||||||
|
|
||||||
|
|
@ -60,7 +105,10 @@ Stop-ProcessOnPort -Port 3000
|
||||||
# Stop PostgreSQL container
|
# Stop PostgreSQL container
|
||||||
Write-Host "Stopping PostgreSQL container..."
|
Write-Host "Stopping PostgreSQL container..."
|
||||||
$composeFile = Join-Path $root 'compose/dev.yml'
|
$composeFile = Join-Path $root 'compose/dev.yml'
|
||||||
podman-compose -f $composeFile down 2>$null
|
try {
|
||||||
|
Invoke-Compose -Args @('-f', $composeFile, 'down') | Out-Null
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
|
||||||
# Clean up state file
|
# Clean up state file
|
||||||
if (Test-Path $stateFile) {
|
if (Test-Path $stateFile) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue