summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-03-19 13:52:44 +0100
committerSimon Rettberg2019-03-19 13:52:44 +0100
commitcbb3d0f368347993b61fde2a49eecd66c2e56813 (patch)
tree42dd2b9e195ca588f25e79caa1b9639ad83bbb6d
parent[roomplanner] Implement (auto)rotating SVG, make SVG pretty (diff)
downloadslx-admin-cbb3d0f368347993b61fde2a49eecd66c2e56813.tar.gz
slx-admin-cbb3d0f368347993b61fde2a49eecd66c2e56813.tar.xz
slx-admin-cbb3d0f368347993b61fde2a49eecd66c2e56813.zip
[statistics] Feature: BIOS update info
Fetch list of known BIOS updates that fix issues wrt. bwLehrpool/OpenSLX/whatever it's called today.
-rw-r--r--config.php.example2
-rw-r--r--modules-available/statistics/inc/parser.inc.php8
-rw-r--r--modules-available/statistics/lang/de/permissions.json2
-rw-r--r--modules-available/statistics/lang/de/template-tags.json5
-rw-r--r--modules-available/statistics/lang/en/permissions.json2
-rw-r--r--modules-available/statistics/lang/en/template-tags.json5
-rw-r--r--modules-available/statistics/page.inc.php90
-rw-r--r--modules-available/statistics/templates/machine-bios-update.html26
-rw-r--r--modules-available/statistics/templates/machine-main.html16
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}} &raquo;
+</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">&times;</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>