From 575be16214251c3badf5fcc0874bc74ade88af87 Mon Sep 17 00:00:00 2001 From: Nicole Rappe Date: Sun, 16 Nov 2025 06:56:28 -0700 Subject: [PATCH] Fixed Python Path Issues for Borealis Agent if Agent is moved to a different location on endpoint. --- Borealis.ps1 | 79 ++++++++++++++++++++++++++++++----- Data/Agent/launch_service.ps1 | 72 +++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 11 deletions(-) diff --git a/Borealis.ps1 b/Borealis.ps1 index 0fe25b47..9f2b1c67 100644 --- a/Borealis.ps1 +++ b/Borealis.ps1 @@ -851,19 +851,76 @@ function InstallOrUpdate-BorealisAgent { $existingServerUrl = $null Run-Step "Create Virtual Python Environment" { - if (-not (Test-Path (Join-Path $venvFolderPath 'Scripts\Activate'))) { - $pythonForVenv = $pythonExe - if (-not (Test-Path $pythonForVenv)) { - $pyCmd = Get-Command py -ErrorAction SilentlyContinue - $pythonCmd = Get-Command python -ErrorAction SilentlyContinue - if ($pyCmd) { $pythonForVenv = $pyCmd.Source } - elseif ($pythonCmd) { $pythonForVenv = $pythonCmd.Source } - else { - Write-Host "Python not found. Install Python or run Server setup (option 1)." -ForegroundColor Red - exit 1 - } + $venvActivate = Join-Path $venvFolderPath 'Scripts\Activate' + $pyvenvCfg = Join-Path $venvFolderPath 'pyvenv.cfg' + $pythonForVenv = $pythonExe + if (-not (Test-Path $pythonForVenv)) { + $pyCmd = Get-Command py -ErrorAction SilentlyContinue + $pythonCmd = Get-Command python -ErrorAction SilentlyContinue + if ($pyCmd) { $pythonForVenv = $pyCmd.Source } + elseif ($pythonCmd) { $pythonForVenv = $pythonCmd.Source } + else { + Write-Host "Python not found. Install Python or run Server setup (option 1)." -ForegroundColor Red + exit 1 } + } + + $expectedPython = $pythonForVenv + $expectedPythonNorm = $null + $expectedHomeNorm = $null + try { + if (Test-Path $expectedPython -PathType Leaf) { + $expectedPython = (Resolve-Path $expectedPython -ErrorAction Stop).ProviderPath + } + } catch { $expectedPython = $pythonForVenv } + if ($expectedPython) { + $expectedPythonNorm = $expectedPython.ToLowerInvariant() + try { + $expectedHome = Split-Path -Path $expectedPython -Parent + } catch { $expectedHome = $null } + if ($expectedHome) { $expectedHomeNorm = $expectedHome.ToLowerInvariant() } + } + + $venvNeedsUpgrade = $false + if (Test-Path $pyvenvCfg -PathType Leaf) { + try { + $cfgLines = Get-Content -Path $pyvenvCfg -ErrorAction Stop + $cfgMap = @{} + foreach ($line in $cfgLines) { + $trimmed = $line.Trim() + if (-not $trimmed -or $trimmed.StartsWith('#')) { continue } + $parts = $trimmed -split '=', 2 + if ($parts.Count -ne 2) { continue } + $cfgMap[$parts[0].Trim().ToLowerInvariant()] = $parts[1].Trim() + } + + $cfgExecutable = $cfgMap['executable'] + $cfgHome = $cfgMap['home'] + + if ($cfgExecutable -and -not (Test-Path $cfgExecutable -PathType Leaf)) { + $venvNeedsUpgrade = $true + } elseif ($cfgHome -and -not (Test-Path $cfgHome -PathType Container)) { + $venvNeedsUpgrade = $true + } else { + if ($cfgExecutable -and $expectedPythonNorm) { + try { $resolvedExe = (Resolve-Path $cfgExecutable -ErrorAction Stop).ProviderPath } catch { $resolvedExe = $cfgExecutable } + $resolvedExeNorm = if ($resolvedExe) { $resolvedExe.ToLowerInvariant() } else { $null } + if ($resolvedExeNorm -and $resolvedExeNorm -ne $expectedPythonNorm) { $venvNeedsUpgrade = $true } + } + if (-not $venvNeedsUpgrade -and $cfgHome -and $expectedHomeNorm) { + try { $resolvedHome = (Resolve-Path $cfgHome -ErrorAction Stop).ProviderPath } catch { $resolvedHome = $cfgHome } + $resolvedHomeNorm = if ($resolvedHome) { $resolvedHome.ToLowerInvariant() } else { $null } + if ($resolvedHomeNorm -and $resolvedHomeNorm -ne $expectedHomeNorm) { $venvNeedsUpgrade = $true } + } + } + } catch { $venvNeedsUpgrade = $true } + } + + if (-not (Test-Path $venvActivate)) { & $pythonForVenv -m venv $venvFolderPath + } elseif ($venvNeedsUpgrade) { + Write-Host "Detected relocated Agent virtual environment. Rebuilding interpreter bindings..." -ForegroundColor Yellow + & $pythonForVenv -m venv --upgrade $venvFolderPath } if (Test-Path $agentSourcePath) { # Cleanup Previous Agent Folder & Create New Folder diff --git a/Data/Agent/launch_service.ps1 b/Data/Agent/launch_service.ps1 index 29a3b80d..045bd191 100644 --- a/Data/Agent/launch_service.ps1 +++ b/Data/Agent/launch_service.ps1 @@ -17,11 +17,83 @@ try { if (-not (Test-Path $logsAgent)) { New-Item -ItemType Directory -Path $logsAgent -Force | Out-Null } $wrapperLog = Join-Path $logsAgent 'service_wrapper.log' + function Write-WrapperLog { + param([string]$Message) + if (-not $Message) { return } + try { + "[{0}] {1}" -f (Get-Date -Format s), $Message | Out-File -FilePath $wrapperLog -Append -Encoding utf8 + } catch {} + } + $venvBin = Join-Path $scriptDir '..\Scripts' $pyw = Join-Path $venvBin 'pythonw.exe' $py = Join-Path $venvBin 'python.exe' $agentPy = Join-Path $scriptDir 'agent.py' + $pyvenvCfg = Join-Path $agentRoot 'pyvenv.cfg' + $expectedPy = Join-Path $projRoot 'Dependencies\Python\python.exe' + if (-not (Test-Path $expectedPy -PathType Leaf) -and (Test-Path $py -PathType Leaf)) { + $expectedPy = $py + } + + $expectedPyNorm = $null + $expectedHomeNorm = $null + try { + if (Test-Path $expectedPy -PathType Leaf) { + $expectedPy = (Resolve-Path $expectedPy -ErrorAction Stop).ProviderPath + } + } catch {} + if ($expectedPy) { + $expectedPyNorm = $expectedPy.ToLowerInvariant() + try { $expectedHome = Split-Path -Path $expectedPy -Parent } catch { $expectedHome = $null } + if ($expectedHome) { $expectedHomeNorm = $expectedHome.ToLowerInvariant() } + } + + $venvNeedsRepair = $false + if (Test-Path $pyvenvCfg -PathType Leaf) { + try { + $cfgLines = Get-Content -Path $pyvenvCfg -ErrorAction Stop + $cfgMap = @{} + foreach ($line in $cfgLines) { + $trimmed = $line.Trim() + if (-not $trimmed -or $trimmed.StartsWith('#')) { continue } + $parts = $trimmed -split '=', 2 + if ($parts.Count -ne 2) { continue } + $cfgMap[$parts[0].Trim().ToLowerInvariant()] = $parts[1].Trim() + } + + $cfgExecutable = $cfgMap['executable'] + $cfgHome = $cfgMap['home'] + + if ($cfgExecutable -and -not (Test-Path $cfgExecutable -PathType Leaf)) { + $venvNeedsRepair = $true + } elseif ($cfgHome -and -not (Test-Path $cfgHome -PathType Container)) { + $venvNeedsRepair = $true + } else { + if ($cfgExecutable -and $expectedPyNorm) { + try { $resolvedExe = (Resolve-Path $cfgExecutable -ErrorAction Stop).ProviderPath } catch { $resolvedExe = $cfgExecutable } + $resolvedExeNorm = if ($resolvedExe) { $resolvedExe.ToLowerInvariant() } else { $null } + if ($resolvedExeNorm -and $resolvedExeNorm -ne $expectedPyNorm) { $venvNeedsRepair = $true } + } + if (-not $venvNeedsRepair -and $cfgHome -and $expectedHomeNorm) { + try { $resolvedHome = (Resolve-Path $cfgHome -ErrorAction Stop).ProviderPath } catch { $resolvedHome = $cfgHome } + $resolvedHomeNorm = if ($resolvedHome) { $resolvedHome.ToLowerInvariant() } else { $null } + if ($resolvedHomeNorm -and $resolvedHomeNorm -ne $expectedHomeNorm) { $venvNeedsRepair = $true } + } + } + } catch { $venvNeedsRepair = $true } + } + + if ($venvNeedsRepair -and (Test-Path $expectedPy -PathType Leaf)) { + Write-WrapperLog ("Detected relocated Agent virtual environment. Rebuilding interpreter bindings with {0}" -f $expectedPy) + try { + & $expectedPy -m venv --upgrade $agentRoot | Out-Null + Write-WrapperLog "Agent virtual environment successfully rebound to current project path." + } catch { + Write-WrapperLog ("Agent virtual environment repair failed: {0}" -f $_.Exception.Message) + } + } + if (-not (Test-Path $pyw) -and -not (Test-Path $py)) { throw "Python not found under: $venvBin" } if (-not (Test-Path $agentPy)) { throw "Agent script not found: $agentPy" }