<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>-</title> <link rel="stylesheet" href="css/bootstrap.min.css"> <style> .button-expand { margin-right: 1em; } h1, .h1 { margin-top: 20px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col"> <h1 id="hostname">-</h1> <p style="margin-bottom: 0;"><small>refreshed every <span id="status_refresh_interval">-</span> seconds</small></p> </div> <div class="col h1 text-right"> <div class="btn-group align-middle" role="group"> <a role="button" class="btn btn-sm btn-warning" href="#" onclick="reboot();">Reboot</a> <a role="button" class="btn btn-sm btn-danger" href="#" onclick="shutdown();">Shutdown</a> </div> </div> </div> <div class="row"> <div class="col"> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_top">+</button><a href="#collapse_top" data-toggle="collapse"><code>top</code></a> <span class="float-right"><small>refreshed every <span id="top_refresh_interval">-</span> seconds</small></span></p> <div class="collapse show" id="collapse_top"> <pre class="pre-scrollable" id="top"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_failed_system">+</button><a href="#collapse_failed_system" data-toggle="collapse"><code>systemctl --system list-units --failed</code></a></p> <div class="collapse show" id="collapse_failed_system"> <pre class="pre-scrollable" id="failed_system"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_overview_system">+</button><a href="#collapse_overview_system" data-toggle="collapse"><code>systemctl --system status</code></a></p> <div class="collapse" id="collapse_overview_system"> <pre class="pre-scrollable" id="overview_system"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_timers_system">+</button><a href="#collapse_timers_system" data-toggle="collapse"><code>systemctl --system list-timers --all</code></a></p> <div class="collapse" id="collapse_timers_system"> <pre class="pre-scrollable" id="timers_system"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_journal_system">+</button><a href="#collapse_journal_system" data-toggle="collapse"><code>journalctl --system -b --lines=20</code></a></p> <div class="collapse" id="collapse_journal_system"> <pre class="pre-scrollable" id="journal_system"></pre> </div> <hr> </div> </div> <div id="users"> </div> </div> <script src="js/jquery-3.3.1.min.js"></script> <script src="js/bootstrap.bundle.min.js"></script> <script> function reboot() { $.get('reboot'); } function shutdown() { $.get('poweroff'); } function set_hostname(data) { $('#hostname').text(data); $('title').text(data); } function set_top(data) { $('#top').text(data); } function refresh_top() { $.get('top', function(data) { set_top(JSON.parse(data)); }); } var top_refresh_interval_seconds = 5; function loop_top() { setInterval(function() { refresh_top(); }, top_refresh_interval_seconds * 1000); $('#top_refresh_interval').text(top_refresh_interval_seconds); } function set_system(data) { if ('failed' in data) { $('#failed_system').text(data['failed']); } if ('overview' in data) { $('#overview_system').text(data['overview']); } if ('timers' in data) { $('#timers_system').text(data['timers']); } if ('journal' in data) { $('#journal_system').text(data['journal']); } } var users = []; function add_user(name) { if (users.includes(name)) { return; } let text = ` <div class="row" id="user_${name}"> <div class="col"> <h2>${name}</h2> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_failed_user_${name}">+</button><a href="#collapse_failed_user_${name}" data-toggle="collapse"><code>systemctl --user list-units --failed</code></a></p> <div class="collapse show" id="collapse_failed_user_${name}"> <pre class="pre-scrollable" id="failed_user_${name}"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_overview_user_${name}">+</button><a href="#collapse_overview_user_${name}" data-toggle="collapse"><code>systemctl --user status</code></a></p> <div class="collapse" id="collapse_overview_user_${name}"> <pre class="pre-scrollable" id="overview_user_${name}"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_timers_user_${name}">+</button><a href="#collapse_timers_user_${name}" data-toggle="collapse"><code>systemctl --user list-timers --all</code></a></p> <div class="collapse" id="collapse_timers_user_${name}"> <pre class="pre-scrollable" id="timers_user_${name}"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_journal_user_${name}">+</button><a href="#collapse_journal_user_${name}" data-toggle="collapse"><code>journalctl --user -b --lines=20</code></a></p> <div class="collapse" id="collapse_journal_user_${name}"> <pre class="pre-scrollable" id="journal_user_${name}"></pre> </div> <hr> </div> </div> `; $('#users').append(text); users.push(name); } function set_user(name, data) { add_user(name); if ('failed' in data) { $('#failed_user_' + name).text(data['failed']); } if ('overview' in data) { $('#overview_user_' + name).text(data['overview']); } if ('timers' in data) { $('#timers_user_' + name).text(data['timers']); } if ('journal' in data) { $('#journal_user_' + name).text(data['journal']); } } function set_users(data) { users.forEach(function(name) { if (!(name in data)) { $('#user_' + name).remove(); let i = users.indexOf(name); if (i > -1) { users.splice(i, 1); } } }); Object.keys(data).forEach(function(name) { set_user(name, data[name]); }); } function refresh_status() { $.get('status', function(data) { data = JSON.parse(data); set_hostname(data['hostname']); set_system(data['system']); set_users(data['user']); }); } var status_refresh_interval_seconds = 30; function loop_status() { setInterval(function() { refresh_status(); }, status_refresh_interval_seconds * 1000); $('#status_refresh_interval').text(status_refresh_interval_seconds); } function main() { refresh_top(); refresh_status(); loop_top(); loop_status(); } $(function() { main(); }); </script> </body> </html>