ES
games/xencenter-xenadmin-xcp-jumphp / src / Form / MoveDiskForm.php · commit fb1b7c9
<?phpnamespace App\Form;use App\Feature\Storage\Actions;use App\Feature\Storage\Menus;use App\Gui\Units;use App\Model\Connection;use JumPHP\Gui\Button;use JumPHP\Gui\Form;use JumPHP\Gui\Label;use JumPHP\Gui\ListBox;/** * Move a virtual disk to another SR (Feature\Storage\Actions::moveDisk): its VM running -> VDI.pool_migrate (storage live * migration); halted (or no VM) -> VDI.copy, the VBDs made again on the copy, the original destroyed. The SRs offered: attached, * not ISO, not its own, with room for it. Closes with ['moveDisk' => [vdi, sr]]. * * @property Label $heading * @property Label $where * @property ListBox $sr * @property Label $how * @property Label $error * @property Button $move * @property Button $cancel */final class MoveDiskForm extends Form{    public function __construct(private \App\Model\Session $session)    {        parent::__construct();    }    /** XAPI's answers, events and the console go on while this dialog is open. */    protected function tick(float $dt): void    {        $this->session->tick($dt);    }    private array $params = [];    /** @return array<string, mixed> */    public static function paramsFor(Connection $c, string $vdi): array    {        $cache = $c->cache;        $r = $cache->get($vdi) ?? [];        $size = (float)($r['virtual_size'] ?? 0);        $vm = Actions::vmOfDisk($c, $vdi);        $srs = [];        foreach ($cache->srs() as $ref => $sr) {            $free = (float)$sr['physical_size'] - (float)$sr['physical_utilisation'];            if ($ref === ($r['SR'] ?? '') || ($sr['content_type'] ?? '') === 'iso' || !Menus::managed($cache, $ref) || Menus::attached($cache, $ref) === 0 || $free < $size) {                continue;            }            $srs[] = ['ref' => $ref, 'name' => $cache->name($ref) . ' (' . Units::bytes($free) . ' free)'];        }        $state = $vm === null ? '' : (string)$cache->field($vm, 'power_state', '');        return ['vdi' => $vdi, 'name' => (string)($r['name_label'] ?? ''), 'size' => $size, 'from' => $cache->name((string)($r['SR'] ?? '')), 'srs' => $srs,            'vm' => $vm === null ? '' : $cache->name($vm), 'state' => $state, 'live' => Actions::isLive($c, $vdi)];    }    protected function loaded(array $params = []): void    {        $this->params = $params;        $this->heading->text = "Move '" . ($params['name'] ?? '') . "'";        $this->where->text = Units::bytes((float)($params['size'] ?? 0)) . " on '" . ($params['from'] ?? '') . "'" . (($params['vm'] ?? '') !== '' ? " · VM '{$params['vm']}'" : '');        $this->sr->items = array_column($params['srs'] ?? [], 'name');        $this->sr->selected = ($params['srs'] ?? []) === [] ? -1 : 0;        $this->how->text = !empty($params['live'])            ? 'The VM is running: the disk moves while it works (storage live migration).'            : 'The disk is copied to the new storage repository, the VM is given the copy, then the original is deleted.';        $this->error->text = ($params['srs'] ?? []) === [] ? 'No other storage repository has room for this disk.' : '';        if (in_array($params['state'] ?? '', ['Suspended', 'Paused'], true)) {            $this->error->text = 'The VM is ' . strtolower((string)$params['state']) . ': start it or shut it down first.';        }        $this->move->enabled = $this->error->text === '';    }    public function onMoveClick(mixed $sender = null): void    {        $sr = $this->params['srs'][(int)$this->sr->selected] ?? null;        if ($sr === null || !$this->move->enabled) {            $this->error->text = $this->error->text ?: 'Choose a storage repository.';            return;        }        $this->close(['moveDisk' => ['vdi' => $this->params['vdi'] ?? '', 'sr' => $sr['ref']]]);    }    public function onCancelClick(Button $sender): void    {        $this->close();    }}