diff options
9 files changed, 152 insertions, 4 deletions
diff --git a/config.php.example b/config.php.example index 7bf3ad8b..0de6fd8d 100644 --- a/config.php.example +++ b/config.php.example @@ -32,6 +32,8 @@ define('CONFIG_DOZMOD_EXPIRE', 60); define('CONFIG_REPORTING_URL', 'https://bwlp-masterserver.ruf.uni-freiburg.de/rpc/'); +define('CONFIG_BIOS_URL', 'https://bwlp-masterserver.ruf.uni-freiburg.de/bios/list.json'); + define('CONFIG_PRODUCT_NAME', 'OpenSLX'); define('CONFIG_PRODUCT_NAME_LONG', 'OpenSLX Admin'); diff --git a/modules-available/statistics/inc/parser.inc.php b/modules-available/statistics/inc/parser.inc.php index 8ac3fcf3..121a2817 100644 --- a/modules-available/statistics/inc/parser.inc.php +++ b/modules-available/statistics/inc/parser.inc.php @@ -87,6 +87,14 @@ class Parser { if (preg_match('/^\s*Configured Clock Speed:\s*(\d.*?)\s*$/i', $line, $out)) { $ramClockSpeed = $out[1]; } + } elseif ($section === 'BIOS Information') { + if (preg_match(',^\s*Release Date:\s*(\d{2}/\d{2}/\d{4})\s*$,i', $line, $out)) { + $row['biosdate'] = date('d.m.Y', strtotime($out[1])); + } elseif (preg_match('/^\s*BIOS Revision:\s*(.*?)\s*$/i', $line, $out)) { + $row['biosrevision'] = $out[1]; + } elseif (preg_match('/^\s*Version:\s*(.*?)\s*$/i', $line, $out)) { + $row['biosversion'] = $out[1]; + } } } if (empty($row['ramslotcount'])) { diff --git a/modules-available/statistics/lang/de/permissions.json b/modules-available/statistics/lang/de/permissions.json index 8579b28f..cd1e7a4e 100644 --- a/modules-available/statistics/lang/de/permissions.json +++ b/modules-available/statistics/lang/de/permissions.json @@ -2,11 +2,9 @@ "hardware.projectors.edit": "Beamerzuweisung bearbeiten", "hardware.projectors.view": "Beamerzuweisung anzeigen", "machine.delete": "Rechner l\u00f6schen.", - "machine.note": "Anmerkungen zu einem Rechner speichern.", "machine.note.edit": "Anmerkungen bearbeiten", "machine.note.view": "Anmerkungen anzeigen", "machine.view-details": "Clientinformationen anzeigen", - "view": "Statistiken anschauen.", "view.list": "Clientliste anzeigen", "view.summary": "Visualisierung anzeigen" }
\ No newline at end of file diff --git a/modules-available/statistics/lang/de/template-tags.json b/modules-available/statistics/lang/de/template-tags.json index c0d646e7..8eb367e8 100644 --- a/modules-available/statistics/lang/de/template-tags.json +++ b/modules-available/statistics/lang/de/template-tags.json @@ -3,6 +3,11 @@ "lang_add": "Hinzuf\u00fcgen", "lang_add_filter": "Filter hinzuf\u00fcgen", "lang_address": "Adresse", + "lang_biosDate": "Ver\u00f6ffentlichungsdatum", + "lang_biosFixes": "BIOS-Fehlerkorrekturen", + "lang_biosUpdate": "BIOS Update", + "lang_biosUpdateLink": "Zur Herstellerseite", + "lang_biosVersion": "BIOS-Version", "lang_clientList": "Liste ausgew\u00e4hlter Rechner", "lang_cores": "Kerne", "lang_cpuCores": "CPU-Kerne", diff --git a/modules-available/statistics/lang/en/permissions.json b/modules-available/statistics/lang/en/permissions.json index 445f96b8..373fcf07 100644 --- a/modules-available/statistics/lang/en/permissions.json +++ b/modules-available/statistics/lang/en/permissions.json @@ -2,11 +2,9 @@ "hardware.projectors.edit": "Edit beamer assignment", "hardware.projectors.view": "Show beamer assignment", "machine.delete": "Delete clients.", - "machine.note": "Save client notes.", "machine.note.edit": "Edit notes", "machine.note.view": "Show notes", "machine.view-details": "Show client details", - "view": "View statistics.", "view.list": "Show client list", "view.summary": "Show visualization" }
\ No newline at end of file diff --git a/modules-available/statistics/lang/en/template-tags.json b/modules-available/statistics/lang/en/template-tags.json index 044c8df5..ea74ce52 100644 --- a/modules-available/statistics/lang/en/template-tags.json +++ b/modules-available/statistics/lang/en/template-tags.json @@ -3,6 +3,11 @@ "lang_add": "Add", "lang_add_filter": "Add Filter", "lang_address": "Address", + "lang_biosDate": "Release date", + "lang_biosFixes": "BIOS fixes", + "lang_biosUpdate": "BIOS update", + "lang_biosUpdateLink": "Go to vendor's site", + "lang_biosVersion": "BIOS version", "lang_clientList": "List of selected machines", "lang_cores": "Cores", "lang_cpuCores": "CPU cores", diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index d1749187..302aea29 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -890,6 +890,21 @@ class Page_Statistics extends Page } } unset($client['data']); + // BIOS update check + if (!empty($client['biosrevision'])) { + $model = $client['manufacturer'] . '##' . $client['pcmodel']; + $ret = $this->checkBios($model, $client['biosdate'], $client['biosrevision']); + if ($ret === false) { // Not loaded, use AJAX + $params = [ + 'model' => $model, + 'date' => $client['biosdate'], + 'revision' => $client['biosrevision'], + ]; + $client['biosurl'] = '?do=statistics&action=bios&' . http_build_query($params); + } elseif (!isset($ret['status']) || $ret['status'] !== 0) { + $client['bioshtml'] = Render::parse('machine-bios-update', $ret); + } + } // Get locations if (Module::isAvailable('locations')) { $locs = Location::getLocationsAssoc(); @@ -1082,6 +1097,11 @@ class Page_Statistics extends Page { if (!User::load()) return; + if (Request::any('action') === 'bios') { + $this->ajaxCheckBios(); + return; + } + $param = Request::any('lookup', false, 'string'); if ($param === false) { die('No lookup given'); @@ -1144,6 +1164,76 @@ class Page_Statistics extends Page 'timeout' => time() + mt_rand(10, 30) * 86400, ), true); } + + const BIOS_CACHE = '/tmp/bwlp-bios.json'; + + private function ajaxCheckBios() + { + $model = Request::any('model', false, 'string'); + $date = Request::any('date', false, 'string'); + $revision = Request::any('revision', false, 'string'); + $reply = $this->checkBios($model, $date, $revision); + if ($reply === false) { + $data = Download::asString(CONFIG_BIOS_URL, 3, $err); + if ($err < 200 || $err >= 300) { + $reply = ['error' => 'HTTP: ' . $err]; + } else { + file_put_contents(self::BIOS_CACHE, $data); + $data = json_decode($data, true); + $reply = $this->checkBios($model, $date, $revision, $data); + } + } + if ($reply === false) { + $reply = ['error' => 'Internal Error']; + } + if (isset($reply['status']) && $reply['status'] === 0) + exit; // Show nothing, 0 means OK + die(Render::parse('machine-bios-update', $reply)); + } + + private function checkBios($model, $date, $revision, $json = null) + { + if ($json === null) { + if (!file_exists(self::BIOS_CACHE) || filemtime(self::BIOS_CACHE) + 3600 < time()) + return false; + $json = json_decode(file_get_contents(self::BIOS_CACHE), true); + } + if (!is_array($json) || !isset($json['system'])) + return ['error' => 'Malformed JSON, no system key']; + if (!isset($json['system'][$model]) || !isset($json['system'][$model]['fixes']) || !isset($json['system'][$model]['match'])) + return ['status' => 0]; + $m = $json['system'][$model]['match']; + if ($m === 'revision') { + $cmp = function ($item) { $s = explode('.', $item); return $s[0] * 0x10000 + $s[1]; }; + $reference = $cmp($revision); + } elseif ($m === 'date') { + $cmp = function ($item) { $s = explode('.', $item); return $s[2] * 10000 + $s[1] * 100 + $s[0]; }; + $reference = $cmp($date); + } else { + return ['error' => 'Invalid comparison key: ' . $m]; + } + $retval = ['fixes' => []]; + $level = 0; + foreach ($json['system'][$model]['fixes'] as $fix) { + if ($cmp($fix[$m]) > $reference) { + class_exists('Dictionary'); // Trigger setup of lang stuff + $lang = isset($fix['text'][LANG]) ? LANG : 'en'; + $fix['text'] = $fix['text'][$lang]; + $retval['fixes'][] = $fix; + $level = max($level, $fix['level']); + } + } + $retval['url'] = $json['system'][$model]['url']; + $retval['status'] = $level; + if ($level > 5) { + $retval['class'] = 'danger'; + } elseif ($level > 3) { + $retval['class'] = 'warning'; + } else { + $retval['class'] = 'info'; + } + return $retval; + } } Page_Statistics::initConstants(); diff --git a/modules-available/statistics/templates/machine-bios-update.html b/modules-available/statistics/templates/machine-bios-update.html new file mode 100644 index 00000000..2e8a8908 --- /dev/null +++ b/modules-available/statistics/templates/machine-bios-update.html @@ -0,0 +1,26 @@ +<div><span class="btn btn-{{class}} btn-sm" data-toggle="modal" data-target="#bios-modal"> + {{lang_biosUpdate}} » +</span></div> + +<div class="modal fade" id="bios-modal" tabindex="-1" role="dialog" aria-labelledby="bios-modal-label" aria-hidden="true"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span + class="sr-only">Close</span></button> + <h4 class="modal-title" id="bios-modal-label">{{lang_biosFixes}}</h4> + </div> + <div class="modal-body"> + {{#fixes}} + <p><b>{{date}}{{revision}}</b>: {{text}}</p> + {{/fixes}} + <p> + <a href="{{url}}" target="_blank">{{lang_biosUpdateLink}}</a> + </p> + </div> + <div class="modal-footer text-right"> + <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_close}}</button> + </div> + </div> + </div> +</div>
\ No newline at end of file diff --git a/modules-available/statistics/templates/machine-main.html b/modules-available/statistics/templates/machine-main.html index 8156f0aa..e040a6c5 100644 --- a/modules-available/statistics/templates/machine-main.html +++ b/modules-available/statistics/templates/machine-main.html @@ -127,6 +127,19 @@ <td class="text-nowrap">{{lang_model}}</td> <td>{{pcmodel}} ({{manufacturer}})</td> </tr> + {{#biosdate}} + <tr> + <td class="text-nowrap"> + <div>{{lang_biosVersion}}</div> + <div>{{lang_biosDate}}</div> + </td> + <td> + <div id="bios-panel" class="pull-right">{{{bioshtml}}}</div> + <div>{{biosversion}} (<b>{{biosrevision}}</b>)</div> + <div>{{biosdate}}</div> + </td> + </tr> + {{/biosdate}} <tr class="{{ramclass}}"> <td class="text-nowrap">{{lang_ram}}</td> <td> @@ -242,5 +255,8 @@ document.addEventListener("DOMContentLoaded", function () { $('span.do-lookup').each(function () { $(this).load('?do=statistics&lookup=' + $(this).text()); }); + {{#biosurl}} + $('#bios-panel').load('{{{biosurl}}}'); + {{/biosurl}} }, false); // --></script> |