summaryrefslogtreecommitdiffstats
path: root/modules-available/serversetup-bwlp-ipxe/page.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/serversetup-bwlp-ipxe/page.inc.php')
-rw-r--r--modules-available/serversetup-bwlp-ipxe/page.inc.php183
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 {