summaryrefslogtreecommitdiffstats
path: root/modules-available/statistics/pages/list.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/statistics/pages/list.inc.php')
-rw-r--r--modules-available/statistics/pages/list.inc.php134
1 files changed, 102 insertions, 32 deletions
diff --git a/modules-available/statistics/pages/list.inc.php b/modules-available/statistics/pages/list.inc.php
index e9af994a..f08cd71c 100644
--- a/modules-available/statistics/pages/list.inc.php
+++ b/modules-available/statistics/pages/list.inc.php
@@ -22,31 +22,44 @@ class SubPage
}
- /**
- * @param \StatisticsFilterSet $filterSet
- */
- private static function showMachineList($filterSet)
+ private static function showMachineList(StatisticsFilterSet $filterSet): void
{
Module::isAvailable('js_stupidtable');
$filterSet->makeFragments($where, $join, $args);
$xtra = '';
- if ($filterSet->isNoId44Filter()) {
- $xtra .= ', data';
- }
if (Module::isAvailable('runmode')) {
$xtra .= ', runmode.module AS rmmodule, runmode.isclient';
if (strpos($join, 'runmode') === false) {
- $join .= ' LEFT JOIN runmode USING (machineuuid) ';
+ $join .= ' LEFT JOIN runmode ON (m.machineuuid = runmode.machineuuid) ';
}
}
- $res = Database::simpleQuery("SELECT m.machineuuid, m.locationid, m.macaddr, m.clientip, m.lastseen,
+ $allRows = Database::queryAll("SELECT m.machineuuid, m.locationid, m.macaddr, m.clientip, m.lastseen,
m.logintime, m.state, m.currentuser, m.currentrunmode, m.realcores, m.mbram, m.kvmstate, m.cpumodel, m.id44mb,
- m.hostname, m.notes IS NOT NULL AS hasnotes,
+ m.id45mb, m.hostname, m.notes IS NOT NULL AS hasnotes,
m.badsectors, Count(s.machineuuid) AS confvars $xtra FROM machine m
- LEFT JOIN setting_machine s USING (machineuuid)
+ LEFT JOIN setting_machine s ON (m.machineuuid = s.machineuuid)
$join WHERE $where GROUP BY m.machineuuid", $args);
- $rows = array();
- $singleMachine = 'none';
+ // If filter results in just one result, redirect to machine details
+ if (count($allRows) === 1) {
+ Util::redirect('?do=statistics&uuid=' . $allRows[0]['machineuuid']);
+ }
+ // Gather additional info that would be ugly to fetch via joins above
+ $uuids = array_column($allRows, 'machineuuid');
+ $machineWithHdds = Database::queryKeyValueList("SELECT mxx.machineuuid, Count(s.hwid) AS num
+ FROM statistic_hw s
+ INNER JOIN machine_x_hw AS mxx ON (s.hwid = mxx.hwid AND s.hwtype = :type
+ AND mxx.disconnecttime = 0 AND mxx.machineuuid IN (:ids))
+ GROUP BY mxx.machineuuid",
+ ['type' => HardwareInfo::HDD, 'ids' => $uuids]);
+ $machineNicSpeed = Database::queryKeyValueList("SELECT mxx.machineuuid, Max(mxhp.`numeric`) AS num
+ FROM statistic_hw s
+ INNER JOIN machine_x_hw AS mxx ON (s.hwid = mxx.hwid AND s.hwtype = :type
+ AND mxx.disconnecttime = 0 AND mxx.machineuuid IN (:ids))
+ INNER JOIN machine_x_hw_prop mxhp ON (mxx.machinehwid = mxhp.machinehwid AND mxhp.prop = :prop)
+ GROUP BY mxx.machineuuid",
+ ['type' => HardwareInfo::MAINBOARD, 'prop' => 'nic-speed', 'ids' => $uuids]);
+ $machineWithConfigOverrides = Database::queryKeyValueList("SELECT machineuuid, Count(machineuuid) AS num
+ FROM setting_machine WHERE machineuuid IN (:ids) GROUP BY machineuuid", ['ids' => $uuids]);
// TODO: Cannot disable checkbox for those where user has no permission, since we got multiple actions now
// We should pass these lists to the output and add some JS magic
// Either disable the delete/reboot/... buttons as soon as at least one "forbidden" client is selected (potentially annoying)
@@ -56,38 +69,54 @@ class SubPage
$shutdownAllowedLocations = User::getAllowedLocations('.rebootcontrol.action.reboot');
$wolAllowedLocations = User::getAllowedLocations('.rebootcontrol.action.wol');
$execAllowedLocations = User::getAllowedLocations('.rebootcontrol.action.exec');
+ $benchmarkAllowedLocations = User::getAllowedLocations('.vmstore.benchmark');
// Only make client clickable if user is allowed to view details page
$detailsAllowedLocations = User::getAllowedLocations("machine.view-details");
$location = self::buildLocationLookup();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if ($singleMachine === 'none') {
- $singleMachine = $row['machineuuid'];
- } else {
- $singleMachine = false;
- }
+ $rows = [];
+ $colValCount = []; // Count unique values for several columns
+ foreach ($allRows as &$row) {
+ settype($row['locationid'], 'int');
$row['link_details'] = in_array($row['locationid'], $detailsAllowedLocations);
//$row['firstseen'] = Util::prettyTime($row['firstseen']);
$row['lastseen_int'] = $row['lastseen'];
$row['lastseen'] = Util::prettyTime($row['lastseen']);
//$row['lastboot'] = Util::prettyTime($row['lastboot']);
- $row['gbram'] = round(ceil($row['mbram'] / 512) / 2, 1); // Trial and error until we got "expected" rounding..
- $row['gbtmp'] = round($row['id44mb'] / 1024);
+ $row['gbram'] = Dictionary::number(ceil($row['mbram'] / 512) / 2, 1); // Trial and error until we got "expected" rounding..
+ $row['gbtmp'] = Dictionary::number($row['id44mb'] / 1024);
+ $row['gbpersist'] = Dictionary::number($row['id45mb'] / 1024);
$octets = explode('.', $row['clientip']);
if (count($octets) === 4) {
$row['subnet'] = "$octets[0].$octets[1].$octets[2]";
$row['lastoctet'] = $octets[3];
}
- $row['ramclass'] = StatisticsStyling::ramColorClass($row['mbram']);
+ $row['ramclass'] = StatisticsStyling::ramColorClass((int)$row['mbram']);
$row['kvmclass'] = StatisticsStyling::kvmColorClass($row['kvmstate']);
- $row['hddclass'] = StatisticsStyling::hddColorClass($row['gbtmp']);
+ $row['hddclass'] = StatisticsStyling::hddColorClass((int)$row['gbtmp']);
if (empty($row['hostname'])) {
$row['hostname'] = $row['clientip'];
}
- if (isset($row['data'])) {
- if (!preg_match('#^Disk.* /dev/[^d].* (bytes$|sectors,)#m', $row['data'])) {
- $row['nohdd'] = true;
- }
+ if (isset($machineWithConfigOverrides[$row['machineuuid']])) {
+ $row['confvars'] = $machineWithConfigOverrides[$row['machineuuid']];
+ }
+ if (isset($machineWithHdds[$row['machineuuid']])) {
+ $row['hddcount'] = $machineWithHdds[$row['machineuuid']];
+ } else if ($row['id44mb'] > 0) {
+ // This might be a machine that wasn't booted with a recent system, and hence doesn't have HWinfo in DB
+ // If we have ID44 space in our main table, we most likely got an HDD, so fake a count of 1
+ $row['hddcount'] = 1;
+ }
+ if (!isset($machineNicSpeed[$row['machineuuid']])) {
+ $row['nic-speed'] = 0;
+ $row['nic-speed_s'] = '???';
+ } else {
+ $row['nic-speed'] = $machineNicSpeed[$row['machineuuid']];
+ $row['nic-speed_s'] = Dictionary::number($machineNicSpeed[$row['machineuuid']]);
}
+ if (isset($row['data']) && !$row['data']) {
+ $row['nohdd'] = true;
+ }
+ // Shorten CPU names a bit for prettier display in small column
$row['cpumodel'] = preg_replace('/\(R\)|\(TM\)|\bintel\b|\bamd\b|\bcpu\b|dual-core|\bdual\s+core\b|\bdual\b|\bprocessor\b/i', ' ', $row['cpumodel']);
if (!empty($row['rmmodule'])) {
$data = RunMode::getRunMode($row['machineuuid'], RunMode::DATA_STRINGS);
@@ -116,10 +145,48 @@ class SubPage
if ($row['locationid'] > 0) {
$row['location'] = $location[$row['locationid']];
}
- $rows[] = $row;
+ foreach (['locationid', 'cpumodel', 'nic-speed_s', 'gbram', 'gbtmp'] as $key) {
+ if (!isset($colValCount[$key][$row[$key]])) {
+ $colValCount[$key][$row[$key]] = [];
+ }
+ $colValCount[$key][$row[$key]][] = $row['machineuuid'];
+ }
+ $rows[] =& $row;
}
- if ($singleMachine !== false && $singleMachine !== 'none') {
- Util::redirect('?do=statistics&uuid=' . $singleMachine);
+ // Now if all machines are from the same location, try to load the roomplan
+ // Also, collect all properties that are the same across all machines for display in the sidebar
+ $roomsvg = null;
+ $side = [];
+ if (!empty($rows) && !empty($colValCount)) {
+ if (count($colValCount['locationid']) === 1
+ && ($lid = array_key_first($colValCount['locationid'])) > 0
+ && Module::isAvailable('roomplanner')) {
+ $roomsvg = PvsGenerator::generateSvg($lid, false, 0, 1, true, $colValCount['locationid'][$lid]);
+ }
+ // Handle our selected attributes
+ foreach (['locationid', 'cpumodel', 'nic-speed_s', 'gbram', 'gbtmp'] as $key) {
+ if (count($colValCount[$key]) === 1) {
+ $val = array_key_first($colValCount[$key]);
+ // Suffixes are not localized, but hopefully generic enough for now
+ switch ($key) {
+ case 'locationid':
+ if (!isset($location[$val]))
+ continue 2;
+ $val = $location[$val]['name'];
+ break;
+ case 'gbram':
+ $val .= ' GiB RAM';
+ break;
+ case 'gbtmp':
+ $val .= ' GiB ID-44';
+ break;
+ case 'nic-speed_s':
+ $val .= ' MBit/s';
+ break;
+ }
+ $side[] = $val;
+ }
+ }
}
$data = array(
'rowCount' => count($rows),
@@ -133,11 +200,14 @@ class SubPage
'canDelete' => !empty($deleteAllowedLocations),
'canWol' => !empty($wolAllowedLocations),
'canExec' => !empty($execAllowedLocations),
+ 'canBenchmark' => !empty($benchmarkAllowedLocations),
+ 'roomsvg' => $roomsvg,
+ 'sidebar' => $side,
);
Render::addTemplate('clientlist', $data);
}
- private static function buildLocationLookup()
+ private static function buildLocationLookup(): array
{
$ret = [];
$i = 0;
@@ -147,4 +217,4 @@ class SubPage
return $ret;
}
-}
+} \ No newline at end of file