RU
games/xencenter-xenadmin-xcp-jumphp / src / Feature / Pools / Dashboard.php · commit fb1b7c9
<?phpnamespace App\Feature\Pools;use App\Gui\Units;use App\Model\Connection;use App\Model\Session;use App\Xapi\Rrd;/** * The cards of the Dashboard tab (the root node "XenCenter"): one per connection, with what the cache and the performance figures * say. A card: id (the tree node to select), index (of the connection), name, state, detail, pool (bool), hosts, vms, running, * cpu (0..1 or null: no figures yet), memory (0..1 or null), memoryText, alerts. */final class Dashboard{    /** @param array<int, Rrd> $rrd the figures of each connection (MainForm::$rrd) @return list<array<string, mixed>> */    public static function cards(Session $session, array $rrd): array    {        $cards = [];        foreach ($session->connections as $i => $c) {            $cards[] = self::card($c, $i, $rrd[$i] ?? null);        }        return $cards;    }    /** @return array<string, mixed> */    public static function card(Connection $c, int $index, ?Rrd $rrd): array    {        $card = ['index' => $index, 'id' => 'conn:' . $index, 'name' => $c->name(), 'state' => $c->state, 'pool' => false, 'hosts' => 0, 'vms' => 0, 'running' => 0,            'cpu' => null, 'memory' => null, 'memoryText' => '', 'alerts' => 0, 'detail' => match ($c->state) {                Connection::CONNECTING => $c->phase ?: 'Connecting…',                Connection::FAILED => $c->error,                default => $c->profile->host,            }];        if (!$c->isConnected()) {            return $card;        }        $cache = $c->cache;        $card['pool'] = $cache->isRealPool();        $card['id'] = (string)($card['pool'] ? $cache->poolRef() : $cache->master());        $card['detail'] = $c->profile->host;        $hosts = $cache->hosts();        $card['hosts'] = count($hosts);        foreach ($cache->vms() as $vm) {            $card['vms']++;            $card['running'] += $vm['power_state'] === 'Running' ? 1 : 0;        }        // memory: what the hosts' metrics say; CPU: the last figure of each host's CPUs, weighted by their number        $total = $used = 0.0;        $cpuSum = 0.0;        $cpuCount = 0;        foreach ($hosts as $ref => $h) {            $m = $cache->hostMemory($ref);            $total += $m['total'];            $used += $m['used'];            if ($rrd !== null) {                foreach ($rrd->names('host', (string)$h['uuid']) as $name) {                    if (preg_match('/^cpu\d+$/', $name)) {                        $series = $rrd->series('host', (string)$h['uuid'], $name);                        if ($series !== []) {                            $cpuSum += (float)end($series)[1];                            $cpuCount++;                        }                    }                }            }        }        $card['cpu'] = $cpuCount > 0 ? $cpuSum / $cpuCount : null;        $card['memory'] = $total > 0 ? $used / $total : null;        $card['memoryText'] = $total > 0 ? Units::bytes($used) . ' of ' . Units::bytes($total) : '';        $card['alerts'] = count($cache->messages());        return $card;    }    /** The line over the cards. @param list<array<string, mixed>> $cards */    public static function summary(array $cards): string    {        if ($cards === []) {            return 'No server yet: File > Add New Server… (or Open the Demo Pool).';        }        $connected = count(array_filter($cards, fn ($c) => $c['state'] === Connection::CONNECTED));        $hosts = array_sum(array_column($cards, 'hosts'));        $vms = array_sum(array_column($cards, 'vms'));        $running = array_sum(array_column($cards, 'running'));        $alerts = array_sum(array_column($cards, 'alerts'));        return "$connected of " . count($cards) . " connected · $hosts servers · $running of $vms VMs running · $alerts alerts";    }}