<!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 create_user_block(name, lbl, cmd) {
let pre_id = `${lbl}_user_${name}`;
let collapse_id = `collapse_${pre_id}`;
let button_params = {
'class': 'btn btn-outline-primary btn-sm button-expand',
'data-toggle': 'collapse',
'data-target': '#' + collapse_id
};
let a_params = {
href: '#' + collapse_id,
'data-toggle': 'collapse'
};
return $('<div/>')
.append($('<p/>')
.append($('<button/>', button_params).text('+'))
.append($('<a/>', a_params)
.append($('<code/>').text(cmd))))
.append($('<div/>', {'class': 'collapse', id: collapse_id})
.append($('<pre/>', {'class': 'pre-scrollable', id: pre_id})))
.append($('<hr/>'));
}
function add_user(name) {
if (users.includes(name)) {
return;
}
let container = $('<div/>', {'class': 'row', id: 'user_' + name})
.append($('<div/>', {'class': 'col'})
.append($('<h2/>').text(name))
.append($('<hr/>'))
.append(create_user_block(name, 'failed', 'systemctl --user list-units --failed'))
.append(create_user_block(name, 'overview', 'systemctl --user status'))
.append(create_user_block(name, 'timers', 'systemctl --user list-timers --all'))
.append(create_user_block(name, 'journal', 'journalctl --user -b --lines=20')));
$('#users').append(container);
$('#collapse_failed_user_' + name).addClass('show');
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>