Add self-healing Cloudflare tunnel with 60s watchdog for USB deck.
Replaces fragile batch-based tunnel install with a single PowerShell script (cloudflare/start-tunnel.ps1) that installs cloudflared as a Windows service (admin) or runs as a background process (non-admin), clears stale EventLog registry keys that caused service rollback, and runs a 60-second watchdog that auto-restarts the connector on failure. Hostname changed to aether.thetempleofdoom.com. LAUNCH.bat and pack-usb.bat updated accordingly.
This commit is contained in:
115
cloudflare/repair-tunnel.ps1
Normal file
115
cloudflare/repair-tunnel.ps1
Normal file
@@ -0,0 +1,115 @@
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Root,
|
||||
[ValidateRange(1, 4)][int]$Level = 1
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$Root = $Root.TrimEnd('\')
|
||||
$configJson = Join-Path $Root 'cloudflare\tunnel-config.json'
|
||||
$installBat = Join-Path $Root 'cloudflare\install-tunnel.bat'
|
||||
$writer = Join-Path $Root 'cloudflare\write-tunnel-config.ps1'
|
||||
$cfDir = Join-Path $env:ProgramData 'AetherForge\.cloudflared'
|
||||
$cfConfig = Join-Path $cfDir 'config.yml'
|
||||
$cfExe = Join-Path $env:ProgramData 'AetherForge\bin\cloudflared.exe'
|
||||
|
||||
function Write-RepairLog([string]$Message) {
|
||||
$line = "{0} [CF-HEAL-L{1}] {2}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Level, $Message
|
||||
Write-Output $line
|
||||
}
|
||||
|
||||
function Get-ServiceRunning {
|
||||
$q = sc.exe query cloudflared 2>&1 | Out-String
|
||||
return ($q -match 'STATE\s+:\s+\d+\s+RUNNING')
|
||||
}
|
||||
|
||||
function Start-CloudflaredService {
|
||||
$null = net.exe start cloudflared 2>&1
|
||||
Start-Sleep -Seconds 3
|
||||
return (Get-ServiceRunning)
|
||||
}
|
||||
|
||||
function Stop-CloudflaredService {
|
||||
$null = net.exe stop cloudflared 2>&1
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
function Restart-CloudflaredService {
|
||||
Stop-CloudflaredService
|
||||
return (Start-CloudflaredService)
|
||||
}
|
||||
|
||||
Write-RepairLog "Repair level $Level starting..."
|
||||
|
||||
switch ($Level) {
|
||||
1 {
|
||||
Write-RepairLog "Action: net start cloudflared"
|
||||
if (Start-CloudflaredService) {
|
||||
Write-RepairLog "Service is RUNNING"
|
||||
exit 0
|
||||
}
|
||||
Write-RepairLog "net start failed"
|
||||
exit 1
|
||||
}
|
||||
2 {
|
||||
Write-RepairLog "Action: restart cloudflared service"
|
||||
if (Restart-CloudflaredService) {
|
||||
Write-RepairLog "Service restarted OK"
|
||||
exit 0
|
||||
}
|
||||
Write-RepairLog "Restart failed"
|
||||
exit 1
|
||||
}
|
||||
3 {
|
||||
Write-RepairLog "Action: rewrite config.yml + restart + DNS route"
|
||||
if (-not (Test-Path $configJson)) {
|
||||
Write-RepairLog "Missing tunnel-config.json"
|
||||
exit 1
|
||||
}
|
||||
if (-not (Test-Path $writer)) {
|
||||
Write-RepairLog "Missing write-tunnel-config.ps1"
|
||||
exit 1
|
||||
}
|
||||
$tunnelId = $null
|
||||
$hostname = $null
|
||||
& $writer -ConfigJson $configJson -CloudflaredDir $cfDir | ForEach-Object {
|
||||
if ($_ -match '^TUNNEL_ID=(.+)$') { $tunnelId = $Matches[1] }
|
||||
if ($_ -match '^HOSTNAME=(.+)$') { $hostname = $Matches[1] }
|
||||
Write-RepairLog $_
|
||||
}
|
||||
if (-not (Test-Path $cfConfig)) {
|
||||
Write-RepairLog "config.yml write failed"
|
||||
exit 1
|
||||
}
|
||||
Restart-CloudflaredService | Out-Null
|
||||
if ($cfExe -and (Test-Path $cfExe) -and $tunnelId -and $hostname) {
|
||||
Write-RepairLog "Action: tunnel route dns $hostname"
|
||||
& $cfExe --config $cfConfig tunnel route dns $tunnelId $hostname 2>&1 | ForEach-Object { Write-RepairLog $_ }
|
||||
}
|
||||
if (Get-ServiceRunning) {
|
||||
Write-RepairLog "Config refresh + service RUNNING"
|
||||
exit 0
|
||||
}
|
||||
Write-RepairLog "Still not RUNNING after config refresh"
|
||||
exit 1
|
||||
}
|
||||
4 {
|
||||
Write-RepairLog "Action: full tunnel reinstall (install-tunnel.bat)"
|
||||
if (-not (Test-Path $installBat)) {
|
||||
Write-RepairLog "Missing install-tunnel.bat"
|
||||
exit 1
|
||||
}
|
||||
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
|
||||
[Security.Principal.WindowsBuiltInRole]::Administrator
|
||||
)
|
||||
if ($isAdmin) {
|
||||
& cmd.exe /c "`"$installBat`" `"$Root`""
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
Write-RepairLog "Requesting elevated reinstall (UAC)..."
|
||||
$p = Start-Process -FilePath $installBat -ArgumentList "`"$Root`"" -Verb RunAs -Wait -PassThru
|
||||
exit $p.ExitCode
|
||||
}
|
||||
}
|
||||
|
||||
Write-RepairLog "Unknown level"
|
||||
exit 1
|
||||
Reference in New Issue
Block a user