diff options
Diffstat (limited to 'modules-available/serversetup-bwlp-ipxe/page.inc.php')
-rw-r--r-- | modules-available/serversetup-bwlp-ipxe/page.inc.php | 183 |
1 files changed, 115 insertions, 68 deletions
diff --git a/modules-available/serversetup-bwlp-ipxe/page.inc.php b/modules-available/serversetup-bwlp-ipxe/page.inc.php index e31814d1..c9260687 100644 --- a/modules-available/serversetup-bwlp-ipxe/page.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/page.inc.php @@ -6,14 +6,13 @@ class Page_ServerSetup extends Page private $addrListTask; private $compileTask = null; private $currentAddress; - private $currentMenu; private $hasIpSet = false; private function getCompileTask() { if ($this->compileTask !== null) return $this->compileTask; - $this->compileTask = Property::get('ipxe-task-id'); + $this->compileTask = Property::get(IPxeBuilder::PROP_IPXE_COMPILE_TASKID); if ($this->compileTask !== false) { $this->compileTask = Taskmanager::status($this->compileTask); if (!Taskmanager::isTask($this->compileTask) || Taskmanager::isFinished($this->compileTask)) { @@ -37,7 +36,10 @@ class Page_ServerSetup extends Page $this->handleGetImage(); } - $this->currentMenu = Property::getBootMenu(); + if (User::hasPermission('edit.address')) { + Taskmanager::submit('IpxeVersion', + ['id' => IPxeBuilder::VERSION_LIST_TASK, 'action' => 'LIST'], true); + } $action = Request::post('action'); @@ -49,9 +51,20 @@ class Page_ServerSetup extends Page if ($action === 'compile') { User::assertPermission("edit.address"); if ($this->getCompileTask() === false) { - Trigger::ipxe(); + $taskId = IPxeBuilder::setIpxeVersion(Request::post('version', false, 'string')); + Trigger::ipxe($taskId); } - Util::redirect('?do=serversetup'); + Util::redirect('?do=serversetup&show=address&sv=1'); + } + if ($action === 'fetch' || $action === 'reset') { + User::assertPermission("edit.address"); + if ($this->getCompileTask() === false) { + $task = Taskmanager::submit('IpxeVersion', ['action' => strtoupper($action)]); + if (Taskmanager::isTask($task)) { + Property::set(IPxeBuilder::PROP_VERSION_SELECT_TASKID, $task['id'], 2); + } + } + Util::redirect('?do=serversetup&show=address&sv=1'); } if ($action === 'ip') { @@ -110,32 +123,33 @@ class Page_ServerSetup extends Page $addr = false; if (User::hasPermission('ipxe.menu.view')) { - Dashboard::addSubmenu('?do=serversetup&show=menu', Dictionary::translate('submenu_menu', true)); + Dashboard::addSubmenu('?do=serversetup&show=menu', Dictionary::translate('submenu_menu')); } if (User::hasPermission('ipxe.bootentry.view')) { - Dashboard::addSubmenu('?do=serversetup&show=bootentry', Dictionary::translate('submenu_bootentry', true)); + Dashboard::addSubmenu('?do=serversetup&show=bootentry', Dictionary::translate('submenu_bootentry')); } if (User::hasPermission('edit.address')) { - Dashboard::addSubmenu('?do=serversetup&show=address', Dictionary::translate('submenu_address', true)); + Dashboard::addSubmenu('?do=serversetup&show=address', Dictionary::translate('submenu_address')); $addr = true; } if (User::hasPermission('download')) { - Dashboard::addSubmenu('?do=serversetup&show=download', Dictionary::translate('submenu_download', true)); + Dashboard::addSubmenu('?do=serversetup&show=download', Dictionary::translate('submenu_download')); } if (User::hasPermission('ipxe.localboot.*')) { - Dashboard::addSubmenu('?do=serversetup&show=localboot', Dictionary::translate('submenu_localboot', true)); + Dashboard::addSubmenu('?do=serversetup&show=localboot', Dictionary::translate('submenu_localboot')); } if (User::hasPermission('ipxe.bootentry.edit')) { - Dashboard::addSubmenu('?do=serversetup&show=import', Dictionary::translate('submenu_import', true)); + Dashboard::addSubmenu('?do=serversetup&show=import', Dictionary::translate('submenu_import')); } if (Request::get('show') === false) { $subs = Dashboard::getSubmenus(); + $sv = Request::get('sv') ? '&sv=' . Request::get('sv') : ''; if (empty($subs)) { User::assertPermission('download'); } elseif ($addr && !preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', Property::getServerIp())) { - Util::redirect('?do=serversetup&show=address'); + Util::redirect('?do=serversetup&show=address' . $sv); } else { - Util::redirect($subs[0]['url']); + Util::redirect($subs[0]['url'] . $sv); } } } @@ -147,15 +161,22 @@ class Page_ServerSetup extends Page $show = Request::get('show'); if (in_array($show, ['menu', 'address', 'download'])) { - $task = $this->getCompileTask(); - if ($task !== false) { + $selectTask = Taskmanager::status(Property::get(IPxeBuilder::PROP_VERSION_SELECT_TASKID)); + $buildTask = $this->getCompileTask(); + if ($buildTask !== false || Taskmanager::isRunning($selectTask) || Request::get('sv')) { + Render::addTemplate('git_task', [ + 'selectTask' => Property::get(IPxeBuilder::PROP_VERSION_SELECT_TASKID), + 'reload' => Taskmanager::isRunning($selectTask), + ]); + } + if ($buildTask !== false) { $files = []; - if ($task['data'] && $task['data']['files']) { - foreach ($task['data']['files'] as $k => $v) { + if ($buildTask['data'] && $buildTask['data']['files']) { + foreach ($buildTask['data']['files'] as $k => $v) { $files[] = ['name' => $k, 'namehyphen' => str_replace(['/', '.'], '-', $k)]; } } - Render::addTemplate('ipxe_update', array('taskid' => $task['id'], 'files' => $files)); + Render::addTemplate('ipxe_update', ['taskid' => $buildTask['id'], 'files' => $files]); } } @@ -198,7 +219,6 @@ class Page_ServerSetup extends Page break; default: Util::redirect('?do=serversetup'); - break; } } @@ -210,20 +230,20 @@ class Page_ServerSetup extends Page }); $files = []; $strings = [ - 'efi' => [Dictionary::translate('dl-efi', true) => 50], - 'pcbios' => [Dictionary::translate('dl-pcbios', true) => 51], - 'usb' => [Dictionary::translate('dl-usb', true) => 80], - 'hd' => [Dictionary::translate('dl-hd', true) => 81], - 'lkrn' => [Dictionary::translate('dl-lkrn', true) => 82], - 'i386' => [Dictionary::translate('dl-i386', true) => 10], - 'x86_64' => [Dictionary::translate('dl-x86_64', true) => 11], - 'ecm' => [Dictionary::translate('dl-usbnic', true) => 60], - 'ncm' => [Dictionary::translate('dl-usbnic', true) => 61], - 'ipxe' => [Dictionary::translate('dl-pcinic', true) => 62], - 'snp' => [Dictionary::translate('dl-snp', true) => 63], + 'efi' => [Dictionary::translate('dl-efi') => 50], + 'pcbios' => [Dictionary::translate('dl-pcbios') => 51], + 'usb' => [Dictionary::translate('dl-usb') => 80], + 'hd' => [Dictionary::translate('dl-hd') => 81], + 'lkrn' => [Dictionary::translate('dl-lkrn') => 82], + 'i386' => [Dictionary::translate('dl-i386') => 10], + 'x86_64' => [Dictionary::translate('dl-x86_64') => 11], + 'ecm' => [Dictionary::translate('dl-usbnic') => 60], + 'ncm' => [Dictionary::translate('dl-usbnic') => 61], + 'ipxe' => [Dictionary::translate('dl-pcinic') => 62], + 'snp' => [Dictionary::translate('dl-snp') => 63], ]; foreach ($list as $file) { - if ($file{0} === '.') + if ($file[0] === '.') continue; if (is_file($file)) { $base = basename($file); @@ -246,7 +266,10 @@ class Page_ServerSetup extends Page Render::addTemplate('download', ['files' => $files]); } - private function makeSelectArray($list, $defaults) + /** + * @return array{EFI: array, PCBIOS: array} + */ + private function makeSelectArray(array $list, array $defaults): array { $ret = ['EFI' => [], 'PCBIOS' => []]; foreach (['PCBIOS', 'EFI'] as $m) { @@ -273,7 +296,7 @@ class Page_ServerSetup extends Page ) m LEFT JOIN serversetup_localboot sl USING (systemmodel) ORDER BY systemmodel'); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { $row['modelesc'] = urlencode($row['systemmodel']); $row['options'] = $this->makeSelectArray(Localboot::BOOT_METHODS, $row); $models[] = $row; @@ -305,7 +328,7 @@ class Page_ServerSetup extends Page GROUP BY be.entryid, be.title"); if (empty($bootentryTable)) { - if (Property::getServerIp() === false || Property::getServerIp() === 'invalid') { + if (Property::getServerIp() === 'invalid') { Message::addError('no-ip-set'); Util::redirect('?do=serversetup&show=address'); } @@ -340,7 +363,7 @@ class Page_ServerSetup extends Page GROUP BY menuid, title ORDER BY title"); $menuTable = []; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { if (empty($row['locations'])) { $locations = []; $row['allowEdit'] = in_array(0, $allowedEdit); @@ -358,7 +381,7 @@ class Page_ServerSetup extends Page )); } - private function hasMenuPermission($menuid, $permission) + private function hasMenuPermission(int $menuid, string $permission): bool { $allowedEditLocations = User::getAllowedLocations($permission); $allowEdit = in_array(0, $allowedEditLocations); @@ -412,7 +435,7 @@ class Page_ServerSetup extends Page LEFT JOIN serversetup_bootentry be USING (entryid) WHERE menuid = :id ORDER BY sortval ASC", compact('id')); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { if ($row['entryid'] === null && $row['refmenuid'] !== null) { $row['entryid'] = 'menu:' . $row['refmenuid']; } @@ -430,7 +453,7 @@ class Page_ServerSetup extends Page foreach ($menu['entrylist'] as &$bootentry) { if (!isset($bootentry['data']) || !isset($bootentry['module'])) continue; - if ($bootentry['module']{0} !== '.') { + if ($bootentry['module'][0] !== '.') { // Hook from other module $bootentry['moduleName'] = Dictionary::translateFileModule($bootentry['module'], 'module', 'module_name'); if (!$bootentry['moduleName']) { @@ -445,7 +468,7 @@ class Page_ServerSetup extends Page if ($k === 'id') continue; $bootentry['otherFields'][] = [ - 'key' => Dictionary::translateFileModule($bootentry['module'], 'module', 'ipxe-' . $k, true), + 'key' => Dictionary::translateFileModule($bootentry['module'], 'module', 'ipxe-' . $k), 'value' => is_bool($v) ? Util::boolToString($v) : $v, ]; } @@ -462,16 +485,16 @@ class Page_ServerSetup extends Page continue; // Naming and agnostic if ($bootentry['data']['arch'] === BootEntry::BIOS) { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_biosOnly', true); + $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_biosOnly'); unset($bootentry['data']['EFI']); } elseif ($bootentry['data']['arch'] === BootEntry::EFI) { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_efiOnly', true); + $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_efiOnly'); unset($bootentry['data']['PCBIOS']); } elseif ($bootentry['data']['arch'] === BootEntry::AGNOSTIC) { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic', true); + $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic'); unset($bootentry['data']['EFI']); } else { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archBoth', true); + $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archBoth'); } foreach ($bootentry['data'] as &$e) { if (isset($e['initRd'])) { @@ -510,14 +533,13 @@ class Page_ServerSetup extends Page Message::addError('invalid-boot-entry', $id); Util::redirect('?do=serversetup'); } - if ($row['module']{0} === '.') { + if ($row['module'] === '.special') { + Message::addError('cannot-edit-special', $id); + Util::redirect('?do=serversetup'); + } + if ($row['module'][0] === '.') { // either script or exec entry - $json = json_decode($row['data'], true); - if (!is_array($json)) { - Message::addError('unknown-bootentry-type', $id); - Util::redirect('?do=serversetup&show=bootentry'); - } - $entry = BootEntry::fromJson($row['module'], $json); + $entry = BootEntry::fromJson($row['module'], $row['data']); if ($entry === null) { Message::addError('unknown-bootentry-type', $id); Util::redirect('?do=serversetup&show=bootentry'); @@ -572,22 +594,42 @@ class Page_ServerSetup extends Page private function showEditAddress() { + $status = IPxeBuilder::getVersionTaskResult(); + $versions = false; + if ($status === null) { + $error = 'Taskmanager down'; + } elseif (!empty($status['versions'])) { + $versions = $status['versions']; + foreach ($versions as &$version) { + if ($version['hash'] === Property::get(IPxeBuilder::PROP_IPXE_HASH)) { + $version['hash_selected'] = 'selected'; + } + $version['date_s'] = date('Y-m-d H:i', $version['date']); + $version['hash_s'] = substr($version['hash'], 0, 7); + } + $error = false; + } else { + $error = $status['error'] ?? 'Unknown error'; + } Render::addTemplate('ipaddress', array( - 'ips' => $this->addrListTask['data']['addresses'], + 'ips' => $this->addrListTask['data']['addresses'] ?? [], 'chooseHintClass' => $this->hasIpSet ? '' : 'alert alert-danger', 'disabled' => ($this->getCompileTask() === false) ? '' : 'disabled', + 'versions' => $versions, + 'error' => $error, + 'lastBuild' => Property::get(IPxeBuilder::PROP_IPXE_BUILDSTRING), )); } // ----------------------------------------------------------------------------------------------- - private function getLocalAddresses() + private function getLocalAddresses(): void { $this->addrListTask = Taskmanager::submit('LocalAddressesList', array()); if ($this->addrListTask === false) { $this->addrListTask['data']['addresses'] = false; - return false; + return; } if (!Taskmanager::isFinished($this->addrListTask)) { // TODO: Async if just displaying @@ -596,12 +638,12 @@ class Page_ServerSetup extends Page if (Taskmanager::isFailed($this->addrListTask) || !isset($this->addrListTask['data']['addresses'])) { $this->addrListTask['data']['addresses'] = false; - return false; + return; } $sortIp = array(); foreach (array_keys($this->addrListTask['data']['addresses']) as $key) { - $item = & $this->addrListTask['data']['addresses'][$key]; + $item =& $this->addrListTask['data']['addresses'][$key]; if (!isset($item['ip']) || !preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $item['ip']) || substr($item['ip'], 0, 4) === '127.') { unset($this->addrListTask['data']['addresses'][$key]); continue; @@ -614,7 +656,6 @@ class Page_ServerSetup extends Page } unset($item); array_multisort($sortIp, SORT_STRING, $this->addrListTask['data']['addresses']); - return true; } private function deleteBootEntry() @@ -757,7 +798,7 @@ class Page_ServerSetup extends Page || $defaultEntryId === null)) { // if still null, use whatever as fallback, in case user didn't select any $defaultEntryId = $newKey; } - $keepIds[] = (int)$newKey; + $keepIds[] = $newKey; if (!empty($entry['plainpass'])) { Database::exec('UPDATE serversetup_menuentry SET md5pass = :md5pass WHERE menuentryid = :id', [ 'md5pass' => IPxe::makeMd5Pass($entry['plainpass'], $newKey), @@ -791,7 +832,7 @@ class Page_ServerSetup extends Page { $newAddress = Request::post('ip', 'none', 'string'); $valid = false; - foreach ($this->addrListTask['data']['addresses'] as $item) { + foreach ($this->addrListTask['data']['addresses'] ?? [] as $item) { if ($item['ip'] !== $newAddress) continue; $valid = true; @@ -832,14 +873,15 @@ class Page_ServerSetup extends Page Message::addError('missing-bootentry-data'); return; } - $module = false; $type = Request::post('type', false, 'string'); - if ($type{0} === '.') { + if ($type[0] === '.') { // Exec or script if ($type === '.exec') { $entry = BootEntry::newStandardBootEntry($data); } elseif ($type === '.script') { $entry = BootEntry::newCustomBootEntry($data); + } else { + $entry = null; } if ($entry === null) { Message::addError('main.empty-field'); @@ -849,7 +891,7 @@ class Page_ServerSetup extends Page } else { // Module hook $hook = Hook::loadSingle($type, 'ipxe-bootentry'); - if ($hook === false) { + if ($hook === null) { Message::addError('unknown-bootentry-type', $type); return; } @@ -883,10 +925,15 @@ class Page_ServerSetup extends Page } else { // Edit existing entry $params['oldid'] = $oldEntryId; - Database::exec('UPDATE serversetup_bootentry SET + // Ignore .special, must never update + $aff = Database::exec("UPDATE serversetup_bootentry SET entryid = If(builtin = 0, :entryid, entryid), title = :title, module = :module, data = :data - WHERE entryid = :oldid', $params); - Message::addSuccess('boot-entry-updated', $newId); + WHERE entryid = :oldid AND module <> '.special'", $params); + if ($aff > 0) { + Message::addSuccess('boot-entry-updated', $newId); + } else { + Message::addWarning('nothing-changed-or-protected', $newId); + } } if (Request::post('next') === 'reload') { Util::redirect('?do=serversetup&show=editbootentry&id=' . $newId); @@ -924,7 +971,7 @@ class Page_ServerSetup extends Page ORDER BY m.title ASC', ['locationid' => $locationId]); $menus = []; $hasDefault = false; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { $eids = explode(',', $row['entries']); $row['default_entry_title'] = $menuEntries[$row['menu_default']] ?? ''; $row['entries'] = []; @@ -1023,7 +1070,7 @@ class Page_ServerSetup extends Page Util::redirect('?do=serversetup&show=import'); } $menu = PxeLinux::parsePxeLinux($content, false); - if (empty($menu->sections)) { + if ($menu === null) { Message::addWarning('import-no-entries'); Util::redirect('?do=serversetup&show=import'); } @@ -1032,8 +1079,8 @@ class Page_ServerSetup extends Page IPxe::importPxeMenuEntries($menu, $foo); Util::redirect('?do=serversetup&show=bootentry'); } else { - $id = IPxe::insertMenu($menu, 'Imported Menu', false, 0, [], []); - if ($id === false) { + $id = IPxe::insertMenu($menu, 'Imported Menu', null, 0, [], []); + if ($id === null) { Message::addError('import-error'); Util::redirect('?do=serversetup&show=import'); } else { |