diff options
author | Simon Rettberg | 2018-01-11 11:19:14 +0100 |
---|---|---|
committer | Simon Rettberg | 2018-01-11 11:19:14 +0100 |
commit | 4537b9b7c9eb63bf3b2d5066d6c50e68f7de4956 (patch) | |
tree | 454c72e456ca01d5ab4a39114851737c9d7fc57c /modules-available | |
parent | [translations] Focus first untranslated tag (diff) | |
download | slx-admin-4537b9b7c9eb63bf3b2d5066d6c50e68f7de4956.tar.gz slx-admin-4537b9b7c9eb63bf3b2d5066d6c50e68f7de4956.tar.xz slx-admin-4537b9b7c9eb63bf3b2d5066d6c50e68f7de4956.zip |
[statistics] Add "replace machines" feature (not linked to anywhere yet)
Diffstat (limited to 'modules-available')
11 files changed, 174 insertions, 3 deletions
diff --git a/modules-available/dnbd3/hooks/statistics-machine-replace.inc.php b/modules-available/dnbd3/hooks/statistics-machine-replace.inc.php new file mode 100644 index 00000000..5e4c4e75 --- /dev/null +++ b/modules-available/dnbd3/hooks/statistics-machine-replace.inc.php @@ -0,0 +1,6 @@ +<?php + +foreach ($list as $entry) { + unset($entry['datelimit']); + Database::exec('UPDATE IGNORE dnbd3_server SET machineuuid = :new WHERE machineuuid = :old', $entry); +} diff --git a/modules-available/roomplanner/hooks/statistics-machine-replace.inc.php b/modules-available/roomplanner/hooks/statistics-machine-replace.inc.php new file mode 100644 index 00000000..651c4c25 --- /dev/null +++ b/modules-available/roomplanner/hooks/statistics-machine-replace.inc.php @@ -0,0 +1,7 @@ +<?php + + +foreach ($list as $entry) { + unset($entry['datelimit']); + Database::exec('UPDATE IGNORE location_roomplan SET tutoruuid = :new WHERE tutoruuid = :old', $entry); +}
\ No newline at end of file diff --git a/modules-available/runmode/hooks/statistics-machine-replace.inc.php b/modules-available/runmode/hooks/statistics-machine-replace.inc.php new file mode 100644 index 00000000..cd23e552 --- /dev/null +++ b/modules-available/runmode/hooks/statistics-machine-replace.inc.php @@ -0,0 +1,6 @@ +<?php + +foreach ($list as $entry) { + unset($entry['datelimit']); + Database::exec('UPDATE IGNORE runmode SET machineuuid = :new WHERE machineuuid = :old', $entry); +} diff --git a/modules-available/statistics/lang/de/messages.json b/modules-available/statistics/lang/de/messages.json index c9667f7b..a9256d5a 100644 --- a/modules-available/statistics/lang/de/messages.json +++ b/modules-available/statistics/lang/de/messages.json @@ -1,7 +1,11 @@ { "deleted-n-machines": "{{0}} Clients gel\u00f6scht", + "ignored-both-in-use": "Rechnerpaar ignoriert, da beide noch in Betrieb zu sein scheinen. ({{0}} und {{1}})", "invalid-filter-argument": "Das Argument {{1}} ist nicht g\u00fcltig f\u00fcr den Filter {{0}}", "invalid-filter-key": "{{0}} ist kein g\u00fcltiges Filterkriterium", + "invalid-replace-format": "Ung\u00fcltiges Parameterformat ({{0}})", + "no-replacement-matches": "Keine Rechner gefunden, die den oben genannten Kriterien entsprechen", "notes-saved": "Anmerkungen gespeichert", - "unknown-machine": "Unbekannte Rechner-ID {{0}}" + "unknown-machine": "Unbekannte Rechner-ID {{0}}", + "x-machines-replaced": "{{0}} Rechner ersetzt" }
\ 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 b8cf0bb1..84c4690c 100644 --- a/modules-available/statistics/lang/de/template-tags.json +++ b/modules-available/statistics/lang/de/template-tags.json @@ -66,6 +66,11 @@ "lang_ramSlots": "Speicher-Slots", "lang_realCores": "Kerne", "lang_reallocatedSectors": "Defekte Sektoren", + "lang_replace": "Ersetzen", + "lang_replaceInstructions": "Hier k\u00f6nnen Sie Metadaten automatisch \u00fcbertragen, wenn in einem Raum die Rechner ausgetauscht wurden. Dies setzt voraus, dass alle neuen Rechner die gleiche IP Adresse erhalten haben wie der Rechner, der zuvor am entsprechenden Platz stand, und die neuen Rechner alle einmal gestartet wurden. In der Liste unten sehen Sie alle Rechnerpaare, auf die folgendes zutrifft: 1) Die IP-Adressen sind identisch 2) Der letzte Boot des einen Rechners liegt vor dem ersten Boot des anderen Rechners. W\u00e4hlen Sie alle Rechnerpaare aus, f\u00fcr die eine Ersetzung stattfinden soll. Bei der Ersetzung werden alle Logeintr\u00e4ge, Sitzungslogs, Position im Raumplan und evtl. spezielle Betriebsmodi vom alten Rechner auf den neuen \u00dcbertragen.", + "lang_replaceMachinesHeading": "Rechner ersetzen", + "lang_replaceNew": "Alter Rechner", + "lang_replaceOld": "Neuer Rechner", "lang_runMode": "Betriebsmodus", "lang_runmodeMachines": "Mit besonderem Betriebsmodus", "lang_runtimeHours": "Laufzeit (Stunden)", @@ -76,6 +81,7 @@ "lang_sockets": "Sockel", "lang_subnet": "Subnetz", "lang_sureDeletePermanent": "M\u00f6chten Sie diese(n) Rechner wirklich unwiderruflich aus der Datenbank entfernen?\r\n\r\nWichtig: L\u00f6schen verhindert nicht, dass ein Rechner nach erneutem Starten von bwLehrpool wieder in die Datenbank aufgenommen wird.", + "lang_sureReplaceNoUndo": "Wollen Sie die Daten ausgew\u00e4hlten Rechner \u00fcbertragen? Diese Aktion kann nicht r\u00fcckg\u00e4ngig gemacht werden.", "lang_tempPart": "Temp. Partition", "lang_tempPartStats": "Tempor\u00e4re Partition", "lang_thoseAreProjectors": "Diese Modellnamen werden als Beamer behandelt, auch wenn die EDID-Informationen des Ger\u00e4tes anderes berichten.", diff --git a/modules-available/statistics/lang/en/messages.json b/modules-available/statistics/lang/en/messages.json index 3471c472..0f290f2e 100644 --- a/modules-available/statistics/lang/en/messages.json +++ b/modules-available/statistics/lang/en/messages.json @@ -1,7 +1,11 @@ { "deleted-n-machines": "Deleted {{0}} clients", + "ignored-both-in-use": "Ignoring machine pair as both still seem to be in use. ({{0}} and {{1}})", "invalid-filter-argument": "{{1}} is not a vald argument for filter {{0}}", "invalid-filter-key": "{{0}} is not a valid filter", + "invalid-replace-format": "Invalid parameter format ({{0}})", + "no-replacement-matches": "No machines match the criteria from above", "notes-saved": "Notes have been saved", - "unknown-machine": "Unknown machine uuid {{0}}" + "unknown-machine": "Unknown machine uuid {{0}}", + "x-machines-replaced": "{{0}} machine(s) replaced" }
\ 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 3529b7d0..b064ee50 100644 --- a/modules-available/statistics/lang/en/template-tags.json +++ b/modules-available/statistics/lang/en/template-tags.json @@ -66,6 +66,11 @@ "lang_ramSlots": "Memory slots", "lang_realCores": "Cores", "lang_reallocatedSectors": "Bad sectors", + "lang_replace": "Replace", + "lang_replaceInstructions": "If some PCs\/clients have been physically replaced, you can re-assign log entries, session data, position information etc. from the old machine to the new one. This requires that the new machine gets assigned the same IP address as the old one and, if the room planner is used -- that it is placed in the same spot as the old one. The list below shows all machine pairs where 1) the last boot of one machine lies before the first boot of the other one 2) both machines had the same IP address last time they booted. The replacement action will reassign all log events, room plan location and special run mode from the old machine to the new machine.", + "lang_replaceMachinesHeading": "Replace machines", + "lang_replaceNew": "Old machine", + "lang_replaceOld": "New machine", "lang_runMode": "Mode of operation", "lang_runmodeMachines": "With special mode of operation", "lang_runtimeHours": "Runtime (hours)", @@ -76,6 +81,7 @@ "lang_sockets": "Sockets", "lang_subnet": "Subnet", "lang_sureDeletePermanent": "Are your sure you want to delete the selected machine(s) from the database? This cannot be undone.\r\n\r\nNote: Deleting machines from the database does not prevent booting up bwLehrpool again, which would recreate their respective database entries.", + "lang_sureReplaceNoUndo": "Are you sure you want to replace the selected machine pairs? This action cannot be undone.", "lang_tempPart": "Temp. partition", "lang_tempPartStats": "Temporary partition", "lang_thoseAreProjectors": "These model names will always be treated as beamers, even if the device's EDID data says otherwise.", diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index 09359342..877a90f2 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -1062,7 +1062,11 @@ class Page_Statistics extends Page public static function getPciId($cat, $id) { - return Database::queryFirst('SELECT value, dateline FROM pciid WHERE category = :cat AND id = :id LIMIT 1', + static $cache = []; + $key = $cat . '-' . $id; + if (isset($cache[$key])) + return $cache[$key]; + return $cache[$key] = Database::queryFirst('SELECT value, dateline FROM pciid WHERE category = :cat AND id = :id LIMIT 1', array('cat' => $cat, 'id' => $id)); } diff --git a/modules-available/statistics/pages/replace.inc.php b/modules-available/statistics/pages/replace.inc.php new file mode 100644 index 00000000..80bbf0ce --- /dev/null +++ b/modules-available/statistics/pages/replace.inc.php @@ -0,0 +1,119 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + $action = Request::post('action', false, 'string'); + if ($action === 'replace') { + self::handleReplace(); + } + if (Request::isPost()) { + Util::redirect('?do=statistics&show=replace'); + } + } + + private static function handleReplace() + { + $replace = Request::post('replace', false, 'array'); + if ($replace === false || empty($replace)) { + Message::addError('main.parameter-empty', 'replace'); + return; + } + $list = []; + foreach ($replace as $p) { + $split = explode('x', $p); + if (count($split) !== 2) { + Message::addError('invalid-replace-format', $p); + continue; + } + $entry = ['old' => $split[0], 'new' => $split[1]]; + $old = Database::queryFirst('SELECT lastseen FROM machine WHERE machineuuid = :old', + ['old' => $entry['old']]); + if ($old === false) { + Message::addError('unknown-machine', $entry['old']); + continue; + } + $new = Database::queryFirst('SELECT firstseen FROM machine WHERE machineuuid = :new', + ['new' => $entry['new']]); + if ($new === false) { + Message::addError('unknown-machine', $entry['new']); + continue; + } + if ($old['lastseen'] - 86400*7 > $new['firstseen']) { + Message::addWarning('ignored-both-in-use', $entry['old'], $entry['new']); + continue; + } + $entry['datelimit'] = min($new['firstseen'], $old['lastseen']); + $list[] = $entry; + } + if (empty($list)) { + Message::addError('main.parameter-empty', 'replace'); + return; + } + + // First handle module internal tables + foreach ($list as $entry) { + Database::exec('UPDATE statistic SET machineuuid = :new WHERE machineuuid = :old AND dateline < :datelimit', $entry); + } + + // Let other modules do their thing + $fun = function($file, $list) { + include $file; + }; + foreach (Hook::load('statistics-machine-replace') as $hook) { + $fun($hook->file, $list); + } + + // Finalize by updating machine table + foreach ($list as $entry) { + unset($entry['datelimit']); + Database::exec('UPDATE machine old, machine new SET + new.fixedlocationid = old.fixedlocationid, + new.position = old.position, + old.position = NULL, + new.notes = old.notes, + old.notes = NULL, + old.lastseen = new.firstseen + WHERE old.machineuuid = :old AND new.machineuuid = :new', $entry); + } + Message::addSuccess('x-machines-replaced', count($list)); + } + + public static function doRender() + { + self::listSuggestions(); + } + + private static function listSuggestions() + { + if (Request::get('debug', false) !== false) { + $oldCutoff = time() - 86400 * 180; + $newCutoff = time() - 86400 * 180; + } else { + $oldCutoff = time() - 86400 * 90; + $newCutoff = time() - 86400 * 30; + } + $res = Database::simpleQuery("SELECT + old.machineuuid AS olduuid, old.locationid AS oldlid, old.hostname AS oldhost, + old.clientip AS oldip, old.macaddr AS oldmac, old.lastseen AS oldlastseen, old.systemmodel AS oldmodel, + new.machineuuid AS newuuid, new.locationid AS newlid, new.hostname AS newhost, + new.clientip AS newip, new.macaddr AS newmac, new.firstseen AS newfirstseen, new.systemmodel AS newmodel + FROM machine old INNER JOIN machine new ON (old.clientip = new.clientip AND old.lastseen < new.firstseen AND old.lastseen > $oldCutoff AND new.firstseen > $newCutoff) + ORDER BY oldhost ASC, oldip ASC"); + $list = []; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['oldlastseen_s'] = Util::prettyTime($row['oldlastseen']); + $row['newfirstseen_s'] = Util::prettyTime($row['newfirstseen']); + $list[] = $row; + } + $data = array('pairs' => $list); + Render::addTemplate('page-replace', $data); + if (empty($list)) { + Message::addInfo('no-replacement-matches'); + } + } + +} + diff --git a/modules-available/statistics/templates/page-replace.html b/modules-available/statistics/templates/page-replace.html index f87610a2..d0e9f766 100644 --- a/modules-available/statistics/templates/page-replace.html +++ b/modules-available/statistics/templates/page-replace.html @@ -17,6 +17,10 @@ } </style> +<p> + {{lang_replaceInstructions}} +</p> + <form method="post" action="?do=statistics&show=replace"> <input type="hidden" name="token" value="{{token}}"> <table class="reptable"> diff --git a/modules-available/syslog/hooks/statistics-machine-replace.inc.php b/modules-available/syslog/hooks/statistics-machine-replace.inc.php new file mode 100644 index 00000000..6be0dd76 --- /dev/null +++ b/modules-available/syslog/hooks/statistics-machine-replace.inc.php @@ -0,0 +1,5 @@ +<?php + +foreach ($list as $entry) { + Database::exec('UPDATE IGNORE clientlog SET machineuuid = :new WHERE machineuuid = :old AND dateline < :datelimit', $entry); +} |