aboutsummaryrefslogblamecommitdiffstatshomepage
path: root/index.html
blob: e12adeb4d86ef09cedaa0928f4c2b7d5256f74fd (plain) (tree)
1
2
3
4
5
6
7
8




                                                                                          
                    
                                                        
           


                      
         

                     
            

         
                           
                       
                         
                                  
                                                                                                                             









                                                                                                      
              
                                                                                                                                                                                                                                                                                                                                             

                                                       

                


                                                                                                                                                                                                                                                                                   

                


                                                                                                                                                                                                                                                                          

                
                                                                                                                                                                                                                                                                                 

                                                                 

                




                                                                                                                                                                                                                                                                                

              

                      
          

                                                      
            








                                                                             
                   
                  


                     
                    

 


                              

 

                         

 
                        
                               
                                  


       






                                                                                    









                                                     


                                                   



               













                                                                
                                                            






                                                                          



                               










                                                                                              













                                                           


                                                         


                          








                                        





                                              
                                  
                                





                                       
                                         
 
                        
                            

                                               
                                                                        


                 
                  
                     

                  







              
<!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 dump_fail(data) {
    console.log('Response code was: ' + data.status + ' ' + data.statusText);
    console.log('Response was:\n' + data.responseText);
}

function get(url, success_callback) {
    $.get(url, success_callback).fail(dump_fail);
}

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>