summaryrefslogtreecommitdiffstats
path: root/modules-available/statistics/inc
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/statistics/inc')
-rw-r--r--modules-available/statistics/inc/filter.inc.php49
-rw-r--r--modules-available/statistics/inc/filterset.inc.php82
-rw-r--r--modules-available/statistics/inc/parser.inc.php36
-rw-r--r--modules-available/statistics/inc/statistics.inc.php17
4 files changed, 147 insertions, 37 deletions
diff --git a/modules-available/statistics/inc/filter.inc.php b/modules-available/statistics/inc/filter.inc.php
index f6765059..46de467b 100644
--- a/modules-available/statistics/inc/filter.inc.php
+++ b/modules-available/statistics/inc/filter.inc.php
@@ -14,18 +14,24 @@ class Filter
public $operator;
public $argument;
+ private static $keyCounter = 0;
+
+ public static function getNewKey($colname)
+ {
+ return $colname . '_' . (self::$keyCounter++);
+ }
+
public function __construct($column, $operator, $argument = null)
{
$this->column = trim($column);
$this->operator = trim($operator);
- $this->argument = trim($argument);
+ $this->argument = is_array($argument) ? $argument : trim($argument);
}
/* returns a where clause and adds needed operators to the passed array */
public function whereClause(&$args, &$joins)
{
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
$addendum = '';
/* check if we have to do some parsing*/
@@ -187,20 +193,24 @@ class Id44Filter extends Filter
public function whereClause(&$args, &$joins)
{
global $SIZE_ID44;
- $lower = floor(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, false) * 1024 - 100);
- $upper = ceil(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, true) * 1024 + 100);
+ if ($this->operator === '=' || $this->operator === '!=') {
+ $lower = floor(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, false) * 1024 - 100);
+ $upper = ceil(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, true) * 1024 + 100);
+ } else {
+ $lower = $upper = round($this->argument * 1024);
+ }
- if ($this->operator == '=') {
+ if ($this->operator === '=') {
return " id44mb BETWEEN $lower AND $upper";
- } elseif ($this->operator == '!=') {
+ } elseif ($this->operator === '!=') {
return " id44mb < $lower OR id44mb > $upper";
- } elseif ($this->operator == '<=') {
- return " id44mb < $upper";
- } elseif ($this->operator == '>=') {
- return " id44mb > $lower";
- } elseif ($this->operator == '<') {
+ } elseif ($this->operator === '<=') {
+ return " id44mb <= $upper";
+ } elseif ($this->operator === '>=') {
+ return " id44mb >= $lower";
+ } elseif ($this->operator === '<') {
return " id44mb < $lower";
- } elseif ($this->operator == '>') {
+ } elseif ($this->operator === '>') {
return " id44mb > $upper";
} else {
error_log("unimplemented operator in Id44Filter: $this->operator");
@@ -222,8 +232,7 @@ class StateFilter extends Filter
$map = [ 'on' => ['IDLE', 'OCCUPIED'], 'off' => ['OFFLINE'], 'idle' => ['IDLE'], 'occupied' => ['OCCUPIED'], 'standby' => ['STANDBY'] ];
$neg = $this->operator == '!=' ? 'NOT ' : '';
if (array_key_exists($this->argument, $map)) {
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
$args[$key] = $map[$this->argument];
return " machine.state $neg IN ( :$key ) ";
} else {
@@ -245,13 +254,17 @@ class LocationFilter extends Filter
$recursive = (substr($this->operator, -1) === '~');
$this->operator = str_replace('~', '=', $this->operator);
- settype($this->argument, 'int');
+ if (is_array($this->argument)) {
+ if ($recursive)
+ Util::traceError('Cannot use ~ operator for location with array');
+ } else {
+ settype($this->argument, 'int');
+ }
$neg = $this->operator === '=' ? '' : 'NOT';
if ($this->argument === 0) {
return "machine.locationid IS $neg NULL";
} else {
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
if ($recursive) {
$args[$key] = array_keys(Location::getRecursiveFlat($this->argument));
} else {
diff --git a/modules-available/statistics/inc/filterset.inc.php b/modules-available/statistics/inc/filterset.inc.php
index 25c5c8fa..774bfd18 100644
--- a/modules-available/statistics/inc/filterset.inc.php
+++ b/modules-available/statistics/inc/filterset.inc.php
@@ -9,6 +9,8 @@ class FilterSet
private $sortDirection;
private $sortColumn;
+ private $cache = false;
+
public function __construct($filters)
{
$this->filters = $filters;
@@ -16,19 +18,28 @@ class FilterSet
public function setSort($col, $direction)
{
- $this->sortDirection = $direction === 'DESC' ? 'DESC' : 'ASC';
+ $direction = ($direction === 'DESC' ? 'DESC' : 'ASC');
- if (is_string($col) && array_key_exists($col, Page_Statistics::$columns)) {
- $this->sortColumn = $col;
- } else {
+ if (!is_string($col) || !array_key_exists($col, Page_Statistics::$columns)) {
/* default sorting column is clientip */
- $this->sortColumn = 'clientip';
+ $col = 'clientip';
}
-
+ if ($col === $this->sortColumn && $direction === $this->sortDirection)
+ return;
+ $this->cache = false;
+ $this->sortDirection = $direction;
+ $this->sortColumn = $col;
}
public function makeFragments(&$where, &$join, &$sort, &$args)
{
+ if ($this->cache !== false) {
+ $where = $this->cache['where'];
+ $join = $this->cache['join'];
+ $sort = $this->cache['sort'];
+ $args = $this->cache['args'];
+ return;
+ }
/* generate where clause & arguments */
$where = '';
$joins = [];
@@ -54,16 +65,13 @@ class FilterSet
$sort = " ORDER BY " . $concreteCol . " " . $this->sortDirection
. ", machineuuid ASC";
+ $this->cache = compact('where', 'join', 'sort', 'args');
}
public function isNoId44Filter()
{
- foreach ($this->filters as $filter) {
- if (get_class($filter) === 'Id44Filter' && $filter->argument == 0) {
- return true;
- }
- }
- return false;
+ $filter = $this->hasFilter('Id44Filter');
+ return $filter !== false && $filter->argument == 0;
}
public function getSortDirection()
@@ -78,10 +86,58 @@ class FilterSet
public function filterNonClients()
{
- if (Module::get('runmode') === false)
+ if (Module::get('runmode') === false || $this->hasFilter('IsClientFilter') !== false)
return;
+ $this->cache = false;
// Runmode module exists, add filter
$this->filters[] = new IsClientFilter(true);
}
+ /**
+ * @param string $type filter type (class name)
+ * @return false|Filter The filter, false if not found
+ */
+ public function hasFilter($type)
+ {
+ foreach ($this->filters as $filter) {
+ if (get_class($filter) === $type) {
+ return $filter;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add a location filter based on the allowed permissions for the given permission.
+ * Returns false if the user doesn't have the given permission for any location.
+ *
+ * @param string $permission permission to use
+ * @return bool false if no permission for any location, true otherwise
+ */
+ public function setAllowedLocationsFromPermission($permission)
+ {
+ $locs = User::getAllowedLocations($permission);
+ if (empty($locs))
+ return false;
+ if (in_array(0, $locs)) {
+ if (!isset($this->filters['permissions']))
+ return true;
+ unset($this->filters['permissions']);
+ } else {
+ $this->filters['permissions'] = new LocationFilter('=', $locs);
+ }
+ $this->cache = false;
+ return true;
+ }
+
+ /**
+ * @return false|array
+ */
+ public function getAllowedLocations()
+ {
+ if (isset($this->filters['permissions']->argument) && is_array($this->filters['permissions']->argument))
+ return $this->filters['permissions']->argument;
+ return false;
+ }
+
}
diff --git a/modules-available/statistics/inc/parser.inc.php b/modules-available/statistics/inc/parser.inc.php
index 679055a7..0d39079d 100644
--- a/modules-available/statistics/inc/parser.inc.php
+++ b/modules-available/statistics/inc/parser.inc.php
@@ -104,10 +104,12 @@ class Parser {
foreach ($lines as $line) {
if (preg_match('/^Disk (\S+):.* (\d+) bytes/i', $line, $out)) {
// --- Beginning of MBR disk ---
+ unset($hdd);
if ($out[2] < 10000) // sometimes vmware reports lots of 512byte disks
continue;
+ if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper
+ continue;
// disk total size and name
- unset($hdd);
$mbrToMbFactor = 0; // This is != 0 for mbr
$sectorToMbFactor = 0; // This is != for gpt
$hdd = array(
@@ -122,10 +124,12 @@ class Parser {
$hdds[] = &$hdd;
} elseif (preg_match('/^Disk (\S+):\s+(\d+)\s+sectors,/i', $line, $out)) {
// --- Beginning of GPT disk ---
+ unset($hdd);
if ($out[2] < 1000) // sometimes vmware reports lots of 512byte disks
continue;
+ if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper
+ continue;
// disk total size and name
- unset($hdd);
$mbrToMbFactor = 0; // This is != 0 for mbr
$sectorToMbFactor = 0; // This is != for gpt
$hdd = array(
@@ -151,24 +155,44 @@ class Parser {
$type = strtolower($out[4]);
if ($type === '5' || $type === 'f' || $type === '85') {
continue;
+ } elseif ($type === '44') {
+ $out[5] = 'OpenSLX-ID44';
+ $color = '#5c1';
+ } elseif ($type === '45') {
+ $out[5] = 'OpenSLX-ID45';
+ $color = '#0d7';
+ } elseif ($type === '82') {
+ $color = '#48f';
+ } else {
+ $color = '#e55';
}
+
$partsize = round(($out[3] - $out[2]) * $mbrToMbFactor);
$hdd['partitions'][] = array(
'id' => $out[1],
'name' => $out[1],
'size' => round($partsize / 1024, $partsize < 1024 ? 1 : 0),
- 'type' => ($type === '44' ? 'OpenSLX' : $out[5]),
+ 'type' => $out[5],
);
$hdd['json'][] = array(
'label' => $out[1],
'value' => $partsize,
- 'color' => ($type === '44' ? '#4d4' : ($type === '82' ? '#48f' : '#e55')),
+ 'color' => $color,
);
$hdd['used'] += $partsize;
} elseif (isset($hdd) && $sectorToMbFactor !== 0 && preg_match(',^\s*(\d+)\s+(\d+)[\+\-]?\s+(\d+)[\+\-]?\s+\S+\s+([0-9a-f]+)\s+(.*)$,i', $line, $out)) {
// --- GPT: Partition entry ---
// Some partition
$type = $out[5];
+ if ($type === 'OpenSLX-ID44') {
+ $color = '#5c1';
+ } elseif ($type === 'OpenSLX-ID45') {
+ $color = '#0d7';
+ } elseif ($type === 'Linux swap') {
+ $color = '#48f';
+ } else {
+ $color = '#e55';
+ }
$id = $hdd['devid'] . '-' . $out[1];
$partsize = round(($out[3] - $out[2]) * $sectorToMbFactor);
$hdd['partitions'][] = array(
@@ -180,7 +204,7 @@ class Parser {
$hdd['json'][] = array(
'label' => $id,
'value' => $partsize,
- 'color' => ($type === 'OpenSLX-ID44' ? '#4d4' : ($type === 'Linux swap' ? '#48f' : '#e55')),
+ 'color' => $color,
);
$hdd['used'] += $partsize;
}
@@ -193,7 +217,7 @@ class Parser {
$hdd['size'] = round(($hdd['sectors'] * $sectorToMbFactor) / 1024);
}
$free = $hdd['size'] - $hdd['used'];
- if ($free > 5 || ($free / $hdd['size']) > 0.1) {
+ if ($hdd['size'] > 0 && ($free > 5 || ($free / $hdd['size']) > 0.1)) {
$hdd['partitions'][] = array(
'id' => 'free-id-' . $i,
'name' => Dictionary::translate('unused'),
diff --git a/modules-available/statistics/inc/statistics.inc.php b/modules-available/statistics/inc/statistics.inc.php
index 2500f16f..1f8a081a 100644
--- a/modules-available/statistics/inc/statistics.inc.php
+++ b/modules-available/statistics/inc/statistics.inc.php
@@ -70,4 +70,21 @@ class Statistics
return $list;
}
+ const SESSION_LENGTH = '~session-length';
+ const OFFLINE_LENGTH = '~offline-length';
+ const SUSPEND_LENGTH = '~suspend-length';
+
+ public static function logMachineState($uuid, $ip, $type, $start, $length, $username = '')
+ {
+ return Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
+ . " VALUES (:start, :type, :uuid, :clientip, :username, :length)", array(
+ 'start' => $start,
+ 'type' => $type,
+ 'uuid' => $uuid,
+ 'clientip' => $ip,
+ 'username' => $username,
+ 'length' => $length,
+ ));
+ }
+
}