Add services management with pagination and conditional buttons

This commit is contained in:
2026-06-06 18:56:42 -04:00
parent e0c4ec7a53
commit 7a8792a1e9
4 changed files with 227 additions and 0 deletions

View File

@@ -1475,6 +1475,87 @@ class ServerController
$this->view->json(['success' => true, 'data' => $result]);
}
public function services(int $id): void
{
$server = $this->serverModel->findById($id);
if (!$server) { $this->view->error(404); }
try {
$ssh = new SSHService();
if (!$ssh->connect($server)) {
throw new \RuntimeException('Could not establish SSH connection');
}
$this->auditService->logCredentialAccess($id, 'View services');
$listResult = $ssh->exec("systemctl list-units --type=service --all --no-pager --no-legend 2>/dev/null | awk '{print \$1, \$3}'");
$serviceNames = [];
foreach (explode("\n", trim($listResult['output'] ?? '')) as $line) {
if (preg_match('/^(\S+)\s+(\S+)/', $line, $m)) {
$serviceNames[$m[1]] = $m[2] === 'active' ? 'active' : ($m[2] === 'inactive' ? 'inactive' : 'other');
}
}
$enabledNames = [];
$enabledResult = $ssh->exec("systemctl list-unit-files --type=service --no-pager --no-legend 2>/dev/null | awk '\$2==\"enabled\"{print \$1}'");
foreach (explode("\n", trim($enabledResult['output'] ?? '')) as $line) {
$enabledNames[trim($line)] = true;
}
$services = [];
foreach ($serviceNames as $name => $status) {
$services[] = [
'name' => $name,
'status' => $status,
'enabled' => isset($enabledNames[$name]),
];
}
$ssh->disconnect();
$this->view->display('servers.services', [
'title' => 'Services - ' . $server['name'] . ' - ServerManager',
'server' => $server,
'services' => $services,
]);
} catch (\Throwable $e) {
Session::setFlash('error', 'Failed to get services: ' . $e->getMessage());
$this->view->redirect("/servers/{$id}");
}
}
public function servicesAction(int $id): void
{
$server = $this->serverModel->findById($id);
if (!$server) {
$this->view->json(['success' => false, 'message' => 'Server not found'], 404);
}
$action = $_POST['action'] ?? '';
$service = $_POST['service'] ?? '';
$allowed = ['start', 'stop', 'restart', 'reload', 'enable', 'disable'];
if (empty($service) || !in_array($action, $allowed, true)) {
$this->view->json(['success' => false, 'message' => 'Invalid action or service']);
}
try {
$ssh = new SSHService();
if (!$ssh->connect($server)) {
throw new \RuntimeException('Could not establish SSH connection');
}
$this->auditService->logServerAction($id, "service_{$action}", "{$service} {$action}");
$result = $ssh->exec("sudo systemctl {$action} {$service} 2>&1; echo EXIT:\$?");
$exitCode = (int) trim(explode('EXIT:', $result['output'] ?? 'EXIT:-1')[1] ?? '-1');
$ssh->disconnect();
$this->view->json([
'success' => $exitCode === 0,
'message' => $exitCode === 0 ? "Service '{$service}' {$action}ed." : "Failed to {$action} '{$service}'.",
'output' => trim($result['output']),
]);
} catch (\Throwable $e) {
$this->view->json(['success' => false, 'message' => 'Failed: ' . $e->getMessage()]);
}
}
public function systemUsers(int $id): void
{
$server = $this->serverModel->findById($id);