Anmelden
DE
games/xencenter-xenadmin-xcp-jumphp / src / Feature / Pools / PoolCommands.php · commit fb1b7c9
<?phpnamespace App\Feature\Pools;use App\Model\Cache;use App\Model\Connection;use App\Model\Session;use App\View\Commands;/** * The pool commands of XenCenter's menus: New Pool…, Add Server…, Add to Pool 'X' (a standalone server), Remove Server from Pool, * Make this server the pool master, Connection Addresses…; their confirmations. View\Commands asks here; PoolActions runs them. */final class PoolCommands{    public static function handles(string $id): bool    {        return in_array($id, ['pool.new', 'pool.addServer', 'pool.addresses', 'host.removeFromPool', 'host.designateMaster'], true) || str_starts_with($id, 'pool.joinTo:');    }    /** The connected servers that are no pool (a host alone): what New Pool and Add Server take. @return list<Connection> */    public static function standalone(Session $session, ?Connection $except = null): array    {        return array_values(array_filter($session->connections, fn (Connection $c) => $c !== $except && $c->isConnected() && !$c->cache->isRealPool()));    }    /** Why a server cannot join a pool ('' = it can): XAPI refuses a host with running or suspended VMs. */    public static function cannotJoin(Connection $c): string    {        foreach ($c->cache->vms() as $vm) {            if (in_array($vm['power_state'], ['Running', 'Paused', 'Suspended'], true)) {                return 'it has running or suspended VMs';            }        }        return '';    }    /** @return list<array<string, mixed>|string> the Pool menu of the menu bar */    public static function poolMenu(?Connection $c, string $ref, string $kind): array    {        $session = Session::$current;        $standalone = $session === null ? [] : self::standalone($session);        $pool = $kind === 'pool' && $c !== null;        // a pool selected: its own menu (Add Server…, Connection Addresses… are in it)        return [Commands::item('pool.new', 'New Pool…', $standalone !== [], 'new-pool'), '-',            ...($pool ? Commands::context($c, $ref, 'pool') : [Commands::item('pool.addServer', 'Add Server…', false, 'add-server'),                Commands::item('pool.addresses', 'Connection Addresses…', $c !== null && $c->isConnected() && $kind === 'host')])];    }    /** @return list<array<string, mixed>|string> under XenCenter (the root's right click) */    public static function rootItems(): array    {        $session = Session::$current;        return ['-', Commands::item('pool.new', 'New Pool…', $session !== null && self::standalone($session) !== [], 'new-pool')];    }    /** @return list<array<string, mixed>|string> the pool's right click */    public static function poolItems(?Connection $c): array    {        $session = Session::$current;        return [Commands::item('pool.addServer', 'Add Server…', $c !== null && $session !== null && self::standalone($session, $c) !== [], 'add-server'),            Commands::item('pool.addresses', 'Connection Addresses…'), '-'];    }    /** @return list<array<string, mixed>|string> a server's: in a pool, leave it / lead it; alone, join one of the connected pools */    public static function hostItems(?Connection $c, string $host): array    {        if ($c === null || !$c->isConnected()) {            return [];        }        $items = ['-'];        $master = (string)$c->cache->master();        if (count($c->cache->hosts()) > 1) {            $idle = $c->cache->vmsOn($host) === [];            $items[] = Commands::item('host.designateMaster', 'Make this server the pool master', $host !== $master);            $items[] = Commands::item('host.removeFromPool', 'Remove Server from Pool', $host !== $master && $idle);        } else {            $reason = self::cannotJoin($c);            foreach (Session::$current === null ? [] : Session::$current->connections as $i => $pool) {                if ($pool !== $c && $pool->isConnected() && $pool->cache->isRealPool()) {                    $items[] = Commands::item('pool.joinTo:' . $i, "Add to Pool '" . $pool->name() . "'", $reason === '', 'pool');                }            }        }        $items[] = Commands::item('pool.addresses', 'Connection Addresses…');        return $items;    }    /** The questions XenCenter asks first. */    public static function confirmation(string $command, string $name, ?Cache $cache = null): ?string    {        return match ($command) {            'host.removeFromPool' => "Remove server '$name' from its pool?\n\nIts local storage is destroyed with every virtual disk on it, the VMs stored there are deleted, "                . "and the server reboots as a standalone server with an empty configuration. This cannot be undone.\n\nShared storage, and the VMs on it, stay in the pool.",            'host.designateMaster' => "Make server '$name' the new pool master?\n\nThe pool's management moves to it; XenCenter's connection is cut for a moment while the toolstacks restart.",            default => null,        };    }}