diff --git a/scripts/dev-up.ps1 b/scripts/dev-up.ps1 index 93e8f14..31311eb 100644 --- a/scripts/dev-up.ps1 +++ b/scripts/dev-up.ps1 @@ -127,10 +127,17 @@ function Warn-ComposeEnvReadiness { } } +# PS 5.1은 $ErrorActionPreference='Stop'에서 네이티브 stderr 리디렉션을 종료 오류(NativeCommandError)로 바꾼다. +# 컨테이너·볼륨 존재 여부처럼 실패가 정상 결과인 docker 탐지는 이 헬퍼로 감싸고 $LASTEXITCODE로 판정한다. +function Invoke-DockerProbe { + $ErrorActionPreference = 'Continue' + & docker @args 2>$null +} + function Test-DevDbRoleSafety([string]$ownerUser, [string]$dbName) { if ([string]::IsNullOrWhiteSpace($ownerUser) -or [string]::IsNullOrWhiteSpace($dbName)) { return } $sql = "SELECT rolname || ':' || rolsuper || ':' || rolbypassrls FROM pg_roles WHERE rolname IN ('vignette_app','vignette_owner') ORDER BY rolname;" - $rows = & docker exec vignette-dev-db psql -U $ownerUser -d $dbName -At -c $sql 2>$null + $rows = Invoke-DockerProbe exec vignette-dev-db psql -U $ownerUser -d $dbName -At -c $sql if ($LASTEXITCODE -ne 0) { Write-Host ' WARN db role 점검 실패 - psql 접속/권한 확인 필요.' return @@ -145,13 +152,13 @@ function Test-DevDbRoleSafety([string]$ownerUser, [string]$dbName) { } function Get-DevDbContainerState { - $state = & docker inspect -f '{{.State.Status}}' $DevDbContainerName 2>$null + $state = Invoke-DockerProbe inspect -f '{{.State.Status}}' $DevDbContainerName if ($LASTEXITCODE -ne 0) { return $null } return "$state".Trim() } function Get-DevDbContainerEnvValue([string]$key, [string]$fallback) { - $envLines = @(& docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' $DevDbContainerName 2>$null) + $envLines = @(Invoke-DockerProbe inspect -f '{{range .Config.Env}}{{println .}}{{end}}' $DevDbContainerName) if ($LASTEXITCODE -ne 0) { return $fallback } $prefix = "${key}=" foreach ($line in $envLines) { @@ -165,7 +172,7 @@ function Get-DevDbContainerEnvValue([string]$key, [string]$fallback) { function Wait-DevDbReady([string]$ownerUser, [int]$attempts = 24) { for ($i = 0; $i -lt $attempts; $i++) { - & docker exec $DevDbContainerName pg_isready -U $ownerUser 1>$null 2>$null + Invoke-DockerProbe exec $DevDbContainerName pg_isready -U $ownerUser | Out-Null if ($LASTEXITCODE -eq 0) { return $true } Start-Sleep -Seconds 2 } @@ -173,13 +180,13 @@ function Wait-DevDbReady([string]$ownerUser, [int]$attempts = 24) { } function Inspect-DevDbContainer { - $healthMode = & docker inspect -f '{{if .Config.Healthcheck}}health{{else}}none{{end}}' $DevDbContainerName 2>$null + $healthMode = Invoke-DockerProbe inspect -f '{{if .Config.Healthcheck}}health{{else}}none{{end}}' $DevDbContainerName if ($LASTEXITCODE -eq 0 -and "$healthMode" -eq 'none') { Write-Host ' WARN vignette-dev-db healthcheck 없음 - 데이터는 유지하고 pg_isready로 점검함(dev-up은 DB를 재생성하지 않음).' } $ownerUser = Get-DevDbContainerEnvValue 'POSTGRES_USER' 'vignette_owner' $dbName = Get-DevDbContainerEnvValue 'POSTGRES_DB' 'vignette' - & docker exec $DevDbContainerName pg_isready -U $ownerUser 1>$null 2>$null + Invoke-DockerProbe exec $DevDbContainerName pg_isready -U $ownerUser | Out-Null if ($LASTEXITCODE -eq 0) { Write-Host ' OK db (vignette-dev-db 준비됨)' } else { @@ -205,7 +212,7 @@ function Start-ExistingDevDbContainer([string]$state) { } function Ensure-DevDbDataVolume { - $existing = & docker volume inspect -f '{{.Name}}' $DevDbDataVolume 2>$null + $existing = Invoke-DockerProbe volume inspect -f '{{.Name}}' $DevDbDataVolume if ($LASTEXITCODE -eq 0) { if ("$existing".Trim() -ne $DevDbDataVolume) { throw "DB named volume 식별 불일치: $existing" @@ -228,7 +235,7 @@ function Ensure-DevDb { Write-Host ' WARN Docker Desktop Linux engine 미실행 - DB 없이 degraded(UI 세션 시작 제한).' return } - docker ps 1>$null 2>$null + Invoke-DockerProbe ps | Out-Null if ($LASTEXITCODE -ne 0) { Write-Host ' WARN Docker 데몬 미응답 - DB 없이 degraded(UI 세션 시작 제한). Docker Desktop 실행 필요.' return