diff options
author | Simon Rettberg | 2020-07-07 16:36:46 +0200 |
---|---|---|
committer | Simon Rettberg | 2020-07-07 16:36:46 +0200 |
commit | d635a52fd965519eecb717ea5b953a5f12ef9b88 (patch) | |
tree | 621d70b385d35409ff5a9f93edbf42ba39ad584f /modules-available/systemstatus | |
parent | [systemstatus] Add dnbd3-master-proxy to service status (diff) | |
download | slx-admin-d635a52fd965519eecb717ea5b953a5f12ef9b88.tar.gz slx-admin-d635a52fd965519eecb717ea5b953a5f12ef9b88.tar.xz slx-admin-d635a52fd965519eecb717ea5b953a5f12ef9b88.zip |
[systemstatus/sysconfig] Manage LDADP via systemd
Finally got rid of our own little service manager. Status/restart
handling capabilities were added to the system status page.
TODO: Permissions for dnbd3, service (re)starting in general
Diffstat (limited to 'modules-available/systemstatus')
9 files changed, 180 insertions, 105 deletions
diff --git a/modules-available/systemstatus/lang/de/module.json b/modules-available/systemstatus/lang/de/module.json index dd1a115c..22be8a1d 100644 --- a/modules-available/systemstatus/lang/de/module.json +++ b/modules-available/systemstatus/lang/de/module.json @@ -1,6 +1,8 @@ { "module_name": "System-Status", + "page_title": "Systemstatus des Servers", "tab_DmsdLog": "bwLehrpool-Suite Server Log", + "tab_Dnbd3Log": "DNBD3 Server Log", "tab_LdadpLog": "LDAP\/AD", "tab_LighttpdLog": "lighttpd Log", "tab_Netstat": "netstat -tulpn", diff --git a/modules-available/systemstatus/lang/de/template-tags.json b/modules-available/systemstatus/lang/de/template-tags.json index 27760c1e..6641b9e1 100644 --- a/modules-available/systemstatus/lang/de/template-tags.json +++ b/modules-available/systemstatus/lang/de/template-tags.json @@ -5,6 +5,7 @@ "lang_attention": "Achtung!", "lang_average": "Durchschnitt", "lang_capacity": "Kapazit\u00e4t", + "lang_confirmRestart": "Diesen Dienst wirklich neustarten? Dies kann Auswirkungen auf den Betrieb haben.", "lang_cpuLoad": "CPU-Last", "lang_dmsdUnreachable": "dmsd nicht erreichbar", "lang_failure": "Fehler", @@ -19,6 +20,7 @@ "lang_onlyOS": "Nur OS", "lang_overview": "\u00dcbersicht", "lang_ramUsage": "RAM-Nutzung", + "lang_restart": "Neustarten", "lang_runningDownloads": "Aktive Downloads", "lang_runningUploads": "Aktive Uploads", "lang_serverReboot": "Server neustarten", @@ -32,7 +34,6 @@ "lang_systemPartition": "Systempartition", "lang_systemStoreError": "Fehler beim Ermitteln des verf\u00fcgbaren Systemspeichers", "lang_total": "Gesamt", - "lang_unknownState": "Unbekannter Status", "lang_updatedPackages": "Ausstehende Updates", "lang_uptimeOS": "OS Uptime", "lang_vmStore": "VM-Speicher", diff --git a/modules-available/systemstatus/lang/en/module.json b/modules-available/systemstatus/lang/en/module.json index 9f6d937a..f5fec515 100644 --- a/modules-available/systemstatus/lang/en/module.json +++ b/modules-available/systemstatus/lang/en/module.json @@ -1,6 +1,8 @@ { "module_name": "System Status", + "page_title": "System status of server", "tab_DmsdLog": "bwLehrpool-Suite log", + "tab_Dnbd3Log": "DNBD3 server log", "tab_LdadpLog": "LDAP\/AD", "tab_LighttpdLog": "lighttpd log", "tab_Netstat": "netstat -tulpn", diff --git a/modules-available/systemstatus/lang/en/template-tags.json b/modules-available/systemstatus/lang/en/template-tags.json index de210864..9eec08c4 100644 --- a/modules-available/systemstatus/lang/en/template-tags.json +++ b/modules-available/systemstatus/lang/en/template-tags.json @@ -5,6 +5,7 @@ "lang_attention": "Attention!", "lang_average": "Average", "lang_capacity": "Capacity", + "lang_confirmRestart": "Are you sure you want to restart this service? This can leads to interruptions.", "lang_cpuLoad": "CPU Load", "lang_dmsdUnreachable": "dmsd not reachable", "lang_failure": "Failure", @@ -19,6 +20,7 @@ "lang_onlyOS": "OS only", "lang_overview": "Overview", "lang_ramUsage": "RAM usage", + "lang_restart": "Restart", "lang_runningDownloads": "Running downloads", "lang_runningUploads": "Running uploads", "lang_serverReboot": "Reboot Server", @@ -32,7 +34,6 @@ "lang_systemPartition": "System partition", "lang_systemStoreError": "Error querying available system storage", "lang_total": "Total", - "lang_unknownState": "Unknown status", "lang_updatedPackages": "Pending updates", "lang_uptimeOS": "OS uptime", "lang_vmStore": "VM store", diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php index 6d317b47..f94aa4d4 100644 --- a/modules-available/systemstatus/page.inc.php +++ b/modules-available/systemstatus/page.inc.php @@ -3,8 +3,6 @@ class Page_SystemStatus extends Page { - private $rebootTask = false; - protected function doPreprocess() { User::load(); @@ -14,27 +12,51 @@ class Page_SystemStatus extends Page Util::redirect('?do=Main'); } - if (Request::post('action') === 'reboot') { + $action = Request::post('action', false, 'string'); + if ($action === 'reboot') { User::assertPermission("serverreboot"); - $this->rebootTask = Taskmanager::submit('Reboot'); + $task = Taskmanager::submit('Reboot'); + if (Taskmanager::isTask($task)) { + Util::redirect('?do=systemstatus&taskid=' . $task['id']); + } + } elseif ($action === 'service-start' || $action === 'service-restart') { + $this->handleServiceAction(substr($action, 8)); + } + if (Request::isPost()) { + Util::redirect('?do=systemstatus'); } User::assertPermission('*'); } + private function handleServiceAction(string $action) + { + $service = Request::post('service', Request::REQUIRED, 'string'); + $task = Taskmanager::submit('Systemctl', ['operation' => $action, 'service' => $service]); + $extra = ''; + $cmp = preg_replace('/\.service$|@.*$/', '', $service); + if ($cmp === 'dmsd') { + $extra = '#id-DmsdLog_pane'; + } elseif ($cmp === 'ldadp') { + $extra = '#id-LdadpLog_pane'; + } elseif ($cmp === 'dnbd3-server') { + $extra = '#id-Dnbd3Log_pane'; + } + Util::redirect('?do=systemstatus&taskid=' . $task['id'] . '&taskname=' . urlencode($service) . $extra); + } + protected function doRender() { $data = array(); - if (is_array($this->rebootTask) && isset($this->rebootTask['id'])) { - $data['rebootTask'] = $this->rebootTask['id']; - } - $tabs = array('DmsdLog', 'Netstat', 'PsList', 'LdadpLog', 'LighttpdLog'); + $data['taskid'] = Request::get('taskid', '', 'string'); + $data['taskname'] = Request::get('taskname', 'Reboot', 'string'); + $tabs = array('DmsdLog', 'Netstat', 'PsList', 'LdadpLog', 'LighttpdLog', 'Dnbd3Log'); $data['tabs'] = array(); // Dictionary::translate('tab_DmsdLog') Dictionary::translate('tab_LdadpLog') Dictionary::translate('tab_Netstat') - // Dictionary::translate('tab_LighttpdLog') Dictionary::translate('tab_PsList') + // Dictionary::translate('tab_LighttpdLog') Dictionary::translate('tab_PsList') Dictionary::translate('tab_Dnbd3Log') foreach ($tabs as $tab) { $data['tabs'][] = array( 'type' => $tab, - 'name' => Dictionary::translate('tab_' . $tab), + 'name' => Dictionary::translate('tab_' . $tab, true), 'enabled' => User::hasPermission('tab.' . $tab), ); } @@ -238,10 +260,16 @@ class Page_SystemStatus extends Page 'task' => Taskmanager::submit('Systemctl', ['service' => $svc, 'operation' => 'is-active']) ); } - $tasks[] = array( - 'name' => 'LDAP/AD-Proxy', - 'task' => Trigger::ldadp() - ); + $ldapIds = $ldadp = false; + if (Module::isAvailable('sysconfig')) { + $ldapIds = ConfigModuleBaseLdap::getActiveModuleIds(); + if (!empty($ldapIds)) { + $ldadp = array( // No name - no display + 'task' => ConfigModuleBaseLdap::ldadp('check', $ldapIds) // TODO: Proper --check usage + ); + $tasks[] =& $ldadp; + } + } $deadline = time() + 10; do { $done = true; @@ -257,13 +285,40 @@ class Page_SystemStatus extends Page } while (!$done && time() < $deadline); foreach ($tasks as $task) { + if (!isset($task['name'])) + continue; $fail = Taskmanager::isFailed($task['task']); - $data['services'][] = array( + $entry = array( 'name' => $task['name'], + 'service' => $task['name'], 'fail' => $fail, - 'data' => isset($task['data']) ? $task['data'] : null, - 'unknown' => $task['task'] === false ); + if ($fail) { + if (!isset($task['task']['data'])) { + $entry['error'] = 'Taskmanager Error'; + } elseif (isset($task['task']['data']['messages'])) { + $entry['error'] = $task['task']['data']['messages']; + } + } + $data['services'][] = $entry; + } + if ($ldadp !== false) { + //error_log(print_r($ldadp, true)); + preg_match_all('/^ldadp@(\d+)\.service\s+(\S+)$/m', $ldadp['task']['data']['messages'], $out, PREG_SET_ORDER); + $instances = []; + foreach ($out as $instance) { + $instances[$instance[1]] = $instance[2]; + } + foreach ($ldapIds as $id) { + $status = $instances[$id] ?? 'failed'; + $fail = ($status !== 'running'); + $data['services'][] = [ + 'name' => 'LDAP/AD Proxy #' . $id, + 'service' => 'ldadp@' . $id, + 'fail' => $fail, + 'error' => $fail ? $status : false, + ]; + } } echo Render::parse('services', $data); @@ -271,35 +326,23 @@ class Page_SystemStatus extends Page protected function ajaxDmsdLog() { - User::assertPermission("tab.dmsdlog"); - $fh = @fopen('/var/log/dmsd.log', 'r'); - if ($fh === false) { - echo 'Error opening log file'; - return; - } - fseek($fh, -6000, SEEK_END); - $data = fread($fh, 6000); - @fclose($fh); - if ($data === false) { - echo 'Error reading from log file'; - return; - } - // If we could read less, try the .1 file too - $amount = 6000 - strlen($data); - if ($amount > 100) { - $fh = @fopen('/var/log/dmsd.log.1', 'r'); - if ($fh !== false) { - fseek($fh, -$amount, SEEK_END); - $data = fread($fh, $amount) . $data; - @fclose($fh); - } - } - if (strlen($data) < 5990) { - $start = 0; - } else { - $start = strpos($data, "\n") + 1; - } - echo '<pre>', htmlspecialchars(substr($data, $start), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>'; + $this->showJournal('dmsd.service', 'tab.dmsdlog'); + } + + protected function ajaxDnbd3Log() + { + $this->showJournal('dnbd3-server.service', 'tab.dnbd3log'); + } + + protected function showJournal($service, $permission) + { + User::assertPermission($permission); + $output = [ + 'name' => $service, + 'service' => $service, + 'task' => Taskmanager::submit('Systemctl', ['operation' => 'journal', 'service' => $service]), + ]; + echo Render::parse('ajax-journal', ['modules' => [$output]]); } protected function ajaxLighttpdLog() @@ -338,40 +381,28 @@ class Page_SystemStatus extends Page protected function ajaxLdadpLog() { User::assertPermission("tab.ldadplog"); - $haveSysconfig = Module::isAvailable('sysconfig'); - $files = glob('/var/log/ldadp/*.log', GLOB_NOSORT); - if ($files === false || empty($files)) echo('No logs found'); - $now = time(); - foreach ($files as $file) { - $mod = filemtime($file); - if ($now - $mod > 86400) continue; - // New enough - handle - preg_match(',/(\d+)\.log,', $file, $out); - $module = $haveSysconfig ? ConfigModule::get($out[1]) : false; + if (!Module::isAvailable('sysconfig')) { + die('SysConfig module not enabled'); + } + $ids = ConfigModuleBaseLdap::getActiveModuleIds(); + //error_log(print_r($ids, true)); + $output = []; + foreach ($ids as $id) { + $module = ConfigModule::get($id); if ($module === false) { - echo '<h4>Module ', $out[1], '</h4>'; - } else { - echo '<h4>Module ', htmlspecialchars($module->title()), '</h4>'; - } - $fh = @fopen($file, 'r'); - if ($fh === false) { - echo '<pre>Error opening log file</pre>'; - continue; - } - fseek($fh, -5000, SEEK_END); - $data = fread($fh, 5000); - @fclose($fh); - if ($data === false) { - echo '<pre>Error reading from log file</pre>'; - continue; - } - if (strlen($data) < 4990) { - $start = 0; + $name = "#$id"; } else { - $start = strpos($data, "\n") + 1; + $name = $module->title(); } - echo '<pre>', htmlspecialchars(substr($data, $start), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>'; + $service = "ldadp@{$id}.service"; + $output[] = [ + 'name' => $name, + 'service' => $service, + 'task' => Taskmanager::submit('Systemctl', ['operation' => 'journal', 'service' => $service]), + ]; } + //error_log(print_r($output, true)); + echo Render::parse('ajax-journal', ['modules' => $output]); } protected function ajaxNetstat() diff --git a/modules-available/systemstatus/templates/_page.html b/modules-available/systemstatus/templates/_page.html index f879ea7a..4b62104c 100644 --- a/modules-available/systemstatus/templates/_page.html +++ b/modules-available/systemstatus/templates/_page.html @@ -1,12 +1,12 @@ <h1>{{lang_moduleHeading}}</h1> -{{#rebootTask}} -<div data-tm-id="{{rebootTask}}" data-tm-log="messages">Reboot...</div> -{{/rebootTask}} +{{#taskid}} +<div data-tm-id="{{taskid}}" data-tm-log="messages">{{taskname}}</div> +{{/taskid}} <ul class="nav nav-tabs tabs-up"> <li class="active"> - <a href="#id-default_pane" id="id-default" class="active" data-toggle="tab" role="tab"> + <a href="#id-default_pane" id="id-default" class="ajax-tab" data-toggle="tab" role="tab"> {{lang_overview}} </a> </li> @@ -128,20 +128,32 @@ <script type="text/javascript"><!-- document.addEventListener("DOMContentLoaded", function() { - $('#diskstat').load('?do=SystemStatus&action=DiskStat'); - $('#addresses').load('?do=SystemStatus&action=AddressList'); - $('#systeminfo').load('?do=SystemStatus&action=SystemInfo'); - $('#services').load('?do=SystemStatus&action=Services'); var slxDone = {}; - $('.ajax-tab').on('shown.bs.tab', function (e) { + var loadTab = function (e) { var $this = $(this); var w = $this.attr('id'); if (!slxDone[w]) { slxDone[w] = true; var $pane = $('#' + w + '_pane'); - $pane.load('?do=SystemStatus&action=' + w.substring(3)); + var tab = w.substring(3); + if (tab === 'default') { + $('#diskstat').load('?do=SystemStatus&action=DiskStat'); + $('#addresses').load('?do=SystemStatus&action=AddressList'); + $('#systeminfo').load('?do=SystemStatus&action=SystemInfo'); + $('#services').load('?do=SystemStatus&action=Services'); + } else { + $pane.load('?do=SystemStatus&action=' + tab, function() { + $(this).find('button[data-confirm]').click(slxModalConfirmHandler); + }); + } } - }); + }; + $('.ajax-tab').on('shown.bs.tab', loadTab); + // Need a better solution for this -- there is already code handling tabs in slx-fixes, maybe put this in there? + if (location.hash === '' || location.hash === '#' || location.hash === '#id-default_pane') { + history.replaceState(null, null, '#id-default_pane'); + loadTab.call($('#id-default')); + } var $dmsd = $('#dmsd-users'); $.ajax({ url: '?do=dozmod§ion=special&action=dmsd-status', @@ -159,3 +171,5 @@ }); }, false); //--></script> + +<div class="hidden" id="confirm-restart">{{lang_confirmRestart}}</div>
\ No newline at end of file diff --git a/modules-available/systemstatus/templates/ajax-journal.html b/modules-available/systemstatus/templates/ajax-journal.html new file mode 100644 index 00000000..0405fe93 --- /dev/null +++ b/modules-available/systemstatus/templates/ajax-journal.html @@ -0,0 +1,19 @@ +<form method="post" action="?do=systemstatus"> + <input type="hidden" name="token" value="{{token}}"> + <input type="hidden" name="action" value="service-restart"> + {{#modules}} + <div class="slx-space"> + <div class="pull-right"> + <button class="btn btn-warning btn-sm pull-right" name="service" value="{{service}}" data-confirm="#confirm-restart"> + <span class="glyphicon glyphicon-refresh"></span> + {{lang_restart}} + </button> + </div> + <h4>{{name}}</h4> + <div data-tm-id="{{task.id}}" data-tm-log="messages">{{service}}</div> + </div> + {{/modules}} +</form> +<script> + tmInit(); +</script>
\ No newline at end of file diff --git a/modules-available/systemstatus/templates/services.html b/modules-available/systemstatus/templates/services.html index 29b33687..2614fca9 100644 --- a/modules-available/systemstatus/templates/services.html +++ b/modules-available/systemstatus/templates/services.html @@ -1,20 +1,20 @@ +<form method="post" action="?do=systemstatus"> + <input type="hidden" name="token" value="{{token}}"> + <input type="hidden" name="action" value="service-start"> + <table class="table"> {{#services}} - {{#unknown}} - <div class="alert alert-warning"> - {{name}}: {{lang_unknownState}} - </div> - {{/unknown}} - {{^unknown}} + <tr class="bg-{{#fail}}danger{{/fail}}{{^fail}}success{{/fail}}"> + <td> {{#fail}} - <div class="alert alert-danger"> - {{name}}: <b>{{lang_failure}}</b> - {{#data.messages}}<pre>{{data.messages}}</pre>{{/data.messages}} - </div> + <button class="btn btn-default btn-xs pull-right" name="service" value="{{service}}"> + {{lang_restart}} + </button> {{/fail}} - {{^fail}} - <div class="alert alert-success"> - {{name}}: {{lang_OK}} - </div> - {{/fail}} - {{/unknown}} + {{name}}: {{#fail}}{{lang_failure}}{{/fail}}{{^fail}}{{lang_OK}}{{/fail}} + <div class="clearfix"></div> + {{#error}}<pre>{{error}}</pre>{{/error}} + </td> + </tr> {{/services}} + </table> +</form>
\ No newline at end of file diff --git a/modules-available/systemstatus/templates/systeminfo.html b/modules-available/systemstatus/templates/systeminfo.html index ed4a1532..cf3f0cc2 100644 --- a/modules-available/systemstatus/templates/systeminfo.html +++ b/modules-available/systemstatus/templates/systeminfo.html @@ -61,6 +61,7 @@ wrpClass: 'circles-wrp', textClass: 'circles-text' }); + var $cpu = $(cpuCircle._el); var lastCpuTotal = {{CpuTotal}}; var lastCpuIdle = {{CpuIdle}}; var lastCpuPercent = {{cpuLoad}}; @@ -93,6 +94,10 @@ {{/memTotal}} function updateSystem() { if (!cpuCircle && !memCircle) return; + if (!$cpu.is(':visible')) { + setTimeout(updateSystem, 1200); + return; + } $.post('?do=SystemStatus&action=SysPoll', { token: TOKEN }, function(data) { if (memCircle && data.MemPercent) memCircle.update(data.MemPercent); if (swapCircle && data.SwapPercent) swapCircle.update(data.SwapPercent); |