mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-10-26 13:01:58 -06:00
Fixed Issues in Borealis.ps1 and Update.ps1
This commit is contained in:
27
Borealis.ps1
27
Borealis.ps1
@@ -1030,13 +1030,40 @@ switch ($choice) {
|
||||
Run-Step "Create Borealis Virtual Python Environment" {
|
||||
if (-not (Test-Path "$venvFolder\Scripts\Activate")) { & $pythonExe -m venv $venvFolder | Out-Null }
|
||||
if (Test-Path $dataSource) {
|
||||
$preserveItems = @('auth_keys','server_secret.key','cache')
|
||||
$preserveRoot = Join-Path $venvFolder '.__borealis_preserve'
|
||||
if (Test-Path $dataDestination) {
|
||||
Remove-Item $preserveRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
New-Item -Path $preserveRoot -ItemType Directory -Force | Out-Null
|
||||
foreach ($item in $preserveItems) {
|
||||
$sourcePath = Join-Path $dataDestination $item
|
||||
if (Test-Path $sourcePath) {
|
||||
$targetPath = Join-Path $preserveRoot $item
|
||||
$targetParent = Split-Path $targetPath -Parent
|
||||
if (-not (Test-Path $targetParent)) {
|
||||
New-Item -Path $targetParent -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
Move-Item -Path $sourcePath -Destination $targetPath -Force
|
||||
}
|
||||
}
|
||||
Remove-Item $dataDestination -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
New-Item -Path $dataDestination -ItemType Directory -Force | Out-Null
|
||||
Copy-Item "$dataSource\Server\Python_API_Endpoints" $dataDestination -Recurse
|
||||
Copy-Item "$dataSource\Server\Sounds" $dataDestination -Recurse
|
||||
Copy-Item "$dataSource\Server\Modules" $dataDestination -Recurse
|
||||
Copy-Item "$dataSource\Server\server.py" $dataDestination
|
||||
Copy-Item "$dataSource\Server\job_scheduler.py" $dataDestination
|
||||
if (Test-Path $preserveRoot) {
|
||||
Get-ChildItem -Path $preserveRoot -Force | ForEach-Object {
|
||||
$target = Join-Path $dataDestination $_.Name
|
||||
if (Test-Path $target) {
|
||||
Remove-Item $target -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
Move-Item -Path $_.FullName -Destination $target -Force
|
||||
}
|
||||
Remove-Item $preserveRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
. "$venvFolder\Scripts\Activate"
|
||||
}
|
||||
|
||||
@@ -198,6 +198,8 @@ function NavigationSidebar({ currentPage, onNavigate, isAdmin = false }) {
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails sx={{ p: 0, bgcolor: "#232323" }}>
|
||||
<NavItem icon={<AdminPanelSettingsIcon fontSize="small" />} label="Device Approvals" pageKey="admin_device_approvals" />
|
||||
<NavItem icon={<KeyIcon fontSize="small" />} label="Enrollment Codes" pageKey="admin_enrollment_codes" indent />
|
||||
<NavItem icon={<DevicesIcon fontSize="small" />} label="Devices" pageKey="devices" />
|
||||
<NavItem icon={<DevicesIcon fontSize="small" />} label="Agent Devices" pageKey="agent_devices" indent />
|
||||
<NavItem icon={<DevicesIcon fontSize="small" />} label="SSH Devices" pageKey="ssh_devices" indent />
|
||||
@@ -395,8 +397,6 @@ function NavigationSidebar({ currentPage, onNavigate, isAdmin = false }) {
|
||||
</AccordionSummary>
|
||||
<AccordionDetails sx={{ p: 0, bgcolor: "#232323" }}>
|
||||
<NavItem icon={<ServerInfoIcon fontSize="small" />} label="Server Info" pageKey="server_info" />
|
||||
<NavItem icon={<KeyIcon fontSize="small" />} label="Installer Codes" pageKey="admin_enrollment_codes" />
|
||||
<NavItem icon={<AdminPanelSettingsIcon fontSize="small" />} label="Device Approvals" pageKey="admin_device_approvals" />
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
);
|
||||
|
||||
@@ -113,7 +113,7 @@ from datetime import datetime, timezone
|
||||
from Modules import db_migrations
|
||||
from Modules.auth import jwt_service as jwt_service_module
|
||||
from Modules.auth.dpop import DPoPValidator
|
||||
from Modules.auth.device_auth import DeviceAuthManager, require_device_auth
|
||||
from Modules.auth.device_auth import DeviceAuthContext, DeviceAuthError, DeviceAuthManager, require_device_auth
|
||||
from Modules.auth.rate_limit import SlidingWindowRateLimiter
|
||||
from Modules.agents import routes as agent_routes
|
||||
from Modules.crypto import certificates, signing
|
||||
@@ -752,6 +752,9 @@ def health():
|
||||
# Endpoint: /api/repo/current_hash — cached GitHub head lookup for agents.
|
||||
@app.route("/api/repo/current_hash", methods=["GET"])
|
||||
def api_repo_current_hash():
|
||||
_, error = _authenticate_agent_request()
|
||||
if error is not None:
|
||||
return error
|
||||
try:
|
||||
repo = (request.args.get('repo') or _DEFAULT_REPO).strip()
|
||||
branch = (request.args.get('branch') or _DEFAULT_BRANCH).strip()
|
||||
@@ -1091,13 +1094,51 @@ def _collect_agent_hash_records() -> List[Dict[str, Any]]:
|
||||
return sanitized
|
||||
|
||||
|
||||
def _apply_agent_hash_update(agent_id: str, agent_hash: str, agent_guid: Optional[str] = None) -> Tuple[Dict[str, Any], int]:
|
||||
def _authenticate_agent_request() -> Tuple[Optional[DeviceAuthContext], Optional["flask.wrappers.Response"]]:
|
||||
"""
|
||||
Lightweight helper mirroring require_device_auth for endpoints declared before DEVICE_AUTH_MANAGER is initialised.
|
||||
|
||||
Returns a tuple of (context, error_response). Callers should return the response immediately when present.
|
||||
"""
|
||||
if DEVICE_AUTH_MANAGER is None:
|
||||
response = jsonify({"error": "auth_unavailable"})
|
||||
response.status_code = 503
|
||||
return None, response
|
||||
try:
|
||||
ctx = DEVICE_AUTH_MANAGER.authenticate()
|
||||
g.device_auth = ctx
|
||||
return ctx, None
|
||||
except DeviceAuthError as exc:
|
||||
response = jsonify({"error": exc.message})
|
||||
response.status_code = exc.status_code
|
||||
retry_after = getattr(exc, "retry_after", None)
|
||||
if retry_after:
|
||||
try:
|
||||
response.headers["Retry-After"] = str(max(1, int(retry_after)))
|
||||
except Exception:
|
||||
response.headers["Retry-After"] = "1"
|
||||
return None, response
|
||||
|
||||
|
||||
def _apply_agent_hash_update(
|
||||
agent_id: str,
|
||||
agent_hash: str,
|
||||
agent_guid: Optional[str] = None,
|
||||
auth_ctx: Optional[DeviceAuthContext] = None,
|
||||
) -> Tuple[Dict[str, Any], int]:
|
||||
agent_id = (agent_id or '').strip()
|
||||
agent_hash = (agent_hash or '').strip()
|
||||
normalized_guid = _normalize_guid(agent_guid)
|
||||
if not agent_hash or (not agent_id and not normalized_guid):
|
||||
return {'error': 'agent_hash and agent_guid or agent_id required'}, 400
|
||||
|
||||
auth_guid = _normalize_guid(getattr(auth_ctx, "guid", None)) if auth_ctx else None
|
||||
if auth_guid:
|
||||
if normalized_guid and normalized_guid != auth_guid:
|
||||
return {'error': 'guid_mismatch'}, 403
|
||||
if not normalized_guid:
|
||||
normalized_guid = auth_guid
|
||||
|
||||
conn = None
|
||||
hostname = None
|
||||
resolved_agent_id = agent_id
|
||||
@@ -1117,6 +1158,9 @@ def _apply_agent_hash_update(agent_id: str, agent_hash: str, agent_guid: Optiona
|
||||
updated_via_guid = True
|
||||
record = _row_to_device_dict(row, _DEVICE_TABLE_COLUMNS)
|
||||
snapshot = _assemble_device_snapshot(record)
|
||||
record_guid = _normalize_guid(record.get('guid'))
|
||||
if auth_guid and record_guid and record_guid != auth_guid:
|
||||
return {'error': 'guid_mismatch'}, 403
|
||||
hostname = snapshot.get('hostname')
|
||||
description = snapshot.get('description')
|
||||
details = snapshot.get('details', {})
|
||||
@@ -1162,6 +1206,9 @@ def _apply_agent_hash_update(agent_id: str, agent_hash: str, agent_guid: Optiona
|
||||
'agent_hash': agent_hash,
|
||||
}
|
||||
else:
|
||||
target_guid_norm = _normalize_guid(target.get('guid')) if target.get('guid') else None
|
||||
if auth_guid and target_guid_norm and target_guid_norm != auth_guid:
|
||||
return {'error': 'guid_mismatch'}, 403
|
||||
hostname = target.get('hostname')
|
||||
details = target.get('details') or {}
|
||||
summary = details.setdefault('summary', {})
|
||||
@@ -1257,6 +1304,12 @@ def _apply_agent_hash_update(agent_id: str, agent_hash: str, agent_guid: Optiona
|
||||
|
||||
@app.route("/api/agent/hash", methods=["GET", "POST"])
|
||||
def api_agent_hash():
|
||||
ctx, error = _authenticate_agent_request()
|
||||
if error is not None:
|
||||
return error
|
||||
auth_guid = _normalize_guid(getattr(ctx, "guid", None))
|
||||
if not auth_guid:
|
||||
return jsonify({'error': 'guid_required'}), 403
|
||||
if request.method == 'GET':
|
||||
agent_guid = _normalize_guid(request.args.get('agent_guid'))
|
||||
agent_id = (request.args.get('agent_id') or request.args.get('id') or '').strip()
|
||||
@@ -1264,16 +1317,32 @@ def api_agent_hash():
|
||||
data = request.get_json(silent=True) or {}
|
||||
agent_guid = _normalize_guid(data.get('agent_guid')) if data else agent_guid
|
||||
agent_id = (data.get('agent_id') or '').strip() if data else agent_id
|
||||
if agent_guid and agent_guid != auth_guid:
|
||||
return jsonify({'error': 'guid_mismatch'}), 403
|
||||
effective_guid = agent_guid or auth_guid
|
||||
try:
|
||||
record = None
|
||||
if agent_guid:
|
||||
record = _lookup_agent_hash_by_guid(agent_guid)
|
||||
if effective_guid:
|
||||
record = _lookup_agent_hash_by_guid(effective_guid)
|
||||
if not record and agent_id:
|
||||
record = _lookup_agent_hash_record(agent_id)
|
||||
if record:
|
||||
candidate_guid = _normalize_guid(record.get('agent_guid'))
|
||||
if candidate_guid and candidate_guid != auth_guid:
|
||||
return jsonify({'error': 'guid_mismatch'}), 403
|
||||
if not candidate_guid and effective_guid:
|
||||
record = dict(record)
|
||||
record['agent_guid'] = effective_guid
|
||||
except Exception as exc:
|
||||
_write_service_log('server', f'/api/agent/hash lookup error: {exc}')
|
||||
return jsonify({'error': 'internal error'}), 500
|
||||
if record:
|
||||
record_guid = _normalize_guid(record.get('agent_guid')) if record.get('agent_guid') else None
|
||||
if record_guid and record_guid != auth_guid:
|
||||
return jsonify({'error': 'guid_mismatch'}), 403
|
||||
if not record_guid:
|
||||
record = dict(record)
|
||||
record['agent_guid'] = auth_guid
|
||||
return jsonify(record)
|
||||
return jsonify({'error': 'agent hash not found'}), 404
|
||||
|
||||
@@ -1281,7 +1350,10 @@ def api_agent_hash():
|
||||
agent_id = (data.get('agent_id') or '').strip()
|
||||
agent_hash = (data.get('agent_hash') or '').strip()
|
||||
agent_guid = _normalize_guid(data.get('agent_guid')) if data else None
|
||||
payload, status = _apply_agent_hash_update(agent_id, agent_hash, agent_guid)
|
||||
if agent_guid and agent_guid != auth_guid:
|
||||
return jsonify({'error': 'guid_mismatch'}), 403
|
||||
effective_guid = agent_guid or auth_guid
|
||||
payload, status = _apply_agent_hash_update(agent_id, agent_hash, effective_guid, auth_ctx=ctx)
|
||||
return jsonify(payload), status
|
||||
|
||||
|
||||
|
||||
221
Update.ps1
221
Update.ps1
@@ -262,11 +262,22 @@ function Get-AgentGuid {
|
||||
[string]$AgentRoot
|
||||
)
|
||||
|
||||
$candidates = @()
|
||||
if (-not $AgentRoot) { $AgentRoot = $scriptDir }
|
||||
if ($AgentRoot) { $candidates += (Join-Path $AgentRoot 'agent_GUID') }
|
||||
$defaultPath = Join-Path $scriptDir 'Agent\Borealis\agent_GUID'
|
||||
if ($defaultPath -and ($candidates -notcontains $defaultPath)) { $candidates += $defaultPath }
|
||||
$candidates = @()
|
||||
if ($AgentRoot) {
|
||||
$settingsDir = Join-Path $AgentRoot 'Settings'
|
||||
if ($settingsDir) {
|
||||
$settingsGuid = Join-Path $settingsDir 'Agent_GUID.txt'
|
||||
if ($candidates -notcontains $settingsGuid) { $candidates += $settingsGuid }
|
||||
}
|
||||
$legacyPath = Join-Path $AgentRoot 'agent_GUID'
|
||||
if ($candidates -notcontains $legacyPath) { $candidates += $legacyPath }
|
||||
}
|
||||
|
||||
$projectSettingsGuid = Join-Path $scriptDir 'Agent\Borealis\Settings\Agent_GUID.txt'
|
||||
if ($candidates -notcontains $projectSettingsGuid) { $candidates += $projectSettingsGuid }
|
||||
$projectLegacyGuid = Join-Path $scriptDir 'Agent\Borealis\agent_GUID'
|
||||
if ($candidates -notcontains $projectLegacyGuid) { $candidates += $projectLegacyGuid }
|
||||
|
||||
foreach ($path in ($candidates | Select-Object -Unique)) {
|
||||
try {
|
||||
@@ -280,6 +291,164 @@ function Get-AgentGuid {
|
||||
return ''
|
||||
}
|
||||
|
||||
function Get-AgentSettingsDirectory {
|
||||
param(
|
||||
[string]$AgentRoot
|
||||
)
|
||||
|
||||
if (-not $AgentRoot) { $AgentRoot = $scriptDir }
|
||||
$settingsDir = Join-Path $AgentRoot 'Settings'
|
||||
if ($settingsDir -and (Test-Path $settingsDir -PathType Container)) {
|
||||
return $settingsDir
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function Get-ProtectedTokenString {
|
||||
param(
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
if (-not $Path -or -not (Test-Path $Path -PathType Leaf)) {
|
||||
return ''
|
||||
}
|
||||
|
||||
try {
|
||||
$protected = [System.IO.File]::ReadAllBytes($Path)
|
||||
if (-not $protected -or $protected.Length -eq 0) { return '' }
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
|
||||
$scopes = @(
|
||||
[System.Security.Cryptography.DataProtectionScope]::CurrentUser,
|
||||
[System.Security.Cryptography.DataProtectionScope]::LocalMachine
|
||||
)
|
||||
|
||||
foreach ($scope in $scopes) {
|
||||
try {
|
||||
$unprotected = [System.Security.Cryptography.ProtectedData]::Unprotect($protected, $null, $scope)
|
||||
if ($unprotected -and $unprotected.Length -gt 0) {
|
||||
return [System.Text.Encoding]::UTF8.GetString($unprotected)
|
||||
}
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
function Invoke-AgentTokenRefresh {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$ServerBaseUrl,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$AgentGuid,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$RefreshToken
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ServerBaseUrl) -or [string]::IsNullOrWhiteSpace($AgentGuid) -or [string]::IsNullOrWhiteSpace($RefreshToken)) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$base = $ServerBaseUrl.TrimEnd('/')
|
||||
$uri = "$base/api/agent/token/refresh"
|
||||
$payload = @{
|
||||
guid = $AgentGuid
|
||||
refresh_token = $RefreshToken
|
||||
} | ConvertTo-Json
|
||||
$headers = @{
|
||||
'User-Agent' = 'borealis-agent-updater'
|
||||
'Content-Type' = 'application/json'
|
||||
}
|
||||
|
||||
try {
|
||||
$resp = Invoke-WebRequest -Uri $uri -Method Post -Body $payload -Headers $headers -UseBasicParsing -ErrorAction Stop
|
||||
$json = $resp.Content | ConvertFrom-Json
|
||||
if ($json -and $json.access_token) {
|
||||
$expiresIn = 900
|
||||
try {
|
||||
if ($json.expires_in) {
|
||||
$expiresIn = [int]$json.expires_in
|
||||
}
|
||||
} catch {}
|
||||
$now = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
|
||||
$expiresAt = $now + [Math]::Max(0, $expiresIn - 5)
|
||||
return [pscustomobject]@{
|
||||
AccessToken = ($json.access_token).Trim()
|
||||
ExpiresAt = $expiresAt
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return $null
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
function Get-AgentAccessTokenContext {
|
||||
param(
|
||||
[string]$AgentRoot,
|
||||
[string]$ServerBaseUrl,
|
||||
[string]$AgentGuid
|
||||
)
|
||||
|
||||
$settingsDir = Get-AgentSettingsDirectory -AgentRoot $AgentRoot
|
||||
if (-not $settingsDir) { return $null }
|
||||
|
||||
$accessPath = Join-Path $settingsDir 'access.jwt'
|
||||
$metaPath = Join-Path $settingsDir 'access.meta.json'
|
||||
$refreshPath = Join-Path $settingsDir 'refresh.token'
|
||||
|
||||
$accessToken = ''
|
||||
$expiresAt = 0
|
||||
|
||||
if (Test-Path $accessPath -PathType Leaf) {
|
||||
try {
|
||||
$accessToken = (Get-Content -Path $accessPath -Raw -ErrorAction Stop).Trim()
|
||||
} catch {
|
||||
$accessToken = ''
|
||||
}
|
||||
}
|
||||
|
||||
if (Test-Path $metaPath -PathType Leaf) {
|
||||
try {
|
||||
$metaRaw = Get-Content -Path $metaPath -Raw -ErrorAction Stop
|
||||
if ($metaRaw) {
|
||||
$metaJson = $metaRaw | ConvertFrom-Json -ErrorAction Stop
|
||||
if ($metaJson -and $metaJson.access_expires_at) {
|
||||
$expiresAt = [int]$metaJson.access_expires_at
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
$expiresAt = 0
|
||||
}
|
||||
}
|
||||
|
||||
$now = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
|
||||
if ($accessToken -and $expiresAt -gt ($now + 30)) {
|
||||
return [pscustomobject]@{
|
||||
AccessToken = $accessToken
|
||||
ExpiresAt = $expiresAt
|
||||
}
|
||||
}
|
||||
|
||||
$refreshToken = Get-ProtectedTokenString -Path $refreshPath
|
||||
if (-not $refreshToken) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$refreshResult = Invoke-AgentTokenRefresh -ServerBaseUrl $ServerBaseUrl -AgentGuid $AgentGuid -RefreshToken $refreshToken
|
||||
if ($refreshResult -and $refreshResult.AccessToken) {
|
||||
return $refreshResult
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
function Get-RepositoryCommitHash {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
@@ -441,7 +610,8 @@ function Set-GitFetchHeadHash {
|
||||
function Get-ServerCurrentRepoHash {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$ServerBaseUrl
|
||||
[string]$ServerBaseUrl,
|
||||
[string]$AuthToken
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ServerBaseUrl)) { return $null }
|
||||
@@ -449,6 +619,9 @@ function Get-ServerCurrentRepoHash {
|
||||
$base = $ServerBaseUrl.TrimEnd('/')
|
||||
$uri = "$base/api/repo/current_hash"
|
||||
$headers = @{ 'User-Agent' = 'borealis-agent-updater' }
|
||||
if ($AuthToken -and $AuthToken.Trim()) {
|
||||
$headers['Authorization'] = "Bearer $AuthToken"
|
||||
}
|
||||
|
||||
try {
|
||||
$resp = Invoke-WebRequest -Uri $uri -Method Get -Headers $headers -UseBasicParsing -ErrorAction Stop
|
||||
@@ -470,7 +643,9 @@ function Submit-AgentHash {
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$AgentHash,
|
||||
|
||||
[string]$AgentGuid
|
||||
[string]$AgentGuid,
|
||||
|
||||
[string]$AuthToken
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ServerBaseUrl) -or [string]::IsNullOrWhiteSpace($AgentHash)) {
|
||||
@@ -484,6 +659,9 @@ function Submit-AgentHash {
|
||||
if (-not [string]::IsNullOrWhiteSpace($AgentGuid)) { $payloadBody.agent_guid = $AgentGuid }
|
||||
$payload = $payloadBody | ConvertTo-Json -Depth 3
|
||||
$headers = @{ 'User-Agent' = 'borealis-agent-updater' }
|
||||
if ($AuthToken -and $AuthToken.Trim()) {
|
||||
$headers['Authorization'] = "Bearer $AuthToken"
|
||||
}
|
||||
|
||||
$resp = Invoke-WebRequest -Uri $uri -Method Post -Headers $headers -Body $payload -ContentType 'application/json' -UseBasicParsing -ErrorAction Stop
|
||||
try {
|
||||
@@ -502,6 +680,7 @@ function Sync-AgentHashRecord {
|
||||
[string]$ServerBaseUrl,
|
||||
[string]$AgentId,
|
||||
[string]$AgentGuid,
|
||||
[string]$AuthToken = '',
|
||||
[string]$BranchName = 'main'
|
||||
)
|
||||
|
||||
@@ -524,16 +703,16 @@ function Sync-AgentHashRecord {
|
||||
}
|
||||
|
||||
try {
|
||||
$submitResult = Submit-AgentHash -ServerBaseUrl $ServerBaseUrl -AgentId $AgentId -AgentHash $AgentHash -AgentGuid $AgentGuid
|
||||
$submitResult = Submit-AgentHash -ServerBaseUrl $ServerBaseUrl -AgentId $AgentId -AgentHash $AgentHash -AgentGuid $AgentGuid -AuthToken $AuthToken
|
||||
if ($submitResult -and ($submitResult.status -eq 'ok')) {
|
||||
Write-Host "Server agent_hash database record updated successfully."
|
||||
Write-Host "The server-side agent hash database record was updated successfully."
|
||||
} elseif ($submitResult -and ($submitResult.status -eq 'ignored')) {
|
||||
Write-Host "Server ignored agent_hash update (agent not registered)." -ForegroundColor DarkYellow
|
||||
Write-Host "Server ignored the agent hash update (the agent is not enrolled with the server)." -ForegroundColor DarkYellow
|
||||
} elseif ($submitResult) {
|
||||
Write-Host "Server agent_hash update response unrecognized." -ForegroundColor DarkYellow
|
||||
Write-Host "Server agent_hash update response unrecognized. We don't know what to do here. (Panic)" -ForegroundColor DarkYellow
|
||||
}
|
||||
} catch {
|
||||
Write-Verbose ("Failed to submit agent hash: {0}" -f $_.Exception.Message)
|
||||
Write-Verbose ("Failed to Submit Agent Hash: {0}" -f $_.Exception.Message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,7 +875,15 @@ function Invoke-BorealisAgentUpdate {
|
||||
$serverBaseUrl = Get-BorealisServerUrl -AgentRoot $agentRoot
|
||||
$agentId = Get-AgentServiceId -AgentRoot $agentRoot
|
||||
|
||||
$serverRepoInfo = Get-ServerCurrentRepoHash -ServerBaseUrl $serverBaseUrl
|
||||
$authContext = Get-AgentAccessTokenContext -AgentRoot $agentRoot -ServerBaseUrl $serverBaseUrl -AgentGuid $agentGuid
|
||||
if (-not $authContext -or -not $authContext.AccessToken) {
|
||||
Write-Host "Unable to obtain agent authentication token. Ensure the agent is running and enrolled, then rerun the updater." -ForegroundColor Yellow
|
||||
Write-Host "⚠️ Borealis update aborted."
|
||||
return
|
||||
}
|
||||
$authToken = $authContext.AccessToken
|
||||
|
||||
$serverRepoInfo = Get-ServerCurrentRepoHash -ServerBaseUrl $serverBaseUrl -AuthToken $authToken
|
||||
$serverHash = ''
|
||||
$serverBranch = 'main'
|
||||
if ($serverRepoInfo) {
|
||||
@@ -736,7 +923,7 @@ function Invoke-BorealisAgentUpdate {
|
||||
return
|
||||
} elseif (-not $needsUpdate) {
|
||||
Write-Host "Local agent files already match the server repository hash." -ForegroundColor Green
|
||||
Sync-AgentHashRecord -ProjectRoot $scriptDir -AgentRoot $agentRoot -AgentHash $serverHash -ServerBaseUrl $serverBaseUrl -AgentId $agentId -AgentGuid $agentGuid -BranchName $serverBranch
|
||||
Sync-AgentHashRecord -ProjectRoot $scriptDir -AgentRoot $agentRoot -AgentHash $serverHash -ServerBaseUrl $serverBaseUrl -AgentId $agentId -AgentGuid $agentGuid -AuthToken $authToken -BranchName $serverBranch
|
||||
Write-Host "✅ Borealis - Automation Platform Already Up-to-Date"
|
||||
return
|
||||
} else {
|
||||
@@ -780,7 +967,11 @@ function Invoke-BorealisAgentUpdate {
|
||||
throw 'Borealis update failed.'
|
||||
}
|
||||
|
||||
$postUpdateInfo = Get-ServerCurrentRepoHash -ServerBaseUrl $serverBaseUrl
|
||||
$refreshedContext = Get-AgentAccessTokenContext -AgentRoot $agentRoot -ServerBaseUrl $serverBaseUrl -AgentGuid $agentGuid
|
||||
if ($refreshedContext -and $refreshedContext.AccessToken) {
|
||||
$authToken = $refreshedContext.AccessToken
|
||||
}
|
||||
$postUpdateInfo = Get-ServerCurrentRepoHash -ServerBaseUrl $serverBaseUrl -AuthToken $authToken
|
||||
if ($postUpdateInfo) {
|
||||
try {
|
||||
$refreshedSha = (($postUpdateInfo.sha) -as [string]).Trim()
|
||||
@@ -805,7 +996,7 @@ function Invoke-BorealisAgentUpdate {
|
||||
}
|
||||
|
||||
if ($newHash) {
|
||||
Sync-AgentHashRecord -ProjectRoot $scriptDir -AgentRoot $agentRoot -AgentHash $newHash -ServerBaseUrl $serverBaseUrl -AgentId $agentId -AgentGuid $agentGuid -BranchName $serverBranch
|
||||
Sync-AgentHashRecord -ProjectRoot $scriptDir -AgentRoot $agentRoot -AgentHash $newHash -ServerBaseUrl $serverBaseUrl -AgentId $agentId -AgentGuid $agentGuid -AuthToken $authToken -BranchName $serverBranch
|
||||
} else {
|
||||
Write-Host "Unable to determine repository hash for submission; server hash not updated." -ForegroundColor DarkYellow
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user