#!/usr/bin/env php 0 ? " Offene Migrationen: " . $pending : "")); return true; } $migrations = $hook["migrations"] ?? []; $applied = $migrations["applied"] ?? []; if ($applied !== []) { manageCliOut(" Migrationen ausgeführt: " . implode(", ", $applied)); } if (!empty($hook["success"])) { if (!empty($hook["hook"]["configured"])) { manageCliOut(" Post-Update-Hook ausgeführt."); } return true; } if (!empty($hook["failed_migration"])) { manageCliError(" FEHLER in Migration " . $hook["failed_migration"] . ": " . (string) $hook["error"]); manageCliError(" Verbleibende Migrationen wurden NICHT ausgeführt."); manageCliError(" Ursache beheben und danach erneut ausführen: manage-client.php migrate"); } else { manageCliError(" FEHLER im Post-Update-Hook: " . (string) ($hook["error"] ?? "unbekannt")); } return false; } try { switch ($command) { case "status": $status = manageClientStatus(); manageCliOut("Instanz: " . ($status["instance"] !== "" ? $status["instance"] : "(nicht gesetzt)")); manageCliOut("Server: " . ($status["server_url"] !== "" ? $status["server_url"] : "(nicht gesetzt)")); manageCliOut("Konfiguriert: " . ($status["configured"] ? "ja" : "NEIN")); manageCliOut("Installierte Ver.: " . ($status["version"] !== "" ? $status["version"] : "unbekannt")); manageCliOut("PHP: " . $status["php_version"]); if ($status["update"] !== null) { manageCliOut("Aktuelles Release: " . $status["update"]["latest"]); manageCliOut("Update verfügbar: " . ($status["update"]["available"] ? "JA" : "nein")); } elseif ($status["update_error"] !== null) { manageCliOut("Update-Prüfung: fehlgeschlagen (" . $status["update_error"] . ")"); } manageCliOut("Lokale Backups: " . count($status["backups"])); manageCliOut("Letztes Backup: " . ($status["last_backup_at"] ?? "nie")); manageCliOut("Offene Migrationen: " . count($status["pending_migrations"])); foreach ($status["pending_migrations"] as $migration) { manageCliOut(" - " . $migration["id"]); } foreach ($status["errors"] as $error) { manageCliError("Warnung: " . $error); } exit(0); case "check": $check = manageUpdateCheck(); manageCliOut("Installiert: " . ($check["current"] !== "" ? $check["current"] : "unbekannt")); manageCliOut("Verfügbar: " . $check["latest"]); if ($check["available"]) { manageCliOut("Ein Update ist verfügbar."); exit(2); } manageCliOut("Die Installation ist aktuell."); exit(0); case "update": $check = manageUpdateCheck(); $force = isset($flags["force"]); if (!$check["available"] && !$force) { manageCliOut("Kein Update verfügbar. Mit --force kann dasselbe Paket erneut ausgerollt werden."); exit(0); } if (!manageCliConfirm( "Version " . $check["latest"] . " jetzt ausrollen" . ($check["current"] !== "" ? " (installiert: " . $check["current"] . ")" : "") . "?" )) { manageCliOut("Abgebrochen."); exit(0); } $result = manageUpdateApply([ "force" => $force, "skip_hook" => isset($flags["skip-hook"]), ]); manageCliOut("Update ausgerollt: " . $result["from_version"] . " -> " . $result["to_version"]); manageCliOut(" Dateien kopiert: " . $result["copied"]); manageCliOut(" Dateien gesichert: " . $result["backed_up"]); manageCliOut(" Geschützt übersprungen: " . $result["skipped"]); manageCliOut(" Sicherungsverzeichnis: " . $result["backup_dir"]); $hookOk = manageCliReportHook($result["hook"]); manageHeartbeatSendQuietly(); // The deployment succeeded either way; the exit code reports the // post-update step so a cron job notices a failed migration. exit($hookOk ? 0 : 1); case "migrate": $pending = manageUpdatePendingMigrations(); if ($pending === []) { manageCliOut("Keine offenen Migrationen."); exit(0); } manageCliOut("Offene Migrationen: " . count($pending)); foreach ($pending as $migration) { manageCliOut(" - " . $migration["id"]); } if (isset($flags["dry-run"])) { manageCliOut("--dry-run: nichts ausgeführt."); exit(0); } if (!manageCliConfirm("Diese Migrationen jetzt ausführen?")) { manageCliOut("Abgebrochen."); exit(0); } $report = manageUpdateRunMigrations(); if ($report["applied"] !== []) { manageCliOut("Ausgeführt: " . implode(", ", $report["applied"])); } if (!$report["success"]) { manageCliError("FEHLER in Migration " . (string) $report["failed"] . ": " . (string) $report["error"]); manageCliError("Verbleibende Migrationen: " . ($report["pending"] - 1)); exit(1); } manageCliOut("Alle Migrationen abgeschlossen."); manageHeartbeatSendQuietly(); exit(0); case "backup": $trigger = is_string($flags["trigger"] ?? null) ? (string) $flags["trigger"] : "manual"; $record = manageBackupCreate($trigger); manageCliOut("Backup erstellt: " . $record["filename"]); manageCliOut(" Dateien: " . $record["file_count"]); manageCliOut(" Größe: " . manageFormatBytes((int) $record["size"])); manageCliOut(" SHA-256: " . $record["sha256"]); if (is_array($record["database"] ?? null)) { manageCliOut(" Datenbank: " . $record["database"]["tables"] . " Tabellen, " . $record["database"]["rows"] . " Zeilen"); } $failed = false; foreach ($record["remote_uploads"] as $upload) { if (!empty($upload["success"])) { manageCliOut(" Upload " . $upload["target"] . ": OK"); } else { $failed = true; manageCliError(" Upload " . $upload["target"] . " FEHLGESCHLAGEN: " . (string) ($upload["error"] ?? "unbekannt")); } } manageHeartbeatSendQuietly(); // The local archive exists regardless, but a failed upload must be // visible to cron. exit($failed ? 1 : 0); case "heartbeat": $result = manageHeartbeatSend(); manageCliOut("Heartbeat gesendet."); manageCliOut(" Aktuelles Release: " . ($result["latest"] !== "" ? $result["latest"] : "keines")); manageCliOut(" Update verfügbar: " . ($result["update_available"] ? "JA" : "nein")); exit(0); case "": case "help": case "-h": case "--help": manageCliUsage(); exit(0); default: manageCliError("Unbekannter Befehl: " . $command); manageCliUsage(); exit(1); } } catch (Throwable $exception) { manageCliError("Fehler: " . $exception->getMessage()); exit(1); }