cluster health info page

Fixes: https://pagure.io/koji/issue/1550
This commit is contained in:
Tomas Kopecek 2019-07-16 15:00:29 +02:00
parent d097af40f9
commit 59d196c51e
3 changed files with 139 additions and 0 deletions

View file

@ -0,0 +1,82 @@
#from kojiweb import util
#def printOption(value, label=None)
#if not $label
#set $label = $value
#end if
<option value="$value"#if $value == $arch then ' selected="selected"' else ''#>$label</option>
#end def
#include "includes/header.chtml"
<style>
span {
display: inline-block;
box-sizing: border-box;
height: 100%;
float: left;
padding: 0px;
text-overflow: ellipsis;
}
.graph {
height: 15px;
}
.free {
background: #00ff00;
text-align: right;
}
.busy {
background: #ff0000;
}
.count {
background: #0000ff;
color: #ffffff;
}
</style>
<h4>Cluster health</h4>
<table class="data-list">
<tr style="text-align: left">
<td colspan="3">
<form action="">
Architecture:
<select onchange="javascript: window.location = 'clusterhealth?arch=' + this.value + '$util.passthrough($self, 'order')';">
$printOption('__all__', 'all')
#for $arch in $arches
$printOption($arch)
#end for
</select>
</form>
</td>
</tr>
<tr class="list-header">
<th>Channel</th>
<th>Load/Capacity</th>
<th>Builder readiness</th>
</tr>
#for $channel in $channels
<tr>
<th>
<a href="channelinfo?channelID=$channel['id']">$channel['name']</a>
</th>
<td width="$graphWidth" class="graph">
#if $channel['capacityPerc']
<span style="width: $channel['capacityPerc']%">
<span style="width: #echo $channel['perc_load']#%" class="busy" title="Load: #echo int($channel['load'])#"></span>
<span style="width: #echo 100 - $channel['perc_load']#%" class="free" title="Free capacity: #echo int($channel['capacity'] - $channel['load'])#">#echo int(100 - $channel['perc_load'])#%&nbsp;</span>
</span>
#end if
</td>
<td width="$graphWidth" class="graph">
<span style="width: #echo $channel['enabledPerc']#%">
<span style="width: #echo 100 - $channel['perc_ready']#%" class="busy" title="Busy builders: #echo $channel['enabled'] - $channel['ready']#"></span>
<span style="width: #echo $channel['perc_ready']#%" class="free" title="Ready builders: $channel['ready']"">#echo int($channel['ready'])#&nbsp;</span>
</span>
</td>
</tr>
#end for
</table>
#include "includes/footer.chtml"

View file

@ -2135,6 +2135,62 @@ def buildsbytarget(environ, days='7', start=None, order='-builds'):
return _genHTML(environ, 'buildsbytarget.chtml')
def _filter_hosts_by_arch(hosts, arch):
if arch == '__all__':
return hosts
else:
return [h for h in hosts if arch in h['arches'].split()]
def clusterhealth(environ, arch='__all__'):
values = _initValues(environ, 'Cluster health', 'reports')
server = _getServer(environ)
channels = server.listChannels()
server.multicall = True
for channel in channels:
server.listHosts(channelID=channel['id'])
max_enabled = 0
max_capacity = 0
arches = set()
for channel, [hosts] in zip(channels, server.multiCall()):
for host in hosts:
arches |= set(host['arches'].split())
hosts = _filter_hosts_by_arch(hosts, arch)
channel['enabled'] = len([x for x in hosts if x['enabled']])
channel['disabled'] = len(hosts) - channel['enabled']
channel['ready'] = len([x for x in hosts if x['ready']])
channel['capacity'] = sum([x['capacity'] for x in hosts])
channel['load'] = sum([x['task_load'] for x in hosts])
if max_enabled < channel['enabled']:
max_enabled = channel['enabled']
if max_capacity < channel['capacity']:
max_capacity = channel['capacity']
graphWidth = 400.0
# compute values for channels
for channel in channels:
try:
channel['capacityPerc'] = channel['capacity'] / max_capacity * 100
except ZeroDivisionError:
channel['capacityPerc'] = 0
try:
channel['enabledPerc'] = channel['enabled'] / max_enabled * 100
except ZeroDivisionError:
channel['enabledPerc'] = 0
if channel['capacity']:
channel['perc_load'] = min(100, channel['load'] / channel['capacity'] * 100)
else:
channel['perc_load'] = 0.0
if channel['enabled']:
channel['perc_ready'] = min(100, channel['ready'] / channel['enabled'] * 100)
else:
channel['perc_ready'] = 0.0
values['arch'] = arch
values['arches'] = sorted(arches)
values['graphWidth'] = graphWidth
values['channels'] = sorted(channels, key=lambda x: x['name'])
return _genHTML(environ, 'clusterhealth.chtml')
def recentbuilds(environ, user=None, tag=None, package=None):
values = _initValues(environ, 'Recent Build RSS')
server = _getServer(environ)

View file

@ -12,6 +12,7 @@
<li><a href="tasksbyhost">Tasks completed by each host</a></li>
<li><a href="buildsbystatus">Succeeded/failed/canceled builds</a></li>
<li><a href="buildsbytarget">Number of builds in each target</a></li>
<li><a href="clusterhealth">Cluster health</a></li>
</ul>
#include "includes/footer.chtml"