diff options
Diffstat (limited to 'modules-available/statistics/pages/machine.inc.php')
-rw-r--r-- | modules-available/statistics/pages/machine.inc.php | 183 |
1 files changed, 165 insertions, 18 deletions
diff --git a/modules-available/statistics/pages/machine.inc.php b/modules-available/statistics/pages/machine.inc.php index e1133338..fdb04023 100644 --- a/modules-available/statistics/pages/machine.inc.php +++ b/modules-available/statistics/pages/machine.inc.php @@ -54,13 +54,31 @@ class SubPage $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot, state, mbram, live_tmpsize, live_tmpfree, live_id45size, live_id45free, live_swapsize, live_swapfree, live_memsize, live_memfree, live_cpuload, live_cputemp, - Length(position) AS hasroomplan, kvmstate, cpumodel, id44mb, data, hostname, currentuser, currentsession, notes + Length(position) AS hasroomplan, kvmstate, cpumodel, id44mb, id45mb, data, hostname, currentuser, currentsession, notes FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid)); if ($client === false) { Message::addError('unknown-machine', $uuid); return; } + // Parse data + $hdds = array(); + if ($client['data'][0] === '{') { + $json = json_decode($client['data'], true); + if (is_array($json)) { + $client += self::parseJson($uuid, $json); + $hdds['hdds'] = self::parseJsonHdd($uuid); + } + } else { + self::parseLegacy($client, $hdds); + } + unset($client['data']); + // Get rid of configured speed, if equal to maximum speed + foreach ($client['ram'] as &$ram) { + if (isset($ram['Configured Memory Speed']) && $ram['Configured Memory Speed'] === $ram['Speed']) { + unset($ram['Configured Memory Speed']); + } + } if (Module::isAvailable('locations') && !Location::isLeaf($client['locationid'])) { $client['hasroomplan'] = false; } @@ -121,6 +139,7 @@ class SubPage } $client['gbram'] = round(ceil($client['mbram'] / 512) / 2, 1); $client['gbtmp'] = round($client['id44mb'] / 1024); + $client['gbid45'] = round($client['id45mb'] / 1024); foreach (['tmp', 'id45', 'swap', 'mem'] as $item) { if ($client['live_' . $item . 'size'] == 0) continue; @@ -135,28 +154,25 @@ class SubPage $client['ramclass'] = StatisticsStyling::ramColorClass($client['mbram']); $client['kvmclass'] = StatisticsStyling::kvmColorClass($client['kvmstate']); $client['hddclass'] = StatisticsStyling::hddColorClass($client['gbtmp']); - // - $hdds = array(); - if ($client['data'][0] === '{') { - $json = json_decode($client['data'], true); - if (is_array($json)) { - $client += self::parseJson($uuid, $json); - } - } else { - self::parseLegacy($client, $hdds); + // Format HDD data to strings + foreach ($hdds['hdds'] as &$hdd) { + $hdd['smart_status_failed'] = !($client['smart_status//passed'] ?? 1); + self::mangleHdd($hdd); } - unset($client['data']); // BIOS update check - if (!empty($client['biosrevision'])) { - $mainboard = $client['mobomanufacturer'] . '##' . $client['mobomodel']; - $system = $client['pcmanufacturer'] . '##' . $client['pcmodel']; - $ret = self::checkBios($mainboard, $system, $client['biosdate'], $client['biosrevision']); + if (!empty($client['bios']['BIOS Revision']) || !empty($client['bios']['Release Date'])) { + if (preg_match('#^(\d{1,2})/(\d{1,2})/(\d{4})#', $client['bios']['Release Date'], $out)) { + $client['bios']['Release Date'] = $out[2] . '.' . $out[1] . '.' . $out[3]; + } + $mainboard = $client['mainboard']['Manufacturer'] . '##' . $client['mainboard']['Product Name']; + $system = $client['system']['Manufacturer'] . '##' . $client['system']['Product Name']; + $ret = self::checkBios($mainboard, $system, $client['bios']['Release Date'], $client['bios']['BIOS Revision']); if ($ret === false) { // Not loaded, use AJAX $params = [ 'mainboard' => $mainboard, 'system' => $system, - 'date' => $client['biosdate'], - 'revision' => $client['biosrevision'], + 'date' => $client['bios']['Release Date'], + 'revision' => $client['bios']['BIOS Revision'], ]; $client['biosurl'] = '?do=statistics&action=bios&' . http_build_query($params); } elseif (!isset($ret['status']) || $ret['status'] !== 0) { @@ -391,7 +407,120 @@ class SubPage return $return; } - private static function eventToIconName($event) + private static function parseJsonHdd(string $uuid): array + { + $hdds = []; + $ret = Database::simpleQuery("SELECT mp.`machinehwid`, mp.`prop`, mp.`value`, mp.`numeric` + FROM machine_x_hw_prop mp + INNER JOIN machine_x_hw mxhw ON (mp.machinehwid = mxhw.machinehwid AND mxhw.machineuuid = :uuid AND mxhw.disconnecttime = 0) + INNER JOIN statistic_hw sh ON (mxhw.hwid = sh.hwid AND sh.hwtype = :type) + UNION SELECT mxhw.`machinehwid`, hwp.`prop`, hwp.`value`, hwp.`numeric` + FROM statistic_hw_prop hwp + INNER JOIN machine_x_hw mxhw ON (hwp.hwid = mxhw.hwid AND mxhw.machineuuid = :uuid AND mxhw.disconnecttime = 0) + INNER JOIN statistic_hw sh ON (mxhw.hwid = sh.hwid AND sh.hwtype = :type) + ", + ['type' => HardwareInfo::HDD, 'uuid' => $uuid]); + foreach ($ret as $row) { + if (!isset($hdds[$row['machinehwid']])) { + $hdds[$row['machinehwid']] = ['partitions' => []]; + } + $hdd =& $hdds[$row['machinehwid']]; + if (preg_match('/^(attr_[0-9]+)_(.*)$/', $row['prop'], $out)) { + // SMART attributes + if (!isset($hdd[$out[1]])) { + $hdd[$out[1]] = []; + } + $hdd[$out[1]][$out[2]] = $row['numeric'] ?? $row['value']; + } elseif (preg_match('/^part_([0-9]+)_(.*)$/', $row['prop'], $out)) { + // Partitions + if (!isset($hdd['partitions'][$out[1]])) { + $hdd['partitions'][$out[1]] = ['id' => 'dev-' . count($hdds) . '-' . $out[1], 'index' => $out[1] + 1]; + } + $hdd['partitions'][$out[1]][$out[2]] = $row['numeric'] ?? $row['value']; + } else { + $hdd[$row['prop']] = $row['numeric'] ?? $row['value']; + } + } + foreach ($hdds as $k => &$hdd) { + $hdd['devid'] = 'k' . $k; + $hdd['partitions'] = array_values($hdd['partitions']); + } + return array_values($hdds); + } + + private static function mangleHdd(array &$hdd) + { + $hours = $hdd['power_on_time//hours'] ?? $hdd['attr_9']['raw'] ?? $hdd['power_on_hours'] + ?? $hdd['power_on_time']['hours'] ?? null; + if ($hours !== null) { + $hdd['PowerOnTime'] = ''; + $val = (int)str_replace('.', '', $hours); + if ($val > 8760) { + $hdd['PowerOnTime'] .= floor($val / 8760) . 'Y, '; + $val %= 8760; + } + if ($val > 720) { + $hdd['PowerOnTime'] .= floor($val / 720) . 'M, '; + $val %= 720; + } + if ($val > 24) { + $hdd['PowerOnTime'] .= floor($val / 24) . 'd, '; + $val %= 24; + } + $hdd['PowerOnTime'] .= $val . 'h'; + } + // Sort by start for building pie-chart + $xx = array_column($hdd['partitions'], 'start'); + array_multisort($xx, SORT_ASC, SORT_NUMERIC, + $hdd['partitions']); + $used = 0; + $json = []; + $lastEnd = 0; + $minDisplaySize = $hdd['size'] / 150; + foreach ($hdd['partitions'] as &$part) { + $dist = $part['start'] - $lastEnd; + if ($dist > $minDisplaySize) { + error_log('Dist: ' . Util::readableFileSize($dist)); + $json[] = ['value' => $dist, 'color' => '#aaa']; + } + if ($part['size'] > $minDisplaySize) { + $json[] = ['value' => $part['size'], 'color' => self::typeToColor($part), 'label' => $part['id']]; + } + $part['size_s'] = Util::readableFileSize($part['size']); + $used += $part['size']; + $lastEnd = $part['start'] + $part['size']; + if (!isset($part['name'])) { + $part['name'] = self::mbrType($part['slxtype'] ?? $part['type']); + } + } + $dist = $hdd['size'] - $lastEnd; + if ($dist > $minDisplaySize) { + $json[] = ['value' => $dist, 'color' => '#aaa']; + } + $hdd['json'] = json_encode($json); + $hdd['size_s'] = Util::readableFileSize($hdd['size']); + if ($hdd['size'] - $used > 1000000000) { + $hdd['unused_s'] = Util::readableFileSize($hdd['size'] - $used); + } + // Finally sort by index for table display + array_multisort(array_column($hdd['partitions'], 'index'), SORT_ASC, + $hdd['partitions']); + } + + private static function typeToColor(array $part): string + { + switch ($part['slxtype'] ?? $part['type']) { + case 44: + return '#5c1'; + case 45: + return '#0d7'; + case 82: + return '#48f'; + } + return '#e55'; + } + + private static function eventToIconName($event): string { switch ($event) { case 'session-open': @@ -484,4 +613,22 @@ class SubPage return $retval; } + private static function mbrType(string $type): string + { + switch ($type) { + case '44': + case '45': + return 'OpenSLX-ID' . $type; + case '82': + return 'Linux Swap'; + case '83': + return 'Linux'; + case '7': + return 'NTFS/Windows'; + case 'ef': + return 'EFI'; + } + return $type; + } + }
\ No newline at end of file |