summaryrefslogtreecommitdiffstats
path: root/modules-available/dnbd3
diff options
context:
space:
mode:
authorSimon Rettberg2017-10-06 18:00:59 +0200
committerSimon Rettberg2017-10-06 18:00:59 +0200
commit2933768b0dc7d58f0b0ba7f2efcbaf1806eb275b (patch)
tree487583c2145bd86cd98ced3705f46af455323267 /modules-available/dnbd3
parentAllow page modules with digits in name (diff)
downloadslx-admin-2933768b0dc7d58f0b0ba7f2efcbaf1806eb275b.tar.gz
slx-admin-2933768b0dc7d58f0b0ba7f2efcbaf1806eb275b.tar.xz
slx-admin-2933768b0dc7d58f0b0ba7f2efcbaf1806eb275b.zip
[dnbd3] New module for managing dnbd3 servers - WIP
Diffstat (limited to 'modules-available/dnbd3')
-rw-r--r--modules-available/dnbd3/config.json4
-rw-r--r--modules-available/dnbd3/inc/dnbd3rpc.inc.php33
-rw-r--r--modules-available/dnbd3/inc/dnbd3util.inc.php62
-rw-r--r--modules-available/dnbd3/lang/de/messages.json3
-rw-r--r--modules-available/dnbd3/lang/de/module.json4
-rw-r--r--modules-available/dnbd3/lang/de/template-tags.json8
-rw-r--r--modules-available/dnbd3/lang/en/messages.json3
-rw-r--r--modules-available/dnbd3/lang/en/module.json4
-rw-r--r--modules-available/dnbd3/lang/pt/module.json3
-rw-r--r--modules-available/dnbd3/page.inc.php96
-rw-r--r--modules-available/dnbd3/templates/page-clientlist.html12
-rw-r--r--modules-available/dnbd3/templates/page-serverlist.html51
12 files changed, 283 insertions, 0 deletions
diff --git a/modules-available/dnbd3/config.json b/modules-available/dnbd3/config.json
new file mode 100644
index 00000000..f06dda5c
--- /dev/null
+++ b/modules-available/dnbd3/config.json
@@ -0,0 +1,4 @@
+{
+ "category":"main.settings-server",
+ "dependencies":["runmode"]
+}
diff --git a/modules-available/dnbd3/inc/dnbd3rpc.inc.php b/modules-available/dnbd3/inc/dnbd3rpc.inc.php
new file mode 100644
index 00000000..41dcefd4
--- /dev/null
+++ b/modules-available/dnbd3/inc/dnbd3rpc.inc.php
@@ -0,0 +1,33 @@
+<?php
+
+class Dnbd3Rpc {
+
+ /**
+ * Query given DNBD3 server for status information.
+ *
+ * @param bool $stats include general stats
+ * @param bool $clients include client list
+ * @param bool $images include image list
+ * @param string $server server address
+ * @param int $port server port
+ * @return false|array the queried data as an array, or false on error
+ */
+ public static function query($stats, $clients, $images, $server, $port = 5003)
+ {
+ $url = 'http://' . $server . ':' . $port . '/query?';
+ if ($stats) {
+ $url .= 'q=stats&';
+ }
+ if ($clients) {
+ $url .= 'q=clients&';
+ }
+ if ($images) {
+ $url .= 'q=images&';
+ }
+ $str = Download::asString($url, 3, $code);
+ if ($str === false || $code !== 200)
+ return false;
+ return json_decode($str, true);
+ }
+
+}
diff --git a/modules-available/dnbd3/inc/dnbd3util.inc.php b/modules-available/dnbd3/inc/dnbd3util.inc.php
new file mode 100644
index 00000000..b04583b8
--- /dev/null
+++ b/modules-available/dnbd3/inc/dnbd3util.inc.php
@@ -0,0 +1,62 @@
+<?php
+
+class Dnbd3Util {
+
+ public static function updateServerStatus()
+ {
+ $dynClients = RunMode::getForMode('dnbd3', 'proxy', false, true);
+ $servers = array();
+ $res = Database::simpleQuery('SELECT s.serverid, s.machineuuid, s.fixedip, s.lastup, s.lastdown, m.clientip
+ FROM dnbd3_server s
+ LEFT JOIN machine m USING (machineuuid)');
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (!is_null($row['clientip'])) {
+ $ip = $row['clientip'];
+ } elseif (!is_null($row['fixedip'])) {
+ $ip = $row['fixedip'];
+ } else {
+ continue; // Huh?
+ }
+ if (!is_null($row['machineuuid'])) {
+ unset($dynClients[$row['machineuuid']]);
+ }
+ $server = array(
+ 'serverid' => $row['serverid'],
+ 'addr' => $ip,
+ );
+ $servers[] = $server;
+ }
+ // See if any clients are in dnbd3 proxy mode but don't have a matching row in the dnbd3_server table
+ foreach ($dynClients as $client) {
+ Database::exec('INSERT IGNORE INTO dnbd3_server (machineuuid) VALUES (:machineuuid)',
+ array('machineuuid' => $client['machineuuid']));
+ // Missing from $servers now but we'll handle them in the next run, so don't bother
+ }
+ // Now query them all
+ $NOW = time();
+ foreach ($servers as $server) {
+ $data = Dnbd3Rpc::query(true, false, false, $server['addr']);
+ if (!is_array($data) || !isset($data['runId'])) {
+ Database::exec('UPDATE dnbd3_server SET uptime = 0, clientcount = 0 WHERE serverid = :serverid',
+ array('serverid' => $server['serverid']));
+ continue;
+ }
+ // Seems up - since we only get absolute rx/tx values from the server, we have to prevent update race conditions
+ // and make sure the server was not restarted in the meantime (use runid and uptime for this)
+ Database::exec('UPDATE dnbd3_server SET runid = :runid, lastseen = :now, uptime = :uptime,
+ totalup = totalup + If(runid = :runid AND uptime <= :uptime, If(lastup < :up, :up - lastup, 0), If(:uptime < 1800, :up, 0)),
+ totaldown = totaldown + If(runid = :runid AND uptime <= :uptime, If(lastdown < :down, :down - lastdown, 0), If(:uptime < 1800, :up, 0)),
+ lastup = :up, lastdown = :down, clientcount = :clientcount
+ WHERE serverid = :serverid', array(
+ 'runid' => $data['runId'],
+ 'now' => $NOW,
+ 'uptime' => $data['uptime'],
+ 'up' => $data['bytesSent'],
+ 'down' => $data['bytesReceived'],
+ 'clientcount' => $data['clientCount'],
+ 'serverid' => $server['serverid']
+ ));
+ }
+ }
+
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/de/messages.json b/modules-available/dnbd3/lang/de/messages.json
new file mode 100644
index 00000000..9d7c143b
--- /dev/null
+++ b/modules-available/dnbd3/lang/de/messages.json
@@ -0,0 +1,3 @@
+{
+ "server-unreachable": "Server nicht erreichbar"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/de/module.json b/modules-available/dnbd3/lang/de/module.json
new file mode 100644
index 00000000..cf748a49
--- /dev/null
+++ b/modules-available/dnbd3/lang/de/module.json
@@ -0,0 +1,4 @@
+{
+ "module_name": "DNBD3",
+ "page_title": "DNBD3-Verwaltung"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/de/template-tags.json b/modules-available/dnbd3/lang/de/template-tags.json
new file mode 100644
index 00000000..8c8f6d7a
--- /dev/null
+++ b/modules-available/dnbd3/lang/de/template-tags.json
@@ -0,0 +1,8 @@
+{
+ "lang_clientCount": "Clients",
+ "lang_lastSeen": "Letzte Aktivit\u00e4t",
+ "lang_proxyServerTHead": "Server\/Proxy",
+ "lang_rxTotal": "Gesamt empfangen",
+ "lang_txTotal": "Gesamt gesendet",
+ "lang_uptime": "Aktuelle Laufzeit"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/en/messages.json b/modules-available/dnbd3/lang/en/messages.json
new file mode 100644
index 00000000..4c658e11
--- /dev/null
+++ b/modules-available/dnbd3/lang/en/messages.json
@@ -0,0 +1,3 @@
+{
+ "server-unreachable": "Server not reachable"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/en/module.json b/modules-available/dnbd3/lang/en/module.json
new file mode 100644
index 00000000..d2bb6fd3
--- /dev/null
+++ b/modules-available/dnbd3/lang/en/module.json
@@ -0,0 +1,4 @@
+{
+ "module_name": "DNBD3",
+ "page_title": "DNBD3 management"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/pt/module.json b/modules-available/dnbd3/lang/pt/module.json
new file mode 100644
index 00000000..8cc7f8e4
--- /dev/null
+++ b/modules-available/dnbd3/lang/pt/module.json
@@ -0,0 +1,3 @@
+{
+ "module_name": "Log do Servidor"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php
new file mode 100644
index 00000000..309680a6
--- /dev/null
+++ b/modules-available/dnbd3/page.inc.php
@@ -0,0 +1,96 @@
+<?php
+
+class Page_Dnbd3 extends Page
+{
+
+ protected function doPreprocess()
+ {
+ User::load();
+
+ if (!User::isLoggedIn()) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
+ if (Request::post('re')) {
+ Dnbd3Util::updateServerStatus();
+ Util::redirect('?do=dnbd3');
+ }
+ }
+
+ protected function doRender()
+ {
+ $show = Request::get('show', false, 'string');
+ if ($show === 'clients') {
+ $this->showClientList();
+ } elseif ($show === false) {
+ $this->showServerList();
+ } else {
+ Util::redirect('?do=dnbd3');
+ }
+ }
+
+ private function showServerList()
+ {
+ $dynClients = RunMode::getForMode(Page::getModule(), 'proxy', true, true);
+ $res = Database::simpleQuery('SELECT serverid, machineuuid, fixedip, lastseen, uptime, totalup, totaldown, clientcount FROM dnbd3_server');
+ $servers = array();
+ $sort = array();
+ $NOW = time();
+ while ($server = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (isset($dynClients[$server['machineuuid']])) {
+ $server += $dynClients[$server['machineuuid']];
+ unset($dynClients[$server['machineuuid']]);
+ }
+ if ($server['uptime'] != 0) {
+ $server['uptime'] += ($NOW - $server['lastseen']);
+ }
+ $server['lastseen_s'] = $server['lastseen'] ? date('d.m.Y H:i', $server['lastseen']) : '-';
+ $server['uptime_s'] = $server['uptime'] ? floor($server['uptime'] / 86400) . 'd ' . gmdate('H:i', $server['uptime']) : '-';
+ $server['totalup_s'] = Util::readableFileSize($server['totalup']);
+ $server['totaldown_s'] = Util::readableFileSize($server['totaldown']);
+ $servers[] = $server;
+ $sort[] = $server['fixedip'] . '.' . $server['machineuuid'];
+ }
+ foreach ($dynClients as $server) {
+ $servers[] = $server;
+ $sort[] = 'A' . $server['machineuuid'];
+ }
+ array_multisort($sort, SORT_ASC, $servers);
+ Render::addTemplate('page-serverlist', array('list' => $servers));
+ }
+
+ private function showClientList()
+ {
+ $serverId = Request::get('server', false, 'int');
+ if ($serverId === false) {
+ // TODO: Missing param
+ }
+ $server = Database::queryFirst('SELECT s.machineuuid, s.fixedip, m.clientip, m.hostname
+ FROM dnbd3_server s
+ LEFT JOIN machine m USING (machineuuid)
+ WHERE s.serverid = :serverId', compact('serverId'));
+ if ($server === false) {
+ // TODO: Not found
+ }
+ if (!is_null($server['clientip'])) {
+ $ip = $server['clientip'];
+ } elseif (!is_null($server['fixedip'])) {
+ $ip = $server['fixedip'];
+ } else {
+ $ip = '127.0.0.1';
+ }
+ $data = Dnbd3Rpc::query(false, true, false, $ip);
+ if ($data === false || !isset($data['clients'])) {
+ Message::addError('server-unreachable');
+ } else {
+ $sort = array();
+ foreach ($data['clients'] as &$c) {
+ $c['bytesSent_s'] = Util::readableFileSize($c['bytesSent']);
+ $sort[] = $c['bytesSent'];
+ }
+ array_multisort($sort, SORT_DESC, $data['clients']);
+ Render::addTemplate('page-clientlist', $data);
+ }
+ }
+
+}
diff --git a/modules-available/dnbd3/templates/page-clientlist.html b/modules-available/dnbd3/templates/page-clientlist.html
new file mode 100644
index 00000000..3fd4442c
--- /dev/null
+++ b/modules-available/dnbd3/templates/page-clientlist.html
@@ -0,0 +1,12 @@
+<table class="table">
+ {{#clients}}
+ <tr>
+ <td>
+ {{address}}
+ </td>
+ <td class="text-right">
+ {{bytesSent_s}}
+ </td>
+ </tr>
+ {{/clients}}
+</table> \ No newline at end of file
diff --git a/modules-available/dnbd3/templates/page-serverlist.html b/modules-available/dnbd3/templates/page-serverlist.html
new file mode 100644
index 00000000..b7fe9038
--- /dev/null
+++ b/modules-available/dnbd3/templates/page-serverlist.html
@@ -0,0 +1,51 @@
+<form method="post">
+ <input type="hidden" name="token" value="{{token}}">
+ <button name="re" value="bla">Refresh</button>
+</form>
+
+<table class="table">
+ <tr>
+ <th>{{lang_proxyServerTHead}}</th>
+ <th class="text-right">{{lang_lastSeen}}</th>
+ <th class="text-right">{{lang_uptime}}</th>
+ <th class="text-right">{{lang_txTotal}}</th>
+ <th class="text-right">{{lang_rxTotal}}</th>
+ <th class="text-right">{{lang_clientCount}}</th>
+ </tr>
+ {{#list}}
+ <tr>
+ <td>
+ {{#uptime}}
+ <span class="glyphicon glyphicon-ok text-success"></span>
+ {{/uptime}}
+ {{^uptime}}
+ <span class="glyphicon glyphicon-off"></span>
+ {{/uptime}}
+ {{fixedip}}
+ {{#machineuuid}}
+ <a href="?do=Statistics&uuid={{machineuuid}}">{{hostname}} ({{clientip}})</a>
+ {{/machineuuid}}
+ </td>
+ <td data-sort="int" data-sort-default="desc" data-sort-value="{{lastseen}}" class="text-right">
+ {{lastseen_s}}
+ </td>
+ <td data-sort="int" data-sort-default="desc" data-sort-value="{{uptime}}" class="text-right">
+ {{uptime_s}}
+ </td>
+ <td data-sort="int" data-sort-default="desc" data-sort-value="{{totalup}}" class="text-right">
+ {{totalup_s}}
+ </td>
+ <td data-sort="int" data-sort-default="desc" data-sort-value="{{totaldown}}" class="text-right">
+ {{totaldown_s}}
+ </td>
+ <td data-sort="int" data-sort-default="desc" class="text-right">
+ {{#uptime}}
+ <a href="?do=dnbd3&amp;show=clients&amp;server={{serverid}}">{{clientcount}}</a>
+ {{/uptime}}
+ {{^uptime}}
+ -
+ {{/uptime}}
+ </td>
+ </tr>
+ {{/list}}
+</table> \ No newline at end of file