diff --git a/scripts/deploy-yggdrasil-heimdall.cmd b/scripts/deploy-yggdrasil-heimdall.cmd deleted file mode 100644 index d15d7b0..0000000 --- a/scripts/deploy-yggdrasil-heimdall.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually. - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually. - exit /b 1 -) -powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0deploy-yggdrasil-heimdall.ps1 diff --git a/scripts/deploy-yggdrasil-heimdall.ps1 b/scripts/deploy-yggdrasil-heimdall.ps1 deleted file mode 100644 index f7d46cc..0000000 --- a/scripts/deploy-yggdrasil-heimdall.ps1 +++ /dev/null @@ -1,156 +0,0 @@ -param( - [string] $SshTarget = "yggdrasil", - [string] $RepoRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "Heimdall"), - [string] $CultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"), - [string] $AppUser = "heimdall", - [string] $RemoteAppHome = "/srv/heimdall", - [string] $RemoteTarballName = "heimdall-source.tar", - [string] $RemoteCultLibTarballName = "heimdall-cultlib.tar", - [string] $DeployScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\deploy-heimdall.sh"), - [string] $CheckScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\check-heimdall.sh"), - [string] $UpstreamRemote = "origin", - [string] $UpstreamBranch = "main", - [string] $CultLibUpstreamRemote = "origin", - [string] $CultLibUpstreamBranch = "main" -) - -$ErrorActionPreference = "Stop" - -if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") { - throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually." -} - -foreach ($path in @($RepoRoot, $CultLibRoot, $DeployScript, $CheckScript)) { - if (-not (Test-Path -LiteralPath $path)) { - throw "Required path not found: $path" - } -} - -$sourceRef = "$UpstreamRemote/$UpstreamBranch" -$cultLibSourceRef = "$CultLibUpstreamRemote/$CultLibUpstreamBranch" -git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch -if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $RepoRoot $sourceRef" } -git -C $CultLibRoot fetch --prune $CultLibUpstreamRemote $CultLibUpstreamBranch -if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $CultLibRoot $cultLibSourceRef" } - -$heimdallCommit = (git -C $RepoRoot rev-parse $sourceRef).Trim() -if ([string]::IsNullOrWhiteSpace($heimdallCommit)) { - throw "Could not determine Heimdall git revision." -} -$cultLibCommit = (git -C $CultLibRoot rev-parse $cultLibSourceRef).Trim() -if ([string]::IsNullOrWhiteSpace($cultLibCommit)) { - throw "Could not determine CultLib git revision." -} - -$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") "yggdrasil-heimdall" -$sourceTarPath = Join-Path $scratch $RemoteTarballName -$cultLibTarPath = Join-Path $scratch $RemoteCultLibTarballName -$manifestPath = Join-Path $scratch "deployment-manifest.txt" -New-Item -ItemType Directory -Force -Path $scratch | Out-Null - -git -C $RepoRoot archive --format=tar --output=$sourceTarPath $sourceRef -if ($LASTEXITCODE -ne 0) { - throw "git archive failed for $RepoRoot $sourceRef" -} - -if (Test-Path -LiteralPath $cultLibTarPath) { - Remove-Item -LiteralPath $cultLibTarPath -Force -} -git -C $CultLibRoot archive --format=tar --output=$cultLibTarPath $cultLibSourceRef packages/cultnet-ts packages/cultcache-ts -if ($LASTEXITCODE -ne 0) { - throw "CultLib tar build failed for $CultLibRoot $cultLibSourceRef" -} - -$sourceHash = (Get-FileHash $sourceTarPath -Algorithm SHA256).Hash.ToLowerInvariant() -$cultLibHash = (Get-FileHash $cultLibTarPath -Algorithm SHA256).Hash.ToLowerInvariant() -$deployedAt = [DateTimeOffset]::UtcNow.ToString("O") -@( - "schema=gamecult.idunn.deployment_manifest.v1" - "appId=yggdrasil-heimdall" - "repoRoot=$RepoRoot" - "upstreamRemote=$UpstreamRemote" - "upstreamBranch=$UpstreamBranch" - "sourceRef=$sourceRef" - "gitCommit=$heimdallCommit" - "artifact=$RemoteTarballName" - "sha256=$sourceHash" - "cultLibRepoRoot=$CultLibRoot" - "cultLibUpstreamRemote=$CultLibUpstreamRemote" - "cultLibUpstreamBranch=$CultLibUpstreamBranch" - "cultLibSourceRef=$cultLibSourceRef" - "cultLibGitCommit=$cultLibCommit" - "cultLibArtifact=$RemoteCultLibTarballName" - "cultLibSha256=$cultLibHash" - "deployedAtUtc=$deployedAt" -) | Set-Content -Encoding ASCII -LiteralPath $manifestPath - -$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))" -$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))" -$remoteSourceTarball = "/home/gamecultadmin/$RemoteTarballName" -$remoteCultLibTarball = "/home/gamecultadmin/$RemoteCultLibTarballName" -$remoteManifest = "/home/gamecultadmin/yggdrasil-heimdall-deployment-manifest.txt" -$remoteRunner = "/home/gamecultadmin/run-yggdrasil-heimdall-deploy.sh" -$targetSourceTarball = "$RemoteAppHome/$RemoteTarballName" -$targetCultLibTarball = "$RemoteAppHome/$RemoteCultLibTarballName" -$targetManifest = "$RemoteAppHome/deployment-manifest.txt" - -$sftpBatchPath = Join-Path $scratch "yggdrasil-heimdall-upload.sftp" -$runnerPath = Join-Path $scratch "run-yggdrasil-heimdall-deploy.sh" -$runnerScript = @" -#!/usr/bin/env bash -set -euo pipefail - -sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome' -sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteSourceTarball' '$targetSourceTarball' -sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteCultLibTarball' '$targetCultLibTarball' -sudo -n install -m 644 '$remoteManifest' '$targetManifest' -chmod +x '$remoteDeploy' '$remoteCheck' -sudo -n env GAMECULT_IDUNN_REMOTE_ACTUATOR=1 IDUNN_COMMAND_AUTHORITY=idunn-daemon bash '$remoteDeploy' - -check_ok=0 -for i in `$(seq 1 30); do - if sudo -n bash '$remoteCheck'; then - check_ok=1 - break - fi - sleep 2 -done - -if [ "`$check_ok" -ne 1 ]; then - sudo -n bash '$remoteCheck' - exit 1 -fi -"@.Replace("`r`n", "`n") -[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII) -@( - "put ""$sourceTarPath"" ""$remoteSourceTarball""" - "put ""$cultLibTarPath"" ""$remoteCultLibTarball""" - "put ""$DeployScript"" ""$remoteDeploy""" - "put ""$CheckScript"" ""$remoteCheck""" - "put ""$manifestPath"" ""$remoteManifest""" - "put ""$runnerPath"" ""$remoteRunner""" -) | Set-Content -Encoding ASCII -LiteralPath $sftpBatchPath - -try { - & sftp.exe -b $sftpBatchPath $SshTarget - if ($LASTEXITCODE -ne 0) { - throw "sftp upload failed for yggdrasil-heimdall" - } - - & ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "chmod +x '$remoteRunner' && bash '$remoteRunner'" - $remoteExit = $LASTEXITCODE - & ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "rm -f '$remoteRunner'" - if ($remoteExit -ne 0) { - throw "remote deploy/check failed for yggdrasil-heimdall" - } -} -finally { - Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue - Remove-Item -LiteralPath $sftpBatchPath -Force -ErrorAction SilentlyContinue -} - -Write-Host "yggdrasil-heimdall deployed with CultLib snapshot." -Write-Host " heimdallCommit=$heimdallCommit" -Write-Host " cultLibCommit=$cultLibCommit" -Write-Host " artifactSha256=$sourceHash" -Write-Host " cultLibSha256=$cultLibHash" diff --git a/scripts/deploy-yggdrasil-repixelizer.cmd b/scripts/deploy-yggdrasil-repixelizer.cmd deleted file mode 100644 index ec0edcc..0000000 --- a/scripts/deploy-yggdrasil-repixelizer.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually. - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually. - exit /b 1 -) -powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0deploy-yggdrasil-repixelizer.ps1 diff --git a/scripts/deploy-yggdrasil-repixelizer.ps1 b/scripts/deploy-yggdrasil-repixelizer.ps1 deleted file mode 100644 index d25bbd1..0000000 --- a/scripts/deploy-yggdrasil-repixelizer.ps1 +++ /dev/null @@ -1,161 +0,0 @@ -param( - [string] $SshTarget = "yggdrasil", - [string] $RepoRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "repixelizer"), - [string] $CultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"), - [string] $AppUser = "repixelizer", - [string] $RemoteAppHome = "/srv/repixelizer", - [string] $RemoteTarballName = "repixelizer-source.tar", - [string] $RemoteCultLibTarballName = "repixelizer-cultlib.tar", - [string] $DeployScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\deploy-repixelizer-gui.sh"), - [string] $CheckScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\check-repixelizer-gui.sh"), - [string] $UpstreamRemote = "origin", - [string] $UpstreamBranch = "main", - [string] $CultLibUpstreamRemote = "origin", - [string] $CultLibUpstreamBranch = "main" -) - -$ErrorActionPreference = "Stop" - -if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") { - throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually." -} - -foreach ($path in @($RepoRoot, $CultLibRoot, $DeployScript, $CheckScript)) { - if (-not (Test-Path -LiteralPath $path)) { - throw "Required path not found: $path" - } -} - -$sourceRef = "$UpstreamRemote/$UpstreamBranch" -$cultLibSourceRef = "$CultLibUpstreamRemote/$CultLibUpstreamBranch" -git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch -if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $RepoRoot $sourceRef" } -git -C $CultLibRoot fetch --prune $CultLibUpstreamRemote $CultLibUpstreamBranch -if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $CultLibRoot $cultLibSourceRef" } - -$repixelizerCommit = (git -C $RepoRoot rev-parse $sourceRef).Trim() -if ([string]::IsNullOrWhiteSpace($repixelizerCommit)) { - throw "Could not determine Repixelizer git revision." -} - -$cultLibCommit = (git -C $CultLibRoot rev-parse $cultLibSourceRef).Trim() -if ([string]::IsNullOrWhiteSpace($cultLibCommit)) { - throw "Could not determine CultLib git revision." -} - -$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") "yggdrasil-repixelizer" -$sourceTarPath = Join-Path $scratch $RemoteTarballName -$cultLibTarPath = Join-Path $scratch $RemoteCultLibTarballName -$manifestPath = Join-Path $scratch "deployment-manifest.txt" -New-Item -ItemType Directory -Force -Path $scratch | Out-Null - -git -C $RepoRoot archive --format=tar --output=$sourceTarPath $sourceRef -if ($LASTEXITCODE -ne 0) { - throw "git archive failed for $RepoRoot $sourceRef" -} - -if (Test-Path -LiteralPath $cultLibTarPath) { - Remove-Item -LiteralPath $cultLibTarPath -Force -} -# All three Python packages. CultLib split packages/cultcache-py into -# cultcache-py / cultnet-py / cultmesh-py; module names did not change, so -# archiving only the first still succeeds and ships an incomplete library -# that fails later as an ImportError, far from this line. -git -C $CultLibRoot archive --format=tar --output=$cultLibTarPath $cultLibSourceRef packages/cultcache-py packages/cultnet-py packages/cultmesh-py -if ($LASTEXITCODE -ne 0) { - throw "CultLib tar build failed for $CultLibRoot $cultLibSourceRef" -} - -$sourceHash = (Get-FileHash $sourceTarPath -Algorithm SHA256).Hash.ToLowerInvariant() -$cultLibHash = (Get-FileHash $cultLibTarPath -Algorithm SHA256).Hash.ToLowerInvariant() -$deployedAt = [DateTimeOffset]::UtcNow.ToString("O") -@( - "schema=gamecult.idunn.deployment_manifest.v1" - "appId=yggdrasil-repixelizer" - "repoRoot=$RepoRoot" - "upstreamRemote=$UpstreamRemote" - "upstreamBranch=$UpstreamBranch" - "sourceRef=$sourceRef" - "gitCommit=$repixelizerCommit" - "artifact=$RemoteTarballName" - "sha256=$sourceHash" - "cultLibRepoRoot=$CultLibRoot" - "cultLibUpstreamRemote=$CultLibUpstreamRemote" - "cultLibUpstreamBranch=$CultLibUpstreamBranch" - "cultLibSourceRef=$cultLibSourceRef" - "cultLibGitCommit=$cultLibCommit" - "cultLibArtifact=$RemoteCultLibTarballName" - "cultLibSha256=$cultLibHash" - "deployedAtUtc=$deployedAt" -) | Set-Content -Encoding ASCII -LiteralPath $manifestPath - -$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))" -$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))" -$remoteSourceTarball = "/home/gamecultadmin/$RemoteTarballName" -$remoteCultLibTarball = "/home/gamecultadmin/$RemoteCultLibTarballName" -$remoteManifest = "/home/gamecultadmin/yggdrasil-repixelizer-deployment-manifest.txt" -$remoteRunner = "/home/gamecultadmin/run-yggdrasil-repixelizer-deploy.sh" -$targetSourceTarball = "$RemoteAppHome/$RemoteTarballName" -$targetCultLibTarball = "$RemoteAppHome/$RemoteCultLibTarballName" -$targetManifest = "$RemoteAppHome/deployment-manifest.txt" - -$sftpBatchPath = Join-Path $scratch "yggdrasil-repixelizer-upload.sftp" -$runnerPath = Join-Path $scratch "run-yggdrasil-repixelizer-deploy.sh" -$runnerScript = @" -#!/usr/bin/env bash -set -euo pipefail - -sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome' -sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteSourceTarball' '$targetSourceTarball' -sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteCultLibTarball' '$targetCultLibTarball' -sudo -n install -m 644 '$remoteManifest' '$targetManifest' -chmod +x '$remoteDeploy' '$remoteCheck' -sudo -n env GAMECULT_IDUNN_REMOTE_ACTUATOR=1 IDUNN_COMMAND_AUTHORITY=idunn-daemon bash '$remoteDeploy' - -check_ok=0 -for i in `$(seq 1 30); do - if sudo -n bash '$remoteCheck'; then - check_ok=1 - break - fi - sleep 2 -done - -if [ "`$check_ok" -ne 1 ]; then - sudo -n bash '$remoteCheck' - exit 1 -fi -"@.Replace("`r`n", "`n") -[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII) -@( - "put ""$sourceTarPath"" ""$remoteSourceTarball""" - "put ""$cultLibTarPath"" ""$remoteCultLibTarball""" - "put ""$DeployScript"" ""$remoteDeploy""" - "put ""$CheckScript"" ""$remoteCheck""" - "put ""$manifestPath"" ""$remoteManifest""" - "put ""$runnerPath"" ""$remoteRunner""" -) | Set-Content -Encoding ASCII -LiteralPath $sftpBatchPath - -try { - & sftp.exe -b $sftpBatchPath $SshTarget - if ($LASTEXITCODE -ne 0) { - throw "sftp upload failed for yggdrasil-repixelizer" - } - - & ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "chmod +x '$remoteRunner' && bash '$remoteRunner'" - $remoteExit = $LASTEXITCODE - & ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "rm -f '$remoteRunner'" - if ($remoteExit -ne 0) { - throw "remote deploy/check failed for yggdrasil-repixelizer" - } -} -finally { - Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue - Remove-Item -LiteralPath $sftpBatchPath -Force -ErrorAction SilentlyContinue -} - -Write-Host "yggdrasil-repixelizer deployed with CultLib snapshot." -Write-Host " repixelizerCommit=$repixelizerCommit" -Write-Host " cultLibCommit=$cultLibCommit" -Write-Host " artifactSha256=$sourceHash" -Write-Host " cultLibSha256=$cultLibHash" diff --git a/scripts/deploy-yggdrasil-source-app.ps1 b/scripts/deploy-yggdrasil-source-app.ps1 deleted file mode 100644 index 15408f2..0000000 --- a/scripts/deploy-yggdrasil-source-app.ps1 +++ /dev/null @@ -1,137 +0,0 @@ -param( - [Parameter(Mandatory = $true)] [string] $AppId, - [Parameter(Mandatory = $true)] [string] $RepoRoot, - [Parameter(Mandatory = $true)] [string] $AppUser, - [Parameter(Mandatory = $true)] [string] $RemoteAppHome, - [Parameter(Mandatory = $true)] [string] $RemoteTarballName, - [Parameter(Mandatory = $true)] [string] $DeployScript, - [Parameter(Mandatory = $true)] [string] $CheckScript, - [string] $SshTarget = "yggdrasil", - [string] $UpstreamRemote = "origin", - [string] $UpstreamBranch = "main", - [string] $StateMigrationScript = "" -) - -$ErrorActionPreference = "Stop" - -if ($env:IDUNN_ACTUATOR -ne "1") { - throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually." -} - -if (-not (Test-Path -LiteralPath $RepoRoot)) { - throw "Repo root not found: $RepoRoot" -} -if (-not (Test-Path -LiteralPath $DeployScript)) { - throw "Deploy script not found: $DeployScript" -} -if (-not (Test-Path -LiteralPath $CheckScript)) { - throw "Check script not found: $CheckScript" -} -if (-not [string]::IsNullOrWhiteSpace($StateMigrationScript) -and -not (Test-Path -LiteralPath $StateMigrationScript)) { - throw "State migration script not found: $StateMigrationScript" -} - -git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch -if ($LASTEXITCODE -ne 0) { - throw "git fetch failed for $RepoRoot $UpstreamRemote/$UpstreamBranch" -} - -$sourceRef = "$UpstreamRemote/$UpstreamBranch" -$commit = (git -C $RepoRoot rev-parse $sourceRef).Trim() -if ([string]::IsNullOrWhiteSpace($commit)) { - throw "Could not determine git revision for $RepoRoot $sourceRef" -} - -$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") $AppId -$tarPath = Join-Path $scratch $RemoteTarballName -$manifestPath = Join-Path $scratch "deployment-manifest.txt" -New-Item -ItemType Directory -Force -Path $scratch | Out-Null - -git -C $RepoRoot archive --format=tar --output=$tarPath $sourceRef -if ($LASTEXITCODE -ne 0) { - throw "git archive failed for $RepoRoot $sourceRef" -} - -$hash = (Get-FileHash $tarPath -Algorithm SHA256).Hash.ToLowerInvariant() -$deployedAt = [DateTimeOffset]::UtcNow.ToString("O") -@( - "schema=gamecult.idunn.deployment_manifest.v1" - "appId=$AppId" - "repoRoot=$RepoRoot" - "upstreamRemote=$UpstreamRemote" - "upstreamBranch=$UpstreamBranch" - "sourceRef=$sourceRef" - "gitCommit=$commit" - "artifact=$RemoteTarballName" - "sha256=$hash" - "deployedAtUtc=$deployedAt" -) | Set-Content -Encoding ASCII -LiteralPath $manifestPath - -$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))" -$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))" -$remoteMigration = if ([string]::IsNullOrWhiteSpace($StateMigrationScript)) { "" } else { "/home/gamecultadmin/$([IO.Path]::GetFileName($StateMigrationScript))" } -$remoteTarball = "/home/gamecultadmin/$RemoteTarballName" -$remoteManifest = "/home/gamecultadmin/$AppId-deployment-manifest.txt" -$remoteRunner = "/home/gamecultadmin/run-$AppId-deploy.sh" -$targetTarball = "$RemoteAppHome/$RemoteTarballName" -$targetManifest = "$RemoteAppHome/deployment-manifest.txt" -$sshArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10", $SshTarget) -$scpArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10") -$runnerPath = Join-Path $scratch "run-$AppId-deploy.sh" - -$runnerScript = @" -#!/usr/bin/env bash -set -euo pipefail - -sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome' -sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteTarball' '$targetTarball' -sudo -n install -m 644 '$remoteManifest' '$targetManifest' -chmod +x '$remoteDeploy' '$remoteCheck' -if [ -n '$remoteMigration' ]; then - chmod +x '$remoteMigration' - sudo -n bash '$remoteMigration' -fi -sudo -n bash '$remoteDeploy' - -check_ok=0 -for i in `$(seq 1 30); do - if sudo -n bash '$remoteCheck'; then - check_ok=1 - break - fi - sleep 2 -done - -if [ "`$check_ok" -ne 1 ]; then - sudo -n bash '$remoteCheck' - exit 1 -fi -"@.Replace("`r`n", "`n") -[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII) - -scp.exe @scpArgs $tarPath "${SshTarget}:$remoteTarball" -if ($LASTEXITCODE -ne 0) { throw "scp source tarball failed for $AppId" } -scp.exe @scpArgs $DeployScript "${SshTarget}:$remoteDeploy" -if ($LASTEXITCODE -ne 0) { throw "scp deploy script failed for $AppId" } -scp.exe @scpArgs $CheckScript "${SshTarget}:$remoteCheck" -if ($LASTEXITCODE -ne 0) { throw "scp check script failed for $AppId" } -if (-not [string]::IsNullOrWhiteSpace($StateMigrationScript)) { - scp.exe @scpArgs $StateMigrationScript "${SshTarget}:$remoteMigration" - if ($LASTEXITCODE -ne 0) { throw "scp state migration script failed for $AppId" } -} -scp.exe @scpArgs $manifestPath "${SshTarget}:$remoteManifest" -if ($LASTEXITCODE -ne 0) { throw "scp manifest failed for $AppId" } -scp.exe @scpArgs $runnerPath "${SshTarget}:$remoteRunner" -if ($LASTEXITCODE -ne 0) { throw "scp runner script failed for $AppId" } - -ssh.exe @sshArgs "chmod +x '$remoteRunner' && bash '$remoteRunner'" -$remoteExit = $LASTEXITCODE -ssh.exe @sshArgs "rm -f '$remoteRunner'" -if ($remoteExit -ne 0) { - throw "remote deploy/check failed for $AppId" -} - -Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue - -Write-Host "$AppId deployed to Yggdrasil from $sourceRef at $commit." -Write-Host " artifactSha256=$hash" diff --git a/scripts/deploy-yggdrasil-streampixels.cmd b/scripts/deploy-yggdrasil-streampixels.cmd deleted file mode 100644 index 7c05142..0000000 --- a/scripts/deploy-yggdrasil-streampixels.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually. - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually. - exit /b 1 -) -powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0deploy-yggdrasil-streampixels.ps1 diff --git a/scripts/deploy-yggdrasil-streampixels.ps1 b/scripts/deploy-yggdrasil-streampixels.ps1 deleted file mode 100644 index d275abf..0000000 --- a/scripts/deploy-yggdrasil-streampixels.ps1 +++ /dev/null @@ -1,156 +0,0 @@ -param( - [string] $SshTarget = "yggdrasil", - [string] $RepoRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "StreamPixels"), - [string] $CultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"), - [string] $AppUser = "streampixels", - [string] $RemoteAppHome = "/srv/streampixels", - [string] $RemoteTarballName = "streampixels-source.tar", - [string] $RemoteCultLibTarballName = "streampixels-cultlib.tar", - [string] $DeployScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\deploy-streampixels-preview.sh"), - [string] $CheckScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\check-streampixels-preview.sh"), - [string] $UpstreamRemote = "origin", - [string] $UpstreamBranch = "main", - [string] $CultLibUpstreamRemote = "origin", - [string] $CultLibUpstreamBranch = "main" -) - -$ErrorActionPreference = "Stop" - -if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") { - throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually." -} - -foreach ($path in @($RepoRoot, $CultLibRoot, $DeployScript, $CheckScript)) { - if (-not (Test-Path -LiteralPath $path)) { - throw "Required path not found: $path" - } -} - -$sourceRef = "$UpstreamRemote/$UpstreamBranch" -$cultLibSourceRef = "$CultLibUpstreamRemote/$CultLibUpstreamBranch" -git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch -if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $RepoRoot $sourceRef" } -git -C $CultLibRoot fetch --prune $CultLibUpstreamRemote $CultLibUpstreamBranch -if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $CultLibRoot $cultLibSourceRef" } - -$streamPixelsCommit = (git -C $RepoRoot rev-parse $sourceRef).Trim() -if ([string]::IsNullOrWhiteSpace($streamPixelsCommit)) { - throw "Could not determine StreamPixels git revision." -} -$cultLibCommit = (git -C $CultLibRoot rev-parse $cultLibSourceRef).Trim() -if ([string]::IsNullOrWhiteSpace($cultLibCommit)) { - throw "Could not determine CultLib git revision." -} - -$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") "yggdrasil-streampixels" -$sourceTarPath = Join-Path $scratch $RemoteTarballName -$cultLibTarPath = Join-Path $scratch $RemoteCultLibTarballName -$manifestPath = Join-Path $scratch "deployment-manifest.txt" -New-Item -ItemType Directory -Force -Path $scratch | Out-Null - -git -C $RepoRoot archive --format=tar --output=$sourceTarPath $sourceRef -if ($LASTEXITCODE -ne 0) { - throw "git archive failed for $RepoRoot $sourceRef" -} - -if (Test-Path -LiteralPath $cultLibTarPath) { - Remove-Item -LiteralPath $cultLibTarPath -Force -} -git -C $CultLibRoot archive --format=tar --output=$cultLibTarPath $cultLibSourceRef package.json package-lock.json scripts/run-typescript-workspaces.mjs contracts/cultnet packages/cultcache-ts packages/cultnet-ts packages/cultmesh-ts packages/cultmesh-browser -if ($LASTEXITCODE -ne 0) { - throw "CultLib tar build failed for $CultLibRoot $cultLibSourceRef" -} - -$sourceHash = (Get-FileHash $sourceTarPath -Algorithm SHA256).Hash.ToLowerInvariant() -$cultLibHash = (Get-FileHash $cultLibTarPath -Algorithm SHA256).Hash.ToLowerInvariant() -$deployedAt = [DateTimeOffset]::UtcNow.ToString("O") -@( - "schema=gamecult.idunn.deployment_manifest.v1" - "appId=yggdrasil-streampixels" - "repoRoot=$RepoRoot" - "upstreamRemote=$UpstreamRemote" - "upstreamBranch=$UpstreamBranch" - "sourceRef=$sourceRef" - "gitCommit=$streamPixelsCommit" - "artifact=$RemoteTarballName" - "sha256=$sourceHash" - "cultLibRepoRoot=$CultLibRoot" - "cultLibUpstreamRemote=$CultLibUpstreamRemote" - "cultLibUpstreamBranch=$CultLibUpstreamBranch" - "cultLibSourceRef=$cultLibSourceRef" - "cultLibGitCommit=$cultLibCommit" - "cultLibArtifact=$RemoteCultLibTarballName" - "cultLibSha256=$cultLibHash" - "deployedAtUtc=$deployedAt" -) | Set-Content -Encoding ASCII -LiteralPath $manifestPath - -$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))" -$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))" -$remoteSourceTarball = "/home/gamecultadmin/$RemoteTarballName" -$remoteCultLibTarball = "/home/gamecultadmin/$RemoteCultLibTarballName" -$remoteManifest = "/home/gamecultadmin/yggdrasil-streampixels-deployment-manifest.txt" -$remoteRunner = "/home/gamecultadmin/run-yggdrasil-streampixels-deploy.sh" -$targetSourceTarball = "$RemoteAppHome/$RemoteTarballName" -$targetCultLibTarball = "$RemoteAppHome/$RemoteCultLibTarballName" -$targetManifest = "$RemoteAppHome/deployment-manifest.txt" - -$sftpBatchPath = Join-Path $scratch "yggdrasil-streampixels-upload.sftp" -$runnerPath = Join-Path $scratch "run-yggdrasil-streampixels-deploy.sh" -$runnerScript = @" -#!/usr/bin/env bash -set -euo pipefail - -sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome' -sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteSourceTarball' '$targetSourceTarball' -sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteCultLibTarball' '$targetCultLibTarball' -sudo -n install -m 644 '$remoteManifest' '$targetManifest' -chmod +x '$remoteDeploy' '$remoteCheck' -sudo -n env GAMECULT_IDUNN_REMOTE_ACTUATOR=1 IDUNN_COMMAND_AUTHORITY=idunn-daemon bash '$remoteDeploy' - -check_ok=0 -for i in `$(seq 1 30); do - if sudo -n bash '$remoteCheck'; then - check_ok=1 - break - fi - sleep 2 -done - -if [ "`$check_ok" -ne 1 ]; then - sudo -n bash '$remoteCheck' - exit 1 -fi -"@.Replace("`r`n", "`n") -[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII) -@( - "put ""$sourceTarPath"" ""$remoteSourceTarball""" - "put ""$cultLibTarPath"" ""$remoteCultLibTarball""" - "put ""$DeployScript"" ""$remoteDeploy""" - "put ""$CheckScript"" ""$remoteCheck""" - "put ""$manifestPath"" ""$remoteManifest""" - "put ""$runnerPath"" ""$remoteRunner""" -) | Set-Content -Encoding ASCII -LiteralPath $sftpBatchPath - -try { - & sftp.exe -b $sftpBatchPath $SshTarget - if ($LASTEXITCODE -ne 0) { - throw "sftp upload failed for yggdrasil-streampixels" - } - - & ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "chmod +x '$remoteRunner' && bash '$remoteRunner'" - $remoteExit = $LASTEXITCODE - & ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "rm -f '$remoteRunner'" - if ($remoteExit -ne 0) { - throw "remote deploy/check failed for yggdrasil-streampixels" - } -} -finally { - Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue - Remove-Item -LiteralPath $sftpBatchPath -Force -ErrorAction SilentlyContinue -} - -Write-Host "yggdrasil-streampixels deployed with CultLib snapshot." -Write-Host " streamPixelsCommit=$streamPixelsCommit" -Write-Host " cultLibCommit=$cultLibCommit" -Write-Host " artifactSha256=$sourceHash" -Write-Host " cultLibSha256=$cultLibHash" diff --git a/scripts/health-mimir-eve-dashboard.cmd b/scripts/health-mimir-eve-dashboard.cmd deleted file mode 100644 index aaea10f..0000000 --- a/scripts/health-mimir-eve-dashboard.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-mimir-eve-dashboard.cmd archived: Mimir Eve dashboard health is daemon-published over CultNet/RUDP as mimir.cultnet-rudp-provider-health. Do not probe localhost HTTP for daemon health. 1>&2 -exit /b 2 diff --git a/scripts/health-nightwing-eve-browser-reference.cmd b/scripts/health-nightwing-eve-browser-reference.cmd deleted file mode 100644 index 1a4b44e..0000000 --- a/scripts/health-nightwing-eve-browser-reference.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-nightwing-eve-browser-reference.cmd archived: Nightwing Eve browser reference health is daemon-published over CultNet/RUDP as nightwing.cultnet-rudp-browser-reference-health. Use health-nightwing-eve-browser-reference.ps1 only as an explicit witness inspection, not Idunn health truth. -exit /b 2 diff --git a/scripts/health-nightwing-eve-browser-reference.ps1 b/scripts/health-nightwing-eve-browser-reference.ps1 deleted file mode 100644 index e4bd6ab..0000000 --- a/scripts/health-nightwing-eve-browser-reference.ps1 +++ /dev/null @@ -1,335 +0,0 @@ -param( - [string] $SshTarget = "nightwing", - [string] $ExpectedDocumentRoot = "/opt/gamecult/eve-browser-reference", - [string] $RemoteCultCacheWitness = "/var/lib/gamecult/eve-browser-reference/cultcache/eve-browser-reference.service.cc", - [int] $MaxWitnessAgeSeconds = 120 -) - -$ErrorActionPreference = "Stop" - -function Fail-IdunnHealth { - param( - [string] $State, - [string] $Message - ) - - Write-Output "idunn.health.state=$State" - throw $Message -} - -function Invoke-SshText { - param( - [string] $Command, - [string] $FailureMessage, - [string] $FailureState = "failed" - ) - - $output = ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget $Command - if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($output)) { - Fail-IdunnHealth -State $FailureState -Message $FailureMessage - } - - return $output -} - -function Get-CultCacheInspection { - param( - [string] $WitnessCopyPath, - [string] $InspectorPackageJson - ) - - $nodeScript = @' -const fs = require("fs"); -const { createRequire } = require("module"); - -const witnessCopyPath = process.argv[2]; -const inspectorPackageJson = process.argv[3]; -const requireCultCacheInspection = createRequire(inspectorPackageJson); -const { inspectCultCacheBytes } = requireCultCacheInspection("cultcache-ts"); -const inspection = inspectCultCacheBytes(witnessCopyPath, fs.readFileSync(witnessCopyPath)); - -function firstRecord(schemaName) { - return inspection.records.find((record) => record.schemaName === schemaName) ?? null; -} - -function previewArray(record) { - return Array.isArray(record?.payloadPreview) ? record.payloadPreview : []; -} - -function normalizeRecord(schemaName) { - const record = firstRecord(schemaName); - if (!record) { - return null; - } - - const preview = previewArray(record); - switch (schemaName) { - case "mimir.eve_browser_reference_manifest": - return { - schemaName: record.schemaName, - storedAt: record.storedAt, - daemonId: preview[0] ?? "", - siteTitle: preview[1] ?? "", - documentRoot: preview[2] ?? "", - entryPoint: preview[3] ?? "", - port: preview[4] ?? 0, - assetCount: Array.isArray(preview[5]) ? preview[5].length : 0, - surfaceTransport: preview[6] ?? "", - }; - case "mimir.eve_browser_reference_static_surface": - return { - schemaName: record.schemaName, - storedAt: record.storedAt, - daemonId: preview[0] ?? "", - updatedAtUtc: preview[1] ?? "", - documentRoot: preview[2] ?? "", - entryPoint: preview[3] ?? "", - assetCount: Array.isArray(preview[4]) ? preview[4].length : 0, - fixtureCount: Array.isArray(preview[5]) ? preview[5].length : 0, - currentCutLine: preview[6] ?? "", - }; - case "mimir.eve_browser_reference_command_boundary": - return { - schemaName: record.schemaName, - storedAt: record.storedAt, - daemonId: preview[0] ?? "", - updatedAtUtc: preview[1] ?? "", - mode: preview[2] ?? "", - writesAccepted: preview[3] === true, - operatorInputAuthority: preview[4] ?? "", - lifecycleAuthority: preview[5] ?? "", - acceptedCommands: Array.isArray(preview[6]) ? preview[6] : [], - rejectedCommands: Array.isArray(preview[7]) ? preview[7] : [], - }; - case "mimir.eve_browser_reference_transport_profile": - return { - schemaName: record.schemaName, - storedAt: record.storedAt, - daemonId: preview[0] ?? "", - updatedAtUtc: preview[1] ?? "", - currentState: preview[2] ?? "", - inputTransport: preview[3] ?? "", - outputTransport: preview[4] ?? "", - healthContract: preview[5] ?? "", - idunnRudpHealth: preview[6] ?? "", - witnessPath: preview[7] ?? "", - currentCutLine: preview[8] ?? "", - }; - case "idunn.daemon_health": - return { - schemaName: record.schemaName, - storedAt: record.storedAt, - daemonId: preview[0] ?? "", - state: preview[1] ?? "", - detail: preview[2] ?? "", - observedAt: preview[3] ?? "", - healthContract: preview[4] ?? "", - publicationSource: preview[5] ?? "", - transport: preview[6] ?? "", - }; - default: - return { - schemaName: record.schemaName, - storedAt: record.storedAt, - }; - } -} - -console.log(JSON.stringify({ - format: inspection.format, - catalogSchemaVersions: inspection.catalog.map((entry) => entry.schemaVersion), - manifest: normalizeRecord("mimir.eve_browser_reference_manifest"), - staticSurface: normalizeRecord("mimir.eve_browser_reference_static_surface"), - commandBoundary: normalizeRecord("mimir.eve_browser_reference_command_boundary"), - transportProfile: normalizeRecord("mimir.eve_browser_reference_transport_profile"), - daemonHealth: normalizeRecord("idunn.daemon_health"), -})); -'@ - - $inspectionJson = $nodeScript | node - $WitnessCopyPath $InspectorPackageJson - if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($inspectionJson)) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness inspection failed." - } - - try { - return $inspectionJson | ConvertFrom-Json - } catch { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache inspection returned malformed JSON." - } -} - -ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget "systemctl is-active --quiet nightwing-eve-browser-reference.service" -if ($LASTEXITCODE -ne 0) { - Fail-IdunnHealth -State "failed" -Message "nightwing-eve-browser-reference.service is not active on Nightwing." -} - -$cultCacheStat = Invoke-SshText ` - -Command "stat -c '%s %Y %U %G' '$RemoteCultCacheWitness' 2>/dev/null" ` - -FailureMessage "Nightwing Eve browser reference CultCache witness is missing at $RemoteCultCacheWitness." - -$cultCacheParts = $cultCacheStat.Trim() -split '\s+' -if ($cultCacheParts.Length -lt 4) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness stat output was malformed: $cultCacheStat" -} - -$cultCacheSize = [int64]$cultCacheParts[0] -$cultCacheModifiedUtc = [DateTimeOffset]::FromUnixTimeSeconds([int64]$cultCacheParts[1]) -$cultCacheOwner = $cultCacheParts[2] -$cultCacheGroup = $cultCacheParts[3] -$cultCacheAgeSeconds = ([DateTimeOffset]::UtcNow - $cultCacheModifiedUtc).TotalSeconds -if ($cultCacheSize -le 0) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness at $RemoteCultCacheWitness is empty." -} - -if ($cultCacheAgeSeconds -gt $MaxWitnessAgeSeconds) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is stale ($([math]::Round($cultCacheAgeSeconds))s old)." -} - -if ($cultCacheOwner -ne "metacrat" -or $cultCacheGroup -ne "metacrat") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference CultCache witness owner is ${cultCacheOwner}:$cultCacheGroup, expected metacrat:metacrat." -} - -try { - $cultCacheInspectorPackageJson = (Resolve-Path (Join-Path $PSScriptRoot "..\..\CultLib\packages\cultcache-ts\package.json")).Path -} catch { - Fail-IdunnHealth -State "failed" -Message "CultCache inspector package is missing from the local Odin body." -} - -$cultCacheWitnessCopy = Join-Path ([System.IO.Path]::GetTempPath()) ("nightwing-eve-browser-reference-" + [Guid]::NewGuid().ToString("N") + ".cc") -try { - $remoteCultCacheBase64 = Invoke-SshText ` - -Command "base64 -w0 '$RemoteCultCacheWitness' 2>/dev/null" ` - -FailureMessage "Nightwing Eve browser reference CultCache witness could not be copied from Nightwing." - [System.IO.File]::WriteAllBytes($cultCacheWitnessCopy, [Convert]::FromBase64String($remoteCultCacheBase64.Trim())) - $inspection = Get-CultCacheInspection -WitnessCopyPath $cultCacheWitnessCopy -InspectorPackageJson $cultCacheInspectorPackageJson -} catch [FormatException] { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness copy was not valid base64." -} finally { - if (Test-Path $cultCacheWitnessCopy) { - Remove-Item $cultCacheWitnessCopy -Force -ErrorAction SilentlyContinue - } -} - -if ($inspection.format -ne "cultcache.store.v1") { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness has unexpected format '$($inspection.format)'." -} - -$requiredCultCacheSchemas = @( - "mimir.eve_browser_reference_manifest.v1", - "mimir.eve_browser_reference_static_surface.v1", - "mimir.eve_browser_reference_command_boundary.v1", - "mimir.eve_browser_reference_transport_profile.v1", - "idunn.daemon_health.v1" -) - -$publishedCultCacheSchemas = @($inspection.catalogSchemaVersions) -foreach ($schema in $requiredCultCacheSchemas) { - if ($publishedCultCacheSchemas -notcontains $schema) { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference CultCache witness is missing schema '$schema'." - } -} - -if ($null -eq $inspection.manifest) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its manifest record." -} - -if ($inspection.manifest.documentRoot -ne $ExpectedDocumentRoot) { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference manifest document root is '$($inspection.manifest.documentRoot)', expected '$ExpectedDocumentRoot'." -} - -if ($inspection.manifest.entryPoint -ne "index.html") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference manifest entry point is '$($inspection.manifest.entryPoint)', expected 'index.html'." -} - -if ($inspection.manifest.surfaceTransport -ne "static-http-lowering") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference manifest transport is '$($inspection.manifest.surfaceTransport)', expected 'static-http-lowering'." -} - -if ($null -eq $inspection.staticSurface) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its static-surface record." -} - -if ($inspection.staticSurface.documentRoot -ne $ExpectedDocumentRoot) { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference static-surface document root is '$($inspection.staticSurface.documentRoot)', expected '$ExpectedDocumentRoot'." -} - -if ($null -eq $inspection.commandBoundary) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its command boundary record." -} - -if ($inspection.commandBoundary.mode -ne "static-read-only-lowering") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference command boundary mode is '$($inspection.commandBoundary.mode)', expected 'static-read-only-lowering'." -} - -if ($inspection.commandBoundary.writesAccepted) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference command boundary unexpectedly accepts writes." -} - -if ($inspection.commandBoundary.lifecycleAuthority -ne "idunn-supervisor-command.restart") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference lifecycle authority is '$($inspection.commandBoundary.lifecycleAuthority)', expected 'idunn-supervisor-command.restart'." -} - -if ($null -eq $inspection.transportProfile) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its transport profile record." -} - -if ($inspection.transportProfile.currentState -ne "partial-rudp-health-and-provider-store-live") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference transport profile state is '$($inspection.transportProfile.currentState)', expected 'partial-rudp-health-and-provider-store-live'." -} - -if ($inspection.transportProfile.inputTransport -ne "http-static-lowering") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference input transport is '$($inspection.transportProfile.inputTransport)', expected 'http-static-lowering'." -} - -if ($inspection.transportProfile.outputTransport -ne "daemon-owned-cultcache-boundary-store + daemon-published-rudp-health") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference output transport is '$($inspection.transportProfile.outputTransport)', expected 'daemon-owned-cultcache-boundary-store + daemon-published-rudp-health'." -} - -if ($inspection.transportProfile.healthContract -ne "nightwing.cultnet-rudp-browser-reference-health") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference health contract is '$($inspection.transportProfile.healthContract)', expected 'nightwing.cultnet-rudp-browser-reference-health'." -} - -if ($inspection.transportProfile.idunnRudpHealth -ne "idunn.health-published-separately") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference transport profile Idunn health publication is '$($inspection.transportProfile.idunnRudpHealth)', expected 'idunn.health-published-separately'." -} - -if ($inspection.transportProfile.witnessPath -ne $RemoteCultCacheWitness) { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference transport profile witness path is '$($inspection.transportProfile.witnessPath)', expected '$RemoteCultCacheWitness'." -} - -if ($null -eq $inspection.daemonHealth) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its daemon-health record." -} - -if ($inspection.daemonHealth.daemonId -ne "nightwing-eve-browser-reference") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health record advertises daemon '$($inspection.daemonHealth.daemonId)', expected 'nightwing-eve-browser-reference'." -} - -if ($inspection.daemonHealth.state -ne "healthy") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health state is '$($inspection.daemonHealth.state)', expected 'healthy'." -} - -if ($inspection.daemonHealth.healthContract -ne "nightwing.cultnet-rudp-browser-reference-health") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health contract is '$($inspection.daemonHealth.healthContract)', expected 'nightwing.cultnet-rudp-browser-reference-health'." -} - -if ($inspection.daemonHealth.publicationSource -ne "daemon-published") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health publication source is '$($inspection.daemonHealth.publicationSource)', expected 'daemon-published'." -} - -if ($inspection.daemonHealth.transport -ne "cultnet.transport.rudp.v0") { - Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health transport is '$($inspection.daemonHealth.transport)', expected 'cultnet.transport.rudp.v0'." -} - -try { - $daemonHealthObservedAtUtc = [DateTimeOffset]::Parse($inspection.daemonHealth.observedAt) -} catch { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference daemon-health observedAt is malformed: '$($inspection.daemonHealth.observedAt)'." -} - -$daemonHealthAgeSeconds = ([DateTimeOffset]::UtcNow - $daemonHealthObservedAtUtc.ToUniversalTime()).TotalSeconds -if ($daemonHealthAgeSeconds -gt $MaxWitnessAgeSeconds) { - Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference daemon-health record is stale ($([math]::Round($daemonHealthAgeSeconds))s old)." -} - -Write-Host "Nightwing Eve browser reference is active, and its daemon-owned CultCache witness now certifies manifest, boundary, and daemon-health truth directly." diff --git a/scripts/health-nightwing-eve-dashboard.cmd b/scripts/health-nightwing-eve-dashboard.cmd deleted file mode 100644 index 4e5dc72..0000000 --- a/scripts/health-nightwing-eve-dashboard.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-nightwing-eve-dashboard.cmd archived: Nightwing Eve dashboard broker health is not daemon truth. Rebuild typed CultMesh/Odin dashboard state before restoring a health check. 1>&2 -exit /b 2 diff --git a/scripts/health-nightwing-eve-dashboard.ps1 b/scripts/health-nightwing-eve-dashboard.ps1 deleted file mode 100644 index 8dc25f0..0000000 --- a/scripts/health-nightwing-eve-dashboard.ps1 +++ /dev/null @@ -1 +0,0 @@ -throw "health-nightwing-eve-dashboard.ps1 archived: Nightwing Eve dashboard broker health is not daemon truth. Inspect typed CultMesh/Odin dashboard state after the publisher is rebuilt." diff --git a/scripts/health-odin.cmd b/scripts/health-odin.cmd deleted file mode 100644 index 128f0d0..0000000 --- a/scripts/health-odin.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-odin.cmd archived: Odin health is daemon-published over CultNet/RUDP as odin.cultnet-rudp-provider-health. Use health-odin.ps1 only as an explicit daemon witness inspection, not Idunn health truth. -exit /b 2 diff --git a/scripts/health-odin.ps1 b/scripts/health-odin.ps1 deleted file mode 100644 index 1d26b09..0000000 --- a/scripts/health-odin.ps1 +++ /dev/null @@ -1,68 +0,0 @@ -param( - [string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin"), - [int] $MaxSilenceSeconds = 120, - [string] $CultNetRudpBind = "0.0.0.0:17871" -) - -$ErrorActionPreference = "Stop" - -$pidPath = Join-Path $StateDir "odin.pid" -$outLog = Join-Path $StateDir "odin.out.log" -$errLog = Join-Path $StateDir "odin.err.log" -$cachePath = Join-Path $StateDir "odin.ccmp" - -if (-not (Test-Path -LiteralPath $pidPath)) { - throw "Odin PID file is missing at $pidPath" -} - -$pidText = (Get-Content -LiteralPath $pidPath -Raw).Trim() -if ($pidText -notmatch '^\d+$') { - throw "Odin PID file is invalid at ${pidPath}: '$pidText'" -} - -$process = Get-CimInstance Win32_Process -Filter "ProcessId = $pidText" -ErrorAction SilentlyContinue -if ($null -eq $process) { - throw "Odin process $pidText is not running" -} - -foreach ($pattern in @( - 'node.exe', - 'src\odin-coordinator.cjs', - "--stateDir $StateDir", - "--cultnet-rudp-bind $CultNetRudpBind", - '--idunn-daemon odin', - '--idunn-health-contract odin.cultnet-rudp-provider-health' -)) { - if ($process.CommandLine -notlike "*$pattern*") { - throw "Odin process command line is missing expected segment ${pattern}: $($process.CommandLine)" - } -} - -foreach ($logPath in @($outLog, $errLog)) { - if (-not (Test-Path -LiteralPath $logPath)) { - throw "Odin log is missing at $logPath" - } -} - -$newestLogWriteUtc = @($outLog, $errLog) | - ForEach-Object { (Get-Item -LiteralPath $_).LastWriteTimeUtc } | - Sort-Object -Descending | - Select-Object -First 1 -$logAgeSeconds = ([DateTime]::UtcNow - $newestLogWriteUtc).TotalSeconds -if ($logAgeSeconds -gt $MaxSilenceSeconds) { - throw "Odin logs have been silent for $([math]::Round($logAgeSeconds))s, exceeding $MaxSilenceSeconds seconds" -} - -if (-not (Test-Path -LiteralPath $cachePath)) { - throw "Odin CultMesh store is missing at $cachePath" -} - -$rudpPort = [int](($CultNetRudpBind -split ':')[-1]) -$udpListener = Get-NetUDPEndpoint -LocalPort $rudpPort -ErrorAction SilentlyContinue | - Where-Object { $_.OwningProcess -eq [int]$pidText } | - Select-Object -First 1 -if ($null -eq $udpListener) { - throw "Odin is not listening on UDP port $rudpPort as process $pidText" -} - -Write-Host "Odin healthy: pid=$pidText cultmesh_rudp_udp=$rudpPort store=$cachePath log_age=$([math]::Round($logAgeSeconds))s" diff --git a/scripts/health-raven-capture-mux.cmd b/scripts/health-raven-capture-mux.cmd deleted file mode 100644 index 334d7cb..0000000 --- a/scripts/health-raven-capture-mux.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-raven-capture-mux.cmd archived: Raven capture mux no longer owns Muninn daemon health; Muninn publishes muninn.cultnet-rudp-remote-telemetry-health over CultNet/RUDP. -exit /b 2 diff --git a/scripts/health-raven-capture-mux.ps1 b/scripts/health-raven-capture-mux.ps1 deleted file mode 100644 index 779f902..0000000 --- a/scripts/health-raven-capture-mux.ps1 +++ /dev/null @@ -1,2 +0,0 @@ -Write-Error "health-raven-capture-mux.ps1 archived: Raven capture mux no longer owns Muninn daemon health; Muninn publishes muninn.cultnet-rudp-remote-telemetry-health over CultNet/RUDP." -exit 2 diff --git a/scripts/health-stonks.cmd b/scripts/health-stonks.cmd deleted file mode 100644 index 9994234..0000000 --- a/scripts/health-stonks.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-stonks.cmd archived: Stonks health is daemon-published over CultNet/RUDP as stonks.cultnet-rudp-market-health. Do not probe localhost HTTP for daemon health. 1>&2 -exit /b 2 diff --git a/scripts/health-vili.cmd b/scripts/health-vili.cmd deleted file mode 100644 index 4a2e70d..0000000 --- a/scripts/health-vili.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-vili.cmd archived: Vili health is daemon-published over CultNet/RUDP as vili.cultnet-rudp-animation-health. Do not probe HTTP for daemon health. 1>&2 -exit /b 2 diff --git a/scripts/health-voidbot.cmd b/scripts/health-voidbot.cmd deleted file mode 100644 index 6c600cf..0000000 --- a/scripts/health-voidbot.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-voidbot.cmd archived: VoidBot health is daemon-published over CultNet/RUDP as voidbot.cultnet-rudp-stack-health. Use health-voidbot.ps1 only as an explicit witness inspection, not Idunn health truth. 1>&2 -exit /b 2 diff --git a/scripts/health-voidbot.ps1 b/scripts/health-voidbot.ps1 deleted file mode 100644 index cc3196a..0000000 --- a/scripts/health-voidbot.ps1 +++ /dev/null @@ -1,181 +0,0 @@ -param( - [string] $VoidBotRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "VoidBot"), - [int] $MaxOrchestratorAgeSeconds = 180, - [int] $MaxCultMeshStoreAgeSeconds = 180 -) - -Set-StrictMode -Version Latest -$ErrorActionPreference = "Stop" - -function Fail-IdunnHealth { - param( - [string] $State, - [string] $Message - ) - - Write-Output "idunn.health.state=$State" - throw $Message -} - -function Read-JsonFile { - param([Parameter(Mandatory = $true)][string] $Path) - - if (-not (Test-Path -LiteralPath $Path)) { - return $null - } - - $raw = Get-Content -LiteralPath $Path -Raw -Encoding UTF8 - if ([string]::IsNullOrWhiteSpace($raw)) { - return $null - } - - return $raw | ConvertFrom-Json -} - -function Get-JsonPropertyValue { - param( - [Parameter(Mandatory = $false)] $Object, - [Parameter(Mandatory = $true)][string] $Name, - [Parameter(Mandatory = $false)] $Default = $null - ) - - if ($null -eq $Object) { - return $Default - } - - $property = $Object.PSObject.Properties[$Name] - if ($null -eq $property) { - return $Default - } - - return $property.Value -} - -function Get-ProcessOrFail { - param( - [Parameter(Mandatory = $true)][string] $Role, - [Parameter(Mandatory = $true)][int] $ProcessId - ) - - $process = Get-Process -Id $ProcessId -ErrorAction SilentlyContinue - if ($null -eq $process) { - Fail-IdunnHealth -State "failed" -Message "VoidBot $Role process PID $ProcessId is not running." - } - - return $process -} - -function Assert-StoreContains { - param( - [Parameter(Mandatory = $true)][string] $StorePath, - [Parameter(Mandatory = $true)][string[]] $Tokens - ) - - $rg = (Get-Command rg.exe -ErrorAction SilentlyContinue).Source - if ([string]::IsNullOrWhiteSpace($rg)) { - Fail-IdunnHealth -State "degraded" -Message "ripgrep is required to inspect the VoidBot CultMesh witness store." - } - - foreach ($token in $Tokens) { - & $rg -a -q --fixed-strings -- $token $StorePath - if ($LASTEXITCODE -ne 0) { - Fail-IdunnHealth -State "degraded" -Message "VoidBot CultMesh witness store is missing '$token'." - } - } -} - -$runtimePath = Join-Path $VoidBotRoot ".voidbot\status\runtime-stack.json" -$orchestratorPath = Join-Path $VoidBotRoot ".voidbot\status\gamecult-orchestrator.json" -$cultMeshStorePath = Join-Path $VoidBotRoot ".voidbot\status\cultmesh\voidbot-swarm-state.cc" - -$runtime = Read-JsonFile -Path $runtimePath -if ($null -eq $runtime) { - Fail-IdunnHealth -State "failed" -Message "VoidBot runtime state is missing at $runtimePath." -} - -if (-not [bool](Get-JsonPropertyValue -Object $runtime -Name "ready" -Default $false)) { - Fail-IdunnHealth -State "failed" -Message "VoidBot runtime stack reports ready=false." -} - -$runtimeStage = [string](Get-JsonPropertyValue -Object $runtime -Name "stage" -Default "unknown") -if ($runtimeStage -ne "ready") { - Fail-IdunnHealth -State "failed" -Message "VoidBot runtime stack stage is '$runtimeStage', expected 'ready'." -} - -$bot = Get-JsonPropertyValue -Object $runtime -Name "bot" -$worker = Get-JsonPropertyValue -Object $runtime -Name "worker" -$botPid = if ($null -ne $bot) { [int](Get-JsonPropertyValue -Object $bot -Name "pid" -Default 0) } else { 0 } -$workerPid = if ($null -ne $worker) { [int](Get-JsonPropertyValue -Object $worker -Name "pid" -Default 0) } else { 0 } -if ($botPid -le 0) { - Fail-IdunnHealth -State "failed" -Message "VoidBot runtime state does not contain a live bot PID." -} -if ($workerPid -le 0) { - Fail-IdunnHealth -State "failed" -Message "VoidBot runtime state does not contain a live worker PID." -} - -$botProcess = Get-ProcessOrFail -Role "bot" -ProcessId $botPid -$workerProcess = Get-ProcessOrFail -Role "worker" -ProcessId $workerPid - -$orchestrator = Read-JsonFile -Path $orchestratorPath -if ($null -eq $orchestrator -or $null -eq $orchestrator.organs) { - Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator state is missing at $orchestratorPath." -} - -$surfaceState = $orchestrator.organs.PSObject.Properties["voidbot-swarm-surface"] -if ($null -eq $surfaceState) { - Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator does not report the voidbot-swarm-surface organ." -} -$surfaceState = $surfaceState.Value - -if ($surfaceState.lastStatus -ne "ok") { - Fail-IdunnHealth -State "degraded" -Message "VoidBot swarm surface organ lastStatus is '$($surfaceState.lastStatus)', expected 'ok'." -} - -if ([string]::IsNullOrWhiteSpace($surfaceState.lastFinishedAt)) { - Fail-IdunnHealth -State "failed" -Message "VoidBot swarm surface organ has no lastFinishedAt timestamp." -} - -$surfaceFinishedAt = [DateTimeOffset]::Parse($surfaceState.lastFinishedAt).ToUniversalTime() -$surfaceAgeSeconds = ([DateTimeOffset]::UtcNow - $surfaceFinishedAt).TotalSeconds -if ($surfaceAgeSeconds -gt $MaxOrchestratorAgeSeconds) { - Fail-IdunnHealth -State "failed" -Message "VoidBot swarm surface organ is stale ($([math]::Round($surfaceAgeSeconds))s old)." -} - -$orchestratorFile = Get-Item -LiteralPath $orchestratorPath -ErrorAction SilentlyContinue -if ($null -eq $orchestratorFile) { - Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator state file is missing at $orchestratorPath." -} -$orchestratorAgeSeconds = ([DateTimeOffset]::UtcNow - [DateTimeOffset]$orchestratorFile.LastWriteTimeUtc).TotalSeconds -if ($orchestratorAgeSeconds -gt $MaxOrchestratorAgeSeconds) { - Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator state file is stale ($([math]::Round($orchestratorAgeSeconds))s old)." -} - -$cultMeshStore = Get-Item -LiteralPath $cultMeshStorePath -ErrorAction SilentlyContinue -if ($null -eq $cultMeshStore) { - Fail-IdunnHealth -State "failed" -Message "VoidBot CultMesh witness store is missing at $cultMeshStorePath." -} -if ($cultMeshStore.Length -le 0) { - Fail-IdunnHealth -State "failed" -Message "VoidBot CultMesh witness store at $cultMeshStorePath is empty." -} - -$cultMeshStoreAgeSeconds = ([DateTimeOffset]::UtcNow - [DateTimeOffset]$cultMeshStore.LastWriteTimeUtc).TotalSeconds -if ($cultMeshStoreAgeSeconds -gt $MaxCultMeshStoreAgeSeconds) { - Fail-IdunnHealth -State "failed" -Message "VoidBot CultMesh witness store is stale ($([math]::Round($cultMeshStoreAgeSeconds))s old)." -} - -Assert-StoreContains -StorePath $cultMeshStorePath -Tokens @( - "voidbot.provider_advertisement_catalog.v0", - "idunn.command_boundary.v1", - "idunn.daemon_transport_profile.v1", - "voidbot.providers", - "voidbot.discord", - "voidbot.reddit", - "voidbot.archive", - "voidbot.source", - "voidbot.repo_face", - "voidbot.swarm", - "command-boundary:voidbot", - "transport:voidbot" -) - -Write-Host "VoidBot runtime is ready, bot PID $($botProcess.Id) and worker PID $($workerProcess.Id) are live, and the daemon-owned CultMesh witness store is fresh." diff --git a/scripts/health-weksa.cmd b/scripts/health-weksa.cmd deleted file mode 100644 index 0ff58c7..0000000 --- a/scripts/health-weksa.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-weksa.cmd archived: Weksa health is daemon-published over CultNet/RUDP as weksa.cultnet-rudp-provider-health. Do not run local command health for daemon truth. 1>&2 -exit /b 2 diff --git a/scripts/health-yggdrasil-heimdall.cmd b/scripts/health-yggdrasil-heimdall.cmd deleted file mode 100644 index e422cca..0000000 --- a/scripts/health-yggdrasil-heimdall.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-yggdrasil-heimdall.cmd archived: Heimdall health is daemon-published over CultNet/RUDP as heimdall.cultnet-rudp-provider-health. Use health-yggdrasil-source-app.ps1 only as an explicit deployment witness, not Idunn health truth. -exit /b 2 diff --git a/scripts/health-yggdrasil-repixelizer.cmd b/scripts/health-yggdrasil-repixelizer.cmd deleted file mode 100644 index 9aae84c..0000000 --- a/scripts/health-yggdrasil-repixelizer.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-yggdrasil-repixelizer.cmd archived: Repixelizer health is daemon-published over CultNet/RUDP as repixelizer.cultnet-rudp-service-health. Use health-yggdrasil-source-app.ps1 only as an explicit deployment witness, not Idunn health truth. -exit /b 2 diff --git a/scripts/health-yggdrasil-source-app.ps1 b/scripts/health-yggdrasil-source-app.ps1 deleted file mode 100644 index 54df0c2..0000000 --- a/scripts/health-yggdrasil-source-app.ps1 +++ /dev/null @@ -1,43 +0,0 @@ -param( - [Parameter(Mandatory = $true)] [string] $AppId, - [Parameter(Mandatory = $true)] [string] $RepoRoot, - [Parameter(Mandatory = $true)] [string] $RemoteAppHome, - [Parameter(Mandatory = $true)] [string] $CheckScript, - [string] $SshTarget = "yggdrasil" -) - -$ErrorActionPreference = "Stop" - -$localCommit = (git -C $RepoRoot rev-parse HEAD).Trim() -if ([string]::IsNullOrWhiteSpace($localCommit)) { - throw "Could not determine git revision for $RepoRoot" -} - -$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))" -$scpArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10") -$sshArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10", $SshTarget) -scp.exe @scpArgs $CheckScript "${SshTarget}:$remoteCheck" | Out-Null -if ($LASTEXITCODE -ne 0) { throw "scp check script failed for $AppId" } - -$manifest = ssh.exe @sshArgs "cat '$RemoteAppHome/deployment-manifest.txt' 2>/dev/null" -if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($manifest)) { - throw "$AppId deploy manifest is missing on Yggdrasil." -} - -$remoteCommit = "" -foreach ($line in $manifest) { - if ($line -like "gitCommit=*") { - $remoteCommit = $line.Substring("gitCommit=".Length).Trim() - } -} - -if ($remoteCommit -ne $localCommit) { - throw "$AppId deploy is stale. remote=$remoteCommit local=$localCommit" -} - -ssh.exe @sshArgs "chmod +x '$remoteCheck' && sudo -n bash '$remoteCheck'" -if ($LASTEXITCODE -ne 0) { - throw "$AppId remote health check failed." -} - -Write-Host "$AppId is active and deployed at $localCommit." diff --git a/scripts/health-yggdrasil-streampixels.cmd b/scripts/health-yggdrasil-streampixels.cmd deleted file mode 100644 index c54e85e..0000000 --- a/scripts/health-yggdrasil-streampixels.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo health-yggdrasil-streampixels.cmd archived: StreamPixels health is daemon-published over CultNet/RUDP as streampixels.cultnet-rudp-service-health. Use health-yggdrasil-source-app.ps1 only as an explicit deployment witness, not Idunn health truth. -exit /b 2 diff --git a/scripts/linux/deploy-yggdrasil-heimdall b/scripts/linux/deploy-yggdrasil-heimdall deleted file mode 100755 index 6904e0b..0000000 --- a/scripts/linux/deploy-yggdrasil-heimdall +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh -set -eu - -if [ "$(id -u)" -ne 0 ]; then - echo "deploy-yggdrasil-heimdall must run as root through Idunn" >&2 - exit 1 -fi - -source_tar=/srv/heimdall/heimdall-source.tar -cultlib_tar=/srv/heimdall/heimdall-cultlib.tar -releases=/srv/heimdall/app/releases -current=/srv/heimdall/app/current -shared_cultlib="$releases/CultLib" -compose=/srv/compose/yggdrasil-apps.yaml - -for required in "$source_tar" "$cultlib_tar" "$compose"; do - if [ ! -f "$required" ]; then - echo "missing audited Heimdall deployment input: $required" >&2 - exit 1 - fi -done - -artifact_sha=$(sha256sum "$source_tar" | awk '{print $1}') -release="$releases/sha-${artifact_sha}" -previous=$(readlink -f "$current" 2>/dev/null || true) - -if [ ! -f "$release/.idunn-build-complete" ]; then - staging="$release.staging.$$" - rm -rf "$staging" - install -d -o heimdall -g heimdall "$staging" "$shared_cultlib" - tar -xf "$source_tar" -C "$staging" - rm -rf "$shared_cultlib/packages/cultcache-ts" "$shared_cultlib/packages/cultnet-ts" - tar -xf "$cultlib_tar" -C "$shared_cultlib" - - docker run --rm \ - -v /srv/heimdall:/srv/heimdall \ - -w "$staging" \ - node:24.14.1-bookworm-slim@sha256:b506e7321f176aae77317f99d67a24b272c1f09f1d10f1761f2773447d8da26c \ - sh -c 'corepack enable && pnpm install --frozen-lockfile && pnpm typecheck && pnpm test && pnpm build && pnpm prune --prod' - - printf '%s\n' "$artifact_sha" > "$staging/.idunn-build-complete" - chown -R heimdall:heimdall "$staging" "$shared_cultlib" - mv "$staging" "$release" -fi - -ln -sfn "$release" "$current" -chown -h heimdall:heimdall "$current" - -if ! docker compose -f "$compose" up -d --force-recreate heimdall; then - if [ -n "$previous" ] && [ -d "$previous" ]; then - ln -sfn "$previous" "$current" - chown -h heimdall:heimdall "$current" - docker compose -f "$compose" up -d --force-recreate heimdall || true - fi - exit 1 -fi - -healthy=0 -for _ in $(seq 1 30); do - if curl -fsS http://127.0.0.1:4100/healthz >/dev/null; then - healthy=1 - break - fi - sleep 2 -done - -if [ "$healthy" -ne 1 ]; then - echo "Heimdall failed health verification after deploying $artifact_sha" >&2 - if [ -n "$previous" ] && [ -d "$previous" ]; then - ln -sfn "$previous" "$current" - chown -h heimdall:heimdall "$current" - docker compose -f "$compose" up -d --force-recreate heimdall || true - fi - exit 1 -fi - -echo "Heimdall deployed audited source artifact $artifact_sha" diff --git a/scripts/restart-nightwing-eve-browser-reference.cmd b/scripts/restart-nightwing-eve-browser-reference.cmd deleted file mode 100644 index fcf2b2b..0000000 --- a/scripts/restart-nightwing-eve-browser-reference.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo restart-nightwing-eve-browser-reference.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo restart-nightwing-eve-browser-reference.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0restart-nightwing-eve-browser-reference.ps1 diff --git a/scripts/restart-nightwing-eve-browser-reference.ps1 b/scripts/restart-nightwing-eve-browser-reference.ps1 deleted file mode 100644 index 63d2f3a..0000000 --- a/scripts/restart-nightwing-eve-browser-reference.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -param( - [string] $SshTarget = "nwroot", - [string] $Service = "nightwing-eve-browser-reference.service" -) - -$ErrorActionPreference = "Stop" - -if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") { - throw "restart-nightwing-eve-browser-reference.ps1 is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path." -} - -ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget "systemctl restart $Service && systemctl is-active --quiet $Service" -if ($LASTEXITCODE -ne 0) { - throw "Remote restart failed for $Service on $SshTarget with exit code $LASTEXITCODE" -} - -Write-Host "Restarted $Service on $SshTarget." diff --git a/scripts/restart-nightwing-eve-dashboard.cmd b/scripts/restart-nightwing-eve-dashboard.cmd deleted file mode 100644 index 18cd822..0000000 --- a/scripts/restart-nightwing-eve-dashboard.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -echo restart-nightwing-eve-dashboard.cmd archived: Mimir.EveDashboard's HTTP/WebSocket broker is cut. Rebuild a typed CultMesh/Odin dashboard publisher before restoring Idunn lifecycle authority. 1>&2 -exit /b 2 diff --git a/scripts/restart-nightwing-eve-dashboard.ps1 b/scripts/restart-nightwing-eve-dashboard.ps1 deleted file mode 100644 index 996f7ab..0000000 --- a/scripts/restart-nightwing-eve-dashboard.ps1 +++ /dev/null @@ -1 +0,0 @@ -throw "restart-nightwing-eve-dashboard.ps1 archived: Mimir.EveDashboard's HTTP/WebSocket broker is cut. Rebuild a typed CultMesh/Odin dashboard publisher before restoring Idunn lifecycle authority." diff --git a/scripts/restart-odin.cmd b/scripts/restart-odin.cmd deleted file mode 100644 index 3b5534c..0000000 --- a/scripts/restart-odin.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo restart-odin.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo restart-odin.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -File %~dp0restart-odin.ps1 diff --git a/scripts/restart-odin.ps1 b/scripts/restart-odin.ps1 deleted file mode 100644 index 334977b..0000000 --- a/scripts/restart-odin.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -param( - [string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin"), - [string] $CultNetRudpBind = "0.0.0.0:17871", - [string] $IdunnRudpHealth = $(if ($env:ODIN_IDUNN_RUDP_HEALTH) { $env:ODIN_IDUNN_RUDP_HEALTH } else { $env:IDUNN_RUDP_HEALTH }), - [string] $IdunnDaemon = "odin", - [string] $IdunnHealthContract = "odin.cultnet-rudp-provider-health" -) - -$ErrorActionPreference = "Stop" - -if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") { - throw "restart-odin.ps1 is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path." -} - -$repoRoot = Split-Path -Parent $PSScriptRoot -$stopScript = Join-Path $PSScriptRoot "stop-odin.ps1" -$startScript = Join-Path $PSScriptRoot "start-odin.ps1" -$powerShellExe = Join-Path $env:WINDIR "System32\WindowsPowerShell\v1.0\powershell.exe" - -if (-not (Test-Path -LiteralPath $powerShellExe)) { - throw "PowerShell executable is missing at $powerShellExe" -} - -$startArgs = @( - "-NoProfile", - "-ExecutionPolicy", "Bypass", - "-File", $startScript, - "-StateDir", $StateDir, - "-CultNetRudpBind", $CultNetRudpBind, - "-IdunnDaemon", $IdunnDaemon, - "-IdunnHealthContract", $IdunnHealthContract -) - -if (-not [string]::IsNullOrWhiteSpace($IdunnRudpHealth)) { - $startArgs += @("-IdunnRudpHealth", $IdunnRudpHealth) -} - -& $powerShellExe -NoProfile -ExecutionPolicy Bypass -File $stopScript -StateDir $StateDir -if ($LASTEXITCODE -ne 0) { - throw "stop-odin.ps1 failed with exit code $LASTEXITCODE" -} - -& $powerShellExe @startArgs -if ($LASTEXITCODE -ne 0) { - throw "start-odin.ps1 failed with exit code $LASTEXITCODE" -} diff --git a/scripts/restart-stonks.cmd b/scripts/restart-stonks.cmd deleted file mode 100644 index fd9ff6c..0000000 --- a/scripts/restart-stonks.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo restart-stonks.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo restart-stonks.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0restart-stonks.ps1 diff --git a/scripts/restart-stonks.ps1 b/scripts/restart-stonks.ps1 deleted file mode 100644 index 3366720..0000000 --- a/scripts/restart-stonks.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -$ErrorActionPreference = "Stop" - -$stonksRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "Stonks") -$stateDir = Join-Path $stonksRoot "scratch\stonks" -$pidPath = Join-Path $stateDir "stonks.pid" -$startScript = Join-Path $stonksRoot "scripts\start-stonks.ps1" - -if (Test-Path -LiteralPath $pidPath) { - $pidText = (Get-Content -LiteralPath $pidPath -Raw).Trim() - if ($pidText -match "^\d+$") { - $process = Get-Process -Id ([int] $pidText) -ErrorAction SilentlyContinue - if ($null -ne $process) { - Stop-Process -Id $process.Id -Force - Start-Sleep -Milliseconds 500 - } - } - Remove-Item -LiteralPath $pidPath -Force -ErrorAction SilentlyContinue -} - -& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $startScript -exit $LASTEXITCODE diff --git a/scripts/restart-vili.cmd b/scripts/restart-vili.cmd deleted file mode 100644 index 58bbd49..0000000 --- a/scripts/restart-vili.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo restart-vili.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo restart-vili.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%~dp0restart-vili.ps1" %* diff --git a/scripts/restart-vili.ps1 b/scripts/restart-vili.ps1 deleted file mode 100644 index 92a8715..0000000 --- a/scripts/restart-vili.ps1 +++ /dev/null @@ -1,287 +0,0 @@ -param( - [string] $RavenHost = "raven", - [string] $LocalViliRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "Vili"), - [string] $LocalCultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"), - [string] $RemoteViliRoot = "E:\Projects\Vili", - [int] $Port = 8824, - [string] $HostName = "0.0.0.0", - [string] $StateRoot = "E:\Projects\Vili\.vili", - [string] $IdunnRudpHealth = $(if ($env:VILI_IDUNN_RUDP_HEALTH) { $env:VILI_IDUNN_RUDP_HEALTH } else { $env:IDUNN_RUDP_HEALTH }), - [string] $IdunnDaemon = "vili", - [string] $IdunnHealthContract = "vili.cultnet-rudp-animation-health", - [int] $IdunnHealthIntervalSeconds = 15 -) - -$ErrorActionPreference = "Stop" - -if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") { - throw "restart-vili.ps1 is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path." -} - -if ([string]::IsNullOrWhiteSpace($IdunnRudpHealth)) { - throw "Idunn RUDP health endpoint must be supplied by VILI_IDUNN_RUDP_HEALTH, IDUNN_RUDP_HEALTH, or -IdunnRudpHealth; no WireGuard endpoint default is allowed." -} - -$localFiles = @( - (Join-Path $LocalViliRoot "package.json"), - (Join-Path $LocalViliRoot "package-lock.json"), - (Join-Path $LocalViliRoot "scripts\idunn-rudp.cjs"), - (Join-Path $LocalViliRoot "scripts\install-vili-task.ps1"), - (Join-Path $LocalViliRoot "scripts\restart-vili-daemon.cmd"), - (Join-Path $LocalViliRoot "scripts\restart-vili-daemon.ps1"), - (Join-Path $LocalViliRoot "scripts\run-hidden-powershell.vbs"), - (Join-Path $LocalViliRoot "scripts\run-vili-daemon.ps1"), - (Join-Path $LocalViliRoot "scripts\start-vili-daemon.ps1"), - (Join-Path $LocalViliRoot "scripts\vili-daemon.mjs"), - (Join-Path $LocalCultLibRoot "packages\cultnet-ts"), - (Join-Path $LocalCultLibRoot "packages\cultcache-ts"), - (Join-Path $LocalCultLibRoot "node_modules\ajv"), - (Join-Path $LocalCultLibRoot "node_modules\fast-deep-equal"), - (Join-Path $LocalCultLibRoot "node_modules\fast-uri"), - (Join-Path $LocalCultLibRoot "node_modules\json-schema-traverse"), - (Join-Path $LocalCultLibRoot "node_modules\require-from-string"), - (Join-Path $LocalViliRoot "node_modules\@msgpack") -) - -foreach ($path in $localFiles) { - if (-not (Test-Path -LiteralPath $path)) { - throw "Required Vili runtime path not found: $path" - } -} - -$syncId = [guid]::NewGuid().ToString("N") -$remoteSyncRootPs = "$RemoteViliRoot\.odin-vili-sync-$syncId" -$remoteSyncRootSftp = ($remoteSyncRootPs -replace "\\", "/") -$remoteTempPs = "C:\Windows\Temp\odin-raven-vili-restart-$syncId.ps1" -$remoteTempSftp = ($remoteTempPs -replace "\\", "/") -$remoteBundlePs = "C:\Windows\Temp\odin-raven-vili-bundle-$syncId.zip" -$remoteBundleSftp = ($remoteBundlePs -replace "\\", "/") -$localRemoteScript = Join-Path $env:TEMP "odin-raven-vili-restart-$syncId.ps1" -$localSftpBatch = Join-Path $env:TEMP "odin-raven-vili-restart-$syncId.sftp" -$localBundleRoot = Join-Path $env:TEMP "odin-raven-vili-bundle-$syncId" -$localBundleScripts = Join-Path $localBundleRoot "scripts" -$localBundleNodeModules = Join-Path $localBundleRoot "node_modules" -$localBundleZip = Join-Path $env:TEMP "odin-raven-vili-bundle-$syncId.zip" - -$remoteScript = @" -`$ErrorActionPreference = "Stop" -`$ProgressPreference = "SilentlyContinue" - -`$remoteRoot = "$RemoteViliRoot" -`$syncRoot = "$remoteSyncRootPs" -`$scriptsRoot = Join-Path `$remoteRoot "scripts" -`$stateRoot = "$StateRoot" -`$nodeModulesRoot = Join-Path `$remoteRoot "node_modules" -`$pidPath = Join-Path `$stateRoot "vili-daemon.pid" - -try { - Expand-Archive -LiteralPath "$remoteBundlePs" -DestinationPath `$syncRoot -Force - if (-not (Test-Path -LiteralPath `$syncRoot)) { - throw "Uploaded sync root not found at `$syncRoot" - } - - if (Test-Path -LiteralPath `$pidPath) { - `$existingPid = (Get-Content -LiteralPath `$pidPath -Raw -ErrorAction SilentlyContinue).Trim() - if (`$existingPid -match '^\d+$') { - `$process = Get-Process -Id ([int] `$existingPid) -ErrorAction SilentlyContinue - if (`$null -ne `$process) { - Stop-Process -Id `$process.Id -Force - Start-Sleep -Seconds 1 - } - } - Remove-Item -LiteralPath `$pidPath -Force -ErrorAction SilentlyContinue - } - - New-Item -ItemType Directory -Force -Path `$scriptsRoot | Out-Null - New-Item -ItemType Directory -Force -Path `$stateRoot | Out-Null - - Copy-Item -LiteralPath (Join-Path `$syncRoot "package.json") -Destination (Join-Path `$remoteRoot "package.json") -Force - Copy-Item -LiteralPath (Join-Path `$syncRoot "package-lock.json") -Destination (Join-Path `$remoteRoot "package-lock.json") -Force - - `$scriptFiles = @( - "idunn-rudp.cjs", - "install-vili-task.ps1", - "restart-vili-daemon.cmd", - "restart-vili-daemon.ps1", - "run-hidden-powershell.vbs", - "run-vili-daemon.ps1", - "start-vili-daemon.ps1", - "vili-daemon.mjs" - ) - - foreach (`$name in `$scriptFiles) { - Copy-Item -LiteralPath (Join-Path `$syncRoot "scripts\`$name") -Destination (Join-Path `$scriptsRoot `$name) -Force - } - - if (Test-Path -LiteralPath `$nodeModulesRoot) { - Remove-Item -LiteralPath `$nodeModulesRoot -Recurse -Force - } - Move-Item -LiteralPath (Join-Path `$syncRoot "node_modules") -Destination `$nodeModulesRoot -Force - - & powershell.exe @( - "-NoProfile", - "-NonInteractive", - "-ExecutionPolicy", "Bypass", - "-File", (Join-Path `$scriptsRoot "install-vili-task.ps1"), - "-TaskName", "GameCult\Vili", - "-Port", "$Port", - "-HostName", "$HostName", - "-StateRoot", "$StateRoot", - "-IdunnRudpHealth", "$IdunnRudpHealth", - "-IdunnDaemon", "$IdunnDaemon", - "-IdunnHealthContract", "$IdunnHealthContract", - "-IdunnHealthIntervalSeconds", "$IdunnHealthIntervalSeconds" - ) - - & powershell.exe @( - "-NoProfile", - "-NonInteractive", - "-ExecutionPolicy", "Bypass", - "-File", (Join-Path `$scriptsRoot "restart-vili-daemon.ps1"), - "-Port", "$Port", - "-HostName", "$HostName", - "-StateRoot", "$StateRoot", - "-IdunnRudpHealth", "$IdunnRudpHealth", - "-IdunnDaemon", "$IdunnDaemon", - "-IdunnHealthContract", "$IdunnHealthContract", - "-IdunnHealthIntervalSeconds", "$IdunnHealthIntervalSeconds" - ) - - `$task = Get-ScheduledTask -TaskName "Vili" -TaskPath "\GameCult\" -ErrorAction Stop - `$action = @(`$task.Actions)[0] - if (`$action.Execute -notmatch '(^|\\)wscript\.exe$') { - throw "GameCult\Vili action executes `$(`$action.Execute), expected wscript.exe" - } - if (`$action.Arguments -notlike "*run-hidden-powershell.vbs*") { - throw "GameCult\Vili action arguments do not reference run-hidden-powershell.vbs" - } - `$taskHealthChecks = @( - (`$action.Arguments -like "*-IdunnRudpHealth*"), - (`$action.Arguments -like "*$IdunnRudpHealth*"), - (`$action.Arguments -like "*-IdunnDaemon*"), - (`$action.Arguments -like "*$IdunnDaemon*"), - (`$action.Arguments -like "*-IdunnHealthContract*"), - (`$action.Arguments -like "*$IdunnHealthContract*") - ) - if (`$taskHealthChecks -contains `$false) { - throw "GameCult\Vili action arguments do not carry the Idunn RUDP health contract." - } - - `$process = Get-CimInstance Win32_Process | - Where-Object { `$_.CommandLine -like '*vili-daemon.mjs*' } | - Select-Object -First 1 - if (`$null -eq `$process) { - throw "Vili process is not running after restart." - } - `$processHealthChecks = @( - (`$process.CommandLine -like "*--idunn-rudp-health*"), - (`$process.CommandLine -like "*$IdunnRudpHealth*"), - (`$process.CommandLine -like "*--idunn-daemon*"), - (`$process.CommandLine -like "*$IdunnDaemon*"), - (`$process.CommandLine -like "*--idunn-health-contract*"), - (`$process.CommandLine -like "*$IdunnHealthContract*") - ) - if (`$processHealthChecks -contains `$false) { - throw "Vili process command line does not include the Idunn RUDP health arguments." - } - - `$operatorStatePath = Join-Path `$stateRoot "operator-state.json" - `$deadline = (Get-Date).AddSeconds(30) - `$state = `$null - while ((Get-Date) -lt `$deadline) { - if (Test-Path -LiteralPath `$operatorStatePath) { - try { - `$state = Get-Content -LiteralPath `$operatorStatePath -Raw | ConvertFrom-Json - if (`$null -ne `$state.idunnRudpHealth -and `$state.idunnRudpHealth.status -eq "published") { - break - } - } catch { - } - } - Start-Sleep -Seconds 1 - } - if (`$null -eq `$state -or `$null -eq `$state.idunnRudpHealth) { - throw "Vili daemon state file did not report idunnRudpHealth after restart." - } - if (`$state.idunnRudpHealth.status -ne "published") { - throw "Vili idunnRudpHealth status is `$(`$state.idunnRudpHealth.status): `$(`$state.idunnRudpHealth.error)" - } - - Write-Host "Vili Raven runtime repaired and restarted with Idunn RUDP health." - Write-Host "ProcessId=`$(`$process.ProcessId)" - Write-Host "TaskArguments=`$(`$action.Arguments)" - Write-Host "HealthStatus=`$(`$state.idunnRudpHealth.status)" - Write-Host "HealthContract=`$(`$state.idunnRudpHealth.contract)" -} finally { - Remove-Item -LiteralPath `$syncRoot -Recurse -Force -ErrorAction SilentlyContinue - Remove-Item -LiteralPath "$remoteBundlePs" -Force -ErrorAction SilentlyContinue -} -"@ - -$batchLines = @( - "put ""$localBundleZip"" ""$remoteBundleSftp""", - "put ""$localRemoteScript"" ""$remoteTempSftp""" -) - -try { - $moduleCopies = @( - @{ Source = (Join-Path $LocalCultLibRoot "packages\cultnet-ts"); Destination = (Join-Path $localBundleNodeModules "cultnet-ts") }, - @{ Source = (Join-Path $LocalCultLibRoot "packages\cultcache-ts"); Destination = (Join-Path $localBundleNodeModules "cultcache-ts") }, - @{ Source = (Join-Path $LocalCultLibRoot "node_modules\ajv"); Destination = (Join-Path $localBundleNodeModules "ajv") }, - @{ Source = (Join-Path $LocalCultLibRoot "node_modules\fast-deep-equal"); Destination = (Join-Path $localBundleNodeModules "fast-deep-equal") }, - @{ Source = (Join-Path $LocalCultLibRoot "node_modules\fast-uri"); Destination = (Join-Path $localBundleNodeModules "fast-uri") }, - @{ Source = (Join-Path $LocalCultLibRoot "node_modules\json-schema-traverse"); Destination = (Join-Path $localBundleNodeModules "json-schema-traverse") }, - @{ Source = (Join-Path $LocalCultLibRoot "node_modules\require-from-string"); Destination = (Join-Path $localBundleNodeModules "require-from-string") }, - @{ Source = (Join-Path $LocalViliRoot "node_modules\@msgpack"); Destination = (Join-Path $localBundleNodeModules "@msgpack") } - ) - New-Item -ItemType Directory -Force -Path $localBundleScripts, $localBundleNodeModules | Out-Null - Copy-Item -LiteralPath (Join-Path $LocalViliRoot "package.json") -Destination (Join-Path $localBundleRoot "package.json") -Force - Copy-Item -LiteralPath (Join-Path $LocalViliRoot "package-lock.json") -Destination (Join-Path $localBundleRoot "package-lock.json") -Force - $scriptCopies = @( - "idunn-rudp.cjs", - "install-vili-task.ps1", - "restart-vili-daemon.cmd", - "restart-vili-daemon.ps1", - "run-hidden-powershell.vbs", - "run-vili-daemon.ps1", - "start-vili-daemon.ps1", - "vili-daemon.mjs" - ) - foreach ($scriptName in $scriptCopies) { - Copy-Item -LiteralPath (Join-Path $LocalViliRoot "scripts\$scriptName") -Destination (Join-Path $localBundleScripts $scriptName) -Force - } - foreach ($copy in $moduleCopies) { - New-Item -ItemType Directory -Force -Path (Split-Path -Parent $copy.Destination) | Out-Null - Copy-Item -LiteralPath $copy.Source -Destination $copy.Destination -Recurse -Force - } - if (Test-Path -LiteralPath $localBundleZip) { - Remove-Item -LiteralPath $localBundleZip -Force - } - Compress-Archive -Path (Join-Path $localBundleRoot "*") -DestinationPath $localBundleZip -CompressionLevel Optimal - Set-Content -LiteralPath $localRemoteScript -Encoding ASCII -Value $remoteScript - Set-Content -LiteralPath $localSftpBatch -Encoding ASCII -Value ($batchLines -join "`r`n") - & sftp.exe -b $localSftpBatch $RavenHost - if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE - } - - $remoteRunner = @" -`$ErrorActionPreference = "Stop" -try { - & "$remoteTempPs" - `$code = `$LASTEXITCODE -} finally { - Remove-Item -LiteralPath "$remoteTempPs" -Force -ErrorAction SilentlyContinue -} -exit `$code -"@ - $encodedRunner = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($remoteRunner)) - & ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $RavenHost "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand $encodedRunner" -} finally { - Remove-Item -LiteralPath $localRemoteScript, $localSftpBatch -Force -ErrorAction SilentlyContinue - Remove-Item -LiteralPath $localBundleZip -Force -ErrorAction SilentlyContinue - Remove-Item -LiteralPath $localBundleRoot -Recurse -Force -ErrorAction SilentlyContinue -} - -$restartExit = $LASTEXITCODE -exit $restartExit diff --git a/scripts/restart-weksa.cmd b/scripts/restart-weksa.cmd deleted file mode 100644 index 8ddbf57..0000000 --- a/scripts/restart-weksa.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if not "%IDUNN_ACTUATOR%"=="1" ( - echo restart-weksa.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" ( - echo restart-weksa.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2 - exit /b 1 -) -call %~dp0..\..\weksa\scripts\restart-weksa-daemon.cmd diff --git a/scripts/start-odin.ps1 b/scripts/start-odin.ps1 deleted file mode 100644 index 47e0751..0000000 --- a/scripts/start-odin.ps1 +++ /dev/null @@ -1,68 +0,0 @@ -param( - [string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin"), - [string] $CultNetRudpBind = "0.0.0.0:17871", - [string] $IdunnRudpHealth = $(if ($env:ODIN_IDUNN_RUDP_HEALTH) { $env:ODIN_IDUNN_RUDP_HEALTH } else { $env:IDUNN_RUDP_HEALTH }), - [string] $IdunnDaemon = "odin", - [string] $IdunnHealthContract = "odin.cultnet-rudp-provider-health", - [switch] $Foreground -) - -$ErrorActionPreference = "Stop" - -$repoRoot = Split-Path -Parent $PSScriptRoot -$scriptPath = Join-Path $repoRoot "src\odin-coordinator.cjs" -$pidPath = Join-Path $StateDir "odin.pid" -$outLog = Join-Path $StateDir "odin.out.log" -$errLog = Join-Path $StateDir "odin.err.log" -$nodeExe = (Get-Command node.exe -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Source) -if (-not $nodeExe) { - $nodeExe = "C:\Program Files\nodejs\node.exe" -} -if (-not (Test-Path -LiteralPath $nodeExe)) { - throw "Node.js executable is missing; checked PATH and $nodeExe" -} - -if ([string]::IsNullOrWhiteSpace($IdunnRudpHealth)) { - throw "Odin Idunn health publication requires -IdunnRudpHealth, ODIN_IDUNN_RUDP_HEALTH, or IDUNN_RUDP_HEALTH; no localhost default is assumed." -} - -New-Item -ItemType Directory -Force -Path $StateDir | Out-Null - -if (Test-Path $pidPath) { - $oldPid = (Get-Content -Raw $pidPath).Trim() - if ($oldPid -match "^\d+$") { - $old = Get-Process -Id ([int] $oldPid) -ErrorAction SilentlyContinue - if ($old) { - throw "Odin already appears to be running as PID $oldPid." - } - } - Remove-Item -LiteralPath $pidPath -Force -} - -$env:NODE_PATH = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib\packages") -$args = @( - $scriptPath, - "--stateDir", $StateDir, - "--cultnet-rudp-bind", $CultNetRudpBind, - "--idunn-rudp-health", $IdunnRudpHealth, - "--idunn-daemon", $IdunnDaemon, - "--idunn-health-contract", $IdunnHealthContract -) - -if ($Foreground) { - & $nodeExe @args - exit $LASTEXITCODE -} - -$proc = Start-Process -FilePath $nodeExe -ArgumentList $args -WorkingDirectory $repoRoot -WindowStyle Hidden -PassThru -RedirectStandardOutput $outLog -RedirectStandardError $errLog -$proc.Id | Set-Content -Encoding ASCII -LiteralPath $pidPath -Start-Sleep -Seconds 1 -if ($proc.HasExited) { - $detail = "" - if (Test-Path $outLog) { $detail += Get-Content -Raw $outLog } - if (Test-Path $errLog) { $detail += Get-Content -Raw $errLog } - throw "Odin exited immediately with code $($proc.ExitCode).`n$detail" -} - -Write-Host "Odin started as PID $($proc.Id)." -Write-Host "CultMesh/RUDP document catalog: $CultNetRudpBind" diff --git a/scripts/stop-odin.ps1 b/scripts/stop-odin.ps1 deleted file mode 100644 index cfbb412..0000000 --- a/scripts/stop-odin.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -param( - [string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin") -) - -$ErrorActionPreference = "Stop" - -$pidPath = Join-Path $StateDir "odin.pid" -if (-not (Test-Path $pidPath)) { - Write-Host "No Odin PID file found at $pidPath." - exit 0 -} - -$odinPid = (Get-Content -Raw $pidPath).Trim() -if ($odinPid -match "^\d+$") { - $process = Get-Process -Id ([int] $odinPid) -ErrorAction SilentlyContinue - if ($process) { - Stop-Process -Id $process.Id - Write-Host "Stopped Odin PID $odinPid." - } -} - -Remove-Item -LiteralPath $pidPath -Force