[...]], MainForm applies it. * * @property IconBox $icon * @property Label $heading * @property TextBox $name * @property TextBox $description * @property Container $vmPanel * @property TextBox $vcpus * @property TextBox $memory * @property Label $vmNote * @property TextBox $tags * @property \JumPHP\Gui\ComboBox $folder * @property TextBox $newFolder * @property Label $error * @property Button $alerts * @property Button $ok * @property Button $cancel */ final class PropertiesForm 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 */ public static function paramsFor(Connection $c, string $ref, bool $memory = false): array { $r = $c->cache->get($ref) ?? []; $class = (string)$c->cache->classOf($ref); return ['target' => $ref, 'class' => $class, 'icon' => Icons::of($class, $r, $c->cache), 'name' => $c->cache->name($ref), 'description' => (string)($r['name_description'] ?? ''), 'vm' => $class === 'vm', 'halted' => ($r['power_state'] ?? '') === 'Halted', 'vcpus' => (int)($r['VCPUs_at_startup'] ?? 1), 'memory' => (int)round((float)($r['memory_static_max'] ?? 0) / 1048576), 'focusMemory' => $memory] + OrganizeProperties::params($c, $ref); } protected function loaded(array $params = []): void { $this->params = $params; $this->heading->text = "Properties of '" . ($params['name'] ?? '') . "'"; $this->icon->kind = (string)($params['icon'] ?? 'folder'); $this->name->text = (string)($params['name'] ?? ''); $this->description->text = (string)($params['description'] ?? ''); $this->vmPanel->visible = !empty($params['vm']); $this->vcpus->text = (string)($params['vcpus'] ?? 1); $this->memory->text = (string)($params['memory'] ?? 1024); $halted = !empty($params['halted']); $this->vcpus->enabled = $this->memory->enabled = $halted; $this->vmNote->text = $halted ? '' : 'Shut the VM down to change its vCPUs and memory.'; $this->error->text = ''; OrganizeProperties::fill($this, $params); // Tags and Folder $this->alerts->visible = in_array($params['class'] ?? '', ['vm', 'host', 'sr', 'pool'], true); // AlertsForm $this->setFocus(!empty($params['focusMemory']) && $halted ? $this->memory : $this->name); } public function onOkClick(Button $sender): void { $vcpus = (int)$this->vcpus->text; $memory = (int)$this->memory->text; if (trim($this->name->text) === '') { $this->error->text = 'Enter a name.'; return; } if (!empty($this->params['vm']) && !empty($this->params['halted']) && ($vcpus < 1 || $vcpus > 64 || $memory < 256)) { $this->error->text = 'From 1 to 64 vCPUs, and at least 256 MB of memory.'; return; } $this->close(['properties' => ['target' => $this->params['target'], 'name' => trim($this->name->text), 'description' => $this->description->text, 'vcpus' => $vcpus, 'memory' => $memory] + OrganizeProperties::values($this) + $this->params]); } /** XenCenter's Alerts page of the Properties: its own dialog (src/Form/AlertsForm.php), opened by MainForm. */ public function onAlertsClick(Button $sender): void { $this->close(['open' => 'object.alerts', 'target' => $this->params['target'] ?? '']); } public function onCancelClick(Button $sender): void { $this->close(); } /** What changed is sent to XAPI. @param array $p */ public static function apply(Session $session, array $p): void { $ref = (string)$p['target']; $c = $session->connectionOf($ref); if ($c === null) { return; } $class = match ((string)$p['class']) { 'sr' => 'SR', 'vm' => 'VM', default => (string)$p['class']}; if ($p['name'] !== ($c->cache->get($ref)['name_label'] ?? '')) { $c->call("$class.set_name_label", $ref, (string)$p['name']); } if ($p['description'] !== ($c->cache->get($ref)['name_description'] ?? '')) { $c->call("$class.set_name_description", $ref, (string)$p['description']); } OrganizeProperties::apply($c, $ref, $p); if (!empty($p['vm']) && !empty($p['halted'])) { $r = $c->cache->get($ref) ?? []; $bytes = (float)$p['memory'] * 1048576; $steps = []; if (abs($bytes - (float)($r['memory_static_max'] ?? 0)) >= 1048576) { $min = min((float)($r['memory_static_min'] ?? $bytes), $bytes); $steps[] = fn () => $c->run("Changing the memory of '" . $p['name'] . "'", 'VM.set_memory_limits', [$ref, $min, $bytes, $bytes, $bytes], $ref); } $vcpus = (int)$p['vcpus']; if ($vcpus !== (int)($r['VCPUs_at_startup'] ?? 0)) { // the maximum first when it grows, the startup count first when it shrinks $grow = $vcpus > (int)($r['VCPUs_max'] ?? 0); $steps[] = fn () => $grow ? $c->run("Changing the vCPUs of '" . $p['name'] . "'", 'VM.set_VCPUs_max', [$ref, $vcpus], $ref) : $c->run("Changing the vCPUs of '" . $p['name'] . "'", 'VM.set_VCPUs_at_startup', [$ref, $vcpus], $ref); $steps[] = fn () => $grow ? $c->run("Changing the vCPUs of '" . $p['name'] . "'", 'VM.set_VCPUs_at_startup', [$ref, $vcpus], $ref) : $c->run("Changing the vCPUs of '" . $p['name'] . "'", 'VM.set_VCPUs_max', [$ref, $vcpus], $ref); } Chain::run($steps)->then(fn () => null, fn () => null); } } }