module_fn('pi_control', 'table', $name); $notice = null; $error = null; $terminalNotice = null; $terminalError = null; $terminalUrl = null; $settings = modules()->settings('pi_control'); $ttydUrl = trim((string)($settings['ttyd_url'] ?? '/ttyd')); $defaultProvider = 'ttyd'; $tokenTtl = (int)($settings['terminal_token_ttl'] ?? 10); $tokenTtl = $tokenTtl > 0 ? $tokenTtl : 10; $hosts = $pdo->query('SELECT * FROM ' . $table('hosts') . ' ORDER BY name ASC')->fetchAll(PDO::FETCH_ASSOC); $commands = $pdo->query('SELECT * FROM ' . $table('commands') . ' ORDER BY label ASC')->fetchAll(PDO::FETCH_ASSOC); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = (string)($_POST['action'] ?? ''); if ($action === 'open_console') { $hostId = (int)($_POST['terminal_host_id'] ?? 0); $provider = 'ttyd'; if ($hostId <= 0) { $terminalError = 'Bitte einen Host wählen.'; } elseif ($ttydUrl === '') { $terminalError = 'ttyd URL fehlt. Bitte im Setup setzen.'; } else { $driver = (string)$pdo->getAttribute(PDO::ATTR_DRIVER_NAME); $expiresSql = $driver === 'pgsql' ? "NOW() + INTERVAL '{$tokenTtl} minutes'" : "DATETIME('now', '+{$tokenTtl} minutes')"; $token = bin2hex(random_bytes(24)); $stmt = $pdo->prepare( 'INSERT INTO ' . $table('sessions') . ' (token, host_id, provider, created_by, expires_at) VALUES (:token, :host_id, :provider, :created_by, ' . $expiresSql . ')' ); $stmt->execute([ 'token' => $token, 'host_id' => $hostId, 'provider' => $provider, 'created_by' => auth_display_name() ?: null, ]); $sep = str_contains($ttydUrl, '?') ? '&' : '?'; $terminalUrl = rtrim($ttydUrl, '/') . '/' . $sep . 'arg=' . rawurlencode($token); } } else { $hostId = (int)($_POST['host_id'] ?? 0); $commandId = (int)($_POST['command_id'] ?? 0); $rawCommand = trim((string)($_POST['command_text'] ?? '')); if ($hostId <= 0) { $error = 'Bitte einen Host wählen.'; } elseif ($commandId <= 0 && $rawCommand === '') { $error = 'Bitte einen Befehl wählen oder einen Befehl eingeben.'; } else { $selectedCommand = ''; if ($commandId > 0) { foreach ($commands as $c) { if ((int)$c['id'] === $commandId) { if (!auth_is_admin() && !empty($c['admin_only'])) { $error = 'Dieser Befehl ist nur für Admins.'; } else { $selectedCommand = (string)$c['command']; } break; } } } if (!$error) { $commandText = $selectedCommand !== '' ? $selectedCommand : $rawCommand; $stmt = $pdo->prepare( 'INSERT INTO ' . $table('runs') . ' (host_id, command_id, command_text, status, created_by) VALUES (:host_id, :command_id, :command_text, :status, :created_by)' ); $stmt->execute([ 'host_id' => $hostId, 'command_id' => $commandId > 0 ? $commandId : null, 'command_text' => $commandText, 'status' => 'pending', 'created_by' => auth_display_name() ?: null, ]); $notice = 'Befehl wurde erfasst. (Execution-Backend folgt)'; } } } } $runs = $pdo->query('SELECT * FROM ' . $table('runs') . ' ORDER BY id DESC LIMIT 20')->fetchAll(PDO::FETCH_ASSOC); ?>
Pi Control

Konsole

Wähle einen Host und führe einen Befehl aus.

Live-Konsole
Aktive Konsole In neuem Tab öffnen
Befehl ausführen

Hinweis: Execution-Backend wird im nächsten Schritt ergänzt.

Letzte Runs
ID Status Command Von
Noch keine Runs.