PL
games/xencenter-xenadmin-xcp-jumphp / src / Feature / Updates / UpdatesPage.php · commit fb1b7c9
<?phpnamespace App\Feature\Updates;use App\Gui\Icons;use App\Gui\Units;use App\Model\Connection;use App\View\Page;/** * The Updates tab of a pool or a server: for each server a line (how many packages, "Reboot required", "Up to date"), under it its * packages with the version installed → the new one. The first time it is shown, the servers are asked (as XenCenter checks at * start); Check for Updates asks again. */final class UpdatesPage{    public static function page(Connection $c, string $ref, string $kind): Page    {        $hosts = $kind === 'host' ? [$ref] : array_keys($c->cache->hosts());        $hosts = array_map('strval', $hosts);        $master = (string)$c->cache->master();        usort($hosts, fn ($a, $b) => [$b === $master, $c->cache->name($a)] <=> [$a === $master, $c->cache->name($b)]);        $rows = [];        $total = 0;        $reboots = [];        foreach ($hosts as $host) {            $state = Updates::of($c, $host);            if ($state->packages === null && !$state->checking && $state->error === '' && $c->isConnected()) {                Updates::check($c, $host);          // never asked: ask now            }            $packages = $state->packages ?? [];            $total += count($packages);            $reboot = $state->rebootRequired($c, $host);            if ($reboot) {                $reboots[] = $host;            }            $summary = match (true) {                $state->installing => 'Installing updates…',                $state->checking && $state->packages === null => 'Checking for updates…',                $state->error !== '' => 'Check failed: ' . $state->error,                $packages === [] && $reboot => 'Up to date · reboot required',                $packages === [] => $state->packages === null ? 'Not checked yet' : 'Up to date',                default => count($packages) . (count($packages) === 1 ? ' update' : ' updates') . ($reboot ? ' · reboot required' : '')                    . (Updates::needsReboot($packages) ? ' (a reboot will be needed)' : ''),            };            $h = $c->cache->get($host) ?? [];            $rows[] = ['id' => $host, 'icon' => Icons::of('host', $h, $c->cache), 'cells' => [(string)($h['name_label'] ?? $host) . ($host === $master ? ' (pool master)' : ''),                $summary, $reboot ? 'Updated: ' . implode(', ', $state->rebootFor) : '', ''],                'color' => $state->error !== '' ? '#b42318' : ($reboot ? '#9a6700' : null), 'sort' => [sprintf('%s%04d', $host === $master ? '0' : '1', count($rows))]];            foreach ($packages as $p) {                $from = Updates::version($p, 'current_');                $to = Updates::version($p);                $note = trim((string)($p['description'] ?? ''));                $log = is_array($p['changelog'] ?? null) ? trim((string)($p['changelog']['description'] ?? '')) : trim((string)($p['changelog'] ?? ''));                $rows[] = ['id' => 'update:' . $host . ':' . $p['name'], 'icon' => preg_match(Updates::REBOOT_PACKAGES, $p['name']) ? 'warning' : 'info',                    'cells' => ['    ' . $p['name'], $from !== '' ? "$from → $to" : "→ $to", $note . ($log !== '' && $log !== $note ? ' — ' . $log : ''),                        isset($p['size']) ? Units::bytes((float)$p['size']) : ''], 'muted' => false,                    'sort' => [sprintf('%s%04d', $host === $master ? '0' : '1', count($rows))]];            }        }        $actions = [['id' => 'updates.check', 'text' => 'Check for Updates', 'style' => 'primary']];        if ($kind === 'host') {            $actions[] = ['id' => 'updates.install', 'text' => 'Install Updates…', 'enabled' => $total > 0 && !Updates::of($c, $ref)->installing];            if ($reboots !== []) {                $actions[] = ['id' => 'host.reboot', 'text' => 'Reboot Now', 'enabled' => $c->cache->vmsOn($ref) === [], 'style' => 'danger'];            }        } else {            $actions[] = ['id' => 'updates.rolling', 'text' => 'Rolling Pool Update…', 'enabled' => $total > 0];        }        return Page::grid([['title' => 'Server / package', 'width' => 2.0], ['title' => 'Version (installed → new)', 'width' => 3.0],            ['title' => 'Description', 'width' => 3.2], ['title' => 'Size', 'width' => 0.8]], $rows, $actions,            'No server: connect first.');    }}