Files
rippy/deploy/worker-windows/install.ps1
T
Hitonabi 8f208ed0da
Ampel / ampel (push) Successful in 28s
fix(worker-windows): Autostart brach die ganze Installation ab
Beim Commander live aufgetreten: Der Installer meldete
"FEHLER: FEHLER: Zugriff verweigert" samt dem Tipp, die IP koenne falsch sein -
und das, NACHDEM Worker-Code, Abhaengigkeiten und HandBrake schon fertig waren.
Die IP war also nie das Problem.

URSACHE: schtasks /create mit /tn "RippyWorker" legt die Aufgabe im
WURZELORDNER der Aufgabenplanung an, und das verlangt Administratorrechte. Der
Installer laeuft normal ohne. schtasks schrieb "FEHLER: Zugriff verweigert."
nach stderr, und weil im Skript $ErrorActionPreference = "Stop" steht, machte
PowerShell daraus einen TERMINIERENDEN Fehler - der catch-Block riss damit die
komplette Installation ab, obwohl nur der Autostart fehlte. Das doppelte
"FEHLER: FEHLER:" war der Hinweis: der aeussere Handler setzt sein Praefix vor
eine Meldung, die selbst schon mit "FEHLER:" begann, also aus schtasks kam.

FIX, zwei Teile:

1. Autostart ueber den Autostart-ORDNER statt schtasks. Eine Verknuepfung in
   [Environment]::GetFolderPath("Startup") braucht NIE Adminrechte - und der
   Nutzer kann sie dort selbst sehen und loeschen. Auf diesem Windows-PC
   gegengeprueft: Verknuepfung angelegt (1047 Bytes) mit Admin=False.
2. Ein Fehlschlag beim Autostart ist jetzt eine WARNUNG in eigenem try/catch,
   kein Abbruch. Der Worker ist zu dem Zeitpunkt fertig und startbar, und der
   Text sagt das auch - plus den Handweg (shell:startup).

In BEIDEN Installern (install-gui.ps1 und install.ps1, dort mit -Autostart) -
der CLI-Weg hatte denselben Fehler. uninstall.ps1 raeumt jetzt die
Verknuepfung weg UND versucht weiter schtasks /delete, damit aeltere
Installationen sauber verschwinden.

RippyWorkerSetup.exe neu gebaut (50688 -> 52736 Bytes): die GUI ist in der .exe
eingebettet, ohne Rebuild wirkt der Fix beim Nutzer nicht.

Nebenbei: build-exe.ps1 hatte zwei Gedankenstriche. Ausgelieferte .ps1 muessen
reines ASCII sein (PowerShell 5.1 liest sie als ANSI) - jetzt sind alle drei
Skripte ASCII-rein und parsen fehlerfrei.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 22:11:39 +02:00

181 lines
8.0 KiB
PowerShell

# Rippy: Nativer Windows-Transcode-Worker - Installation OHNE Docker.
#
# Was das Skript tut (alles in einen Unterordner "rippy-worker"):
# 1. Prueft Python (3.10+), legt ein venv an, installiert die Abhaengigkeiten
# 2. Laedt den Worker-Code direkt von deiner Rippy-Instanz (/api/worker-setup/paket)
# 3. Laedt HandBrakeCLI (gepinnte Version, offizielles GitHub-Release),
# falls nicht schon im PATH oder im Ordner vorhanden
# 4. Erzeugt start-worker.bat - Doppelklick startet den Worker
#
# Der Worker bedient NUR die Kompressions-Queue (transcode) - gerippt wird
# weiterhin auf der Rippy-Hauptmaschine (dort haengt das Laufwerk).
#
# Aufruf (PowerShell):
# .\install.ps1 -RippyHost 192.168.178.162 [-WorkerName mein-pc] [-Autostart]
#
# -Autostart registriert eine Aufgabe "RippyWorker" (Start bei Anmeldung).
param(
[Parameter(Mandatory = $true)] [string]$RippyHost,
[string]$WorkerName = $env:COMPUTERNAME.ToLower(),
[switch]$Autostart
)
$ErrorActionPreference = "Stop"
# HandBrake-Version: die NEUESTE offizielle (GitHub-Release) - so passt der
# Windows-Worker zu dem, was der Update-Check im UI meldet (frueher war hier
# eine feste 1.9.2 hardcodiert, was verwirrte). Faellt auf eine bekannte
# Version zurueck, falls die GitHub-API gerade nicht erreichbar ist.
$HandBrakeVersion = "1.11.2"
try {
$rel = Invoke-RestMethod "https://api.github.com/repos/HandBrake/HandBrake/releases/latest" `
-TimeoutSec 15 -Headers @{ "User-Agent" = "rippy-installer" }
if ($rel.tag_name) { $HandBrakeVersion = ([string]$rel.tag_name).TrimStart("v") }
Write-Host "Neueste HandBrake-Version: $HandBrakeVersion"
} catch { Write-Host "GitHub-API nicht erreichbar - nutze HandBrake $HandBrakeVersion" }
$HandBrakeUrl = "https://github.com/HandBrake/HandBrake/releases/download/$HandBrakeVersion/HandBrakeCLI-$HandBrakeVersion-win-x86_64.zip"
Write-Host "== Rippy Windows-Worker Installation ==" -ForegroundColor Cyan
# 1. Python finden (py-Launcher oder python im PATH)
$python = $null
foreach ($kandidat in @("py -3", "python")) {
try {
$version = Invoke-Expression "$kandidat --version" 2>&1
if ("$version" -match "Python 3\.(\d+)") {
if ([int]$Matches[1] -ge 10) { $python = $kandidat; break }
}
} catch {}
}
if (-not $python) {
Write-Host "FEHLER: Python 3.10+ nicht gefunden." -ForegroundColor Red
Write-Host "Installieren mit: winget install Python.Python.3.12 (dann Skript erneut ausfuehren)"
exit 1
}
Write-Host "Python gefunden: $python"
# 2. Arbeitsordner + Worker-Code von der Rippy-Instanz laden
$ziel = Join-Path (Get-Location) "rippy-worker"
New-Item -ItemType Directory -Force $ziel | Out-Null
Set-Location $ziel
Write-Host "Lade Worker-Code von http://$RippyHost/api/worker-setup/paket ..."
Invoke-WebRequest "http://$RippyHost/api/worker-setup/paket" -OutFile worker.zip -UseBasicParsing
Expand-Archive worker.zip -DestinationPath . -Force
Remove-Item worker.zip
# 3. venv + Abhaengigkeiten
if (-not (Test-Path "venv")) {
Write-Host "Lege Python-Umgebung an ..."
Invoke-Expression "$python -m venv venv"
}
& .\venv\Scripts\python.exe -m pip install --quiet --upgrade pip
& .\venv\Scripts\pip.exe install --quiet -r requirements.txt
# Nur fuer den Windows-Worker: Tray-Symbol (Status, Start/Stopp, Beenden)
& .\venv\Scripts\pip.exe install --quiet pystray pillow
Write-Host "Python-Abhaengigkeiten installiert."
# 4. HandBrakeCLI besorgen (falls noetig)
$hb = Get-Command HandBrakeCLI.exe -ErrorAction SilentlyContinue
if (-not $hb -and -not (Test-Path ".\HandBrakeCLI.exe")) {
Write-Host "Lade HandBrakeCLI $HandBrakeVersion (offizielles GitHub-Release) ..."
Invoke-WebRequest $HandBrakeUrl -OutFile hb.zip -UseBasicParsing
Expand-Archive hb.zip -DestinationPath . -Force
Remove-Item hb.zip
}
if (-not (Test-Path ".\HandBrakeCLI.exe") -and -not $hb) {
Write-Host "FEHLER: HandBrakeCLI.exe fehlt." -ForegroundColor Red
exit 1
}
Write-Host "HandBrakeCLI bereit."
# 5. Start-Skript erzeugen
$bat = @"
@echo off
rem Rippy Windows-Transcode-Worker - verbindet sich mit $RippyHost
cd /d "%~dp0"
set REDIS_URL=redis://${RippyHost}:6379/0
set DATABASE_URL=postgresql://rippy:rippy@${RippyHost}:5432/rippy
set API_URL=http://${RippyHost}:8000
set WORKER_NAME=$WorkerName
set PATH=%~dp0;%PATH%
venv\Scripts\celery.exe -A celery_app worker --loglevel=info -Q transcode --pool=solo -n ${WorkerName}@%%h
"@
Set-Content -Path "start-worker.bat" -Value $bat -Encoding ASCII
# 6. Tray-Start (empfohlen): Symbol neben der Uhr, kein Konsolenfenster
$trayBat = @"
@echo off
rem Rippy-Worker mit Tray-Symbol - verbindet sich mit $RippyHost
cd /d "%~dp0"
set REDIS_URL=redis://${RippyHost}:6379/0
set DATABASE_URL=postgresql://rippy:rippy@${RippyHost}:5432/rippy
set API_URL=http://${RippyHost}:8000
set WORKER_NAME=$WorkerName
set RIPPY_TRAY_HOST=$RippyHost
set PATH=%~dp0;%PATH%
start "" venv\Scripts\pythonw.exe tray.py
"@
Set-Content -Path "start-tray.bat" -Value $trayBat -Encoding ASCII
Write-Host "start-worker.bat + start-tray.bat erzeugt."
# 7. Deinstaller - MUSS-Kriterium: rueckstandsfrei entfernbar
$uninstall = @"
# Rippy-Worker DEINSTALLIEREN: stoppt Prozesse, entfernt Autostart,
# meldet den Worker in Rippy ab und loescht diesen Ordner komplett.
param([switch]`$Force)
if (-not `$Force) {
`$antwort = Read-Host "Rippy-Worker '$WorkerName' wirklich deinstallieren? (j/n)"
if (`$antwort -ne "j") { Write-Host "Abgebrochen."; exit }
}
Get-CimInstance Win32_Process | Where-Object {
`$_.ExecutablePath -like "`$PSScriptRoot*"
} | ForEach-Object { Stop-Process -Id `$_.ProcessId -Force -ErrorAction SilentlyContinue }
Start-Sleep 2
# Autostart-Verknuepfung entfernen (neuer Weg) ...
try { Remove-Item -Force (Join-Path ([Environment]::GetFolderPath("Startup")) "RippyWorker.lnk") -ErrorAction Stop } catch {}
# ... und die geplante Aufgabe aus aelteren Installationen, falls vorhanden.
schtasks /delete /tn "RippyWorker" /f 2>`$null | Out-Null
try {
Invoke-RestMethod -Method Delete "http://$RippyHost/api/workers/$WorkerName" -TimeoutSec 5 | Out-Null
Write-Host "Worker-Eintrag in Rippy entfernt."
} catch { Write-Host "Hinweis: Eintrag in Rippy ggf. von Hand loeschen (Einstellungen -> Worker)." }
Set-Location (Split-Path `$PSScriptRoot -Parent)
Remove-Item -Recurse -Force `$PSScriptRoot
Write-Host "Rippy-Worker deinstalliert." -ForegroundColor Green
"@
Set-Content -Path "uninstall.ps1" -Value $uninstall -Encoding ASCII
Write-Host "uninstall.ps1 erzeugt."
# 8. Optional: Autostart bei Anmeldung (mit Tray)
#
# Ueber den Autostart-ORDNER, nicht ueber schtasks: Eine Aufgabe im
# Wurzelordner der Aufgabenplanung anzulegen verlangt Administratorrechte, und
# der Installer laeuft normal ohne. Auf dem Commander-PC scheiterte das am
# 25.07.2026 mit "FEHLER: Zugriff verweigert." - und weil oben
# $ErrorActionPreference = "Stop" steht, riss es die ganze Installation mit,
# obwohl nur der Autostart fehlte. Der Autostart-Ordner braucht nie Adminrechte.
if ($Autostart) {
try {
$autostartOrdner = [Environment]::GetFolderPath("Startup")
$wsh = New-Object -ComObject WScript.Shell
$lnk = $wsh.CreateShortcut((Join-Path $autostartOrdner "RippyWorker.lnk"))
$lnk.TargetPath = (Join-Path $ziel "start-tray.bat")
$lnk.WorkingDirectory = $ziel
$lnk.Description = "Rippy Encoding-Worker"
$lnk.Save()
Write-Host "Autostart eingerichtet (Verknuepfung im Autostart-Ordner)."
} catch {
Write-Host "HINWEIS: Autostart konnte nicht eingerichtet werden ($($_.Exception.Message))." -ForegroundColor Yellow
Write-Host " Der Worker ist trotzdem fertig installiert." -ForegroundColor Yellow
Write-Host " Von Hand: start-tray.bat in shell:startup verknuepfen." -ForegroundColor Yellow
}
}
Write-Host ""
Write-Host "FERTIG." -ForegroundColor Green
Write-Host " Starten (mit Tray-Symbol): $ziel\start-tray.bat"
Write-Host " Starten (Konsole/Debug): $ziel\start-worker.bat"
Write-Host " Deinstallieren: $ziel\uninstall.ps1"
Write-Host "Der Worker erscheint in Rippy unter Einstellungen -> Worker als '$WorkerName'."