From c2a6dfb649107ce3ad64162e2bb2c3c7275650fb Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 12 Feb 2019 14:55:12 +0100 Subject: [serversetup*] PXELinux and iPXE side-by-side --- modules-available/serversetup-bwlp/api.inc.php | 254 ------- modules-available/serversetup-bwlp/config.json | 8 - .../serversetup-bwlp/hooks/bootup.inc.php | 11 - .../serversetup-bwlp/hooks/ipxe-update.inc.php | 10 - .../serversetup-bwlp/hooks/main-warning.inc.php | 6 - .../serversetup-bwlp/inc/bootentry.inc.php | 258 ------- .../serversetup-bwlp/inc/ipxe.inc.php | 453 ----------- .../serversetup-bwlp/inc/ipxemenu.inc.php | 142 ---- .../serversetup-bwlp/inc/localboot.inc.php | 15 - .../serversetup-bwlp/inc/menuentry.inc.php | 177 ----- .../serversetup-bwlp/inc/pxelinux.inc.php | 302 -------- modules-available/serversetup-bwlp/install.inc.php | 89 --- .../serversetup-bwlp/lang/de/messages.json | 21 - .../serversetup-bwlp/lang/de/module.json | 19 - .../serversetup-bwlp/lang/de/permissions.json | 12 - .../serversetup-bwlp/lang/de/template-tags.json | 94 --- .../serversetup-bwlp/lang/en/messages.json | 5 - .../serversetup-bwlp/lang/en/module.json | 3 - .../serversetup-bwlp/lang/en/permissions.json | 6 - .../serversetup-bwlp/lang/en/template-tags.json | 42 -- .../serversetup-bwlp/lang/pt/messages.json | 3 - .../serversetup-bwlp/lang/pt/module.json | 3 - .../serversetup-bwlp/lang/pt/template-tags.json | 38 - modules-available/serversetup-bwlp/page.inc.php | 829 --------------------- .../serversetup-bwlp/permissions/permissions.json | 29 - .../serversetup-bwlp/templates/bootentry-list.html | 83 --- .../serversetup-bwlp/templates/download.html | 53 -- .../serversetup-bwlp/templates/heading.html | 3 - .../serversetup-bwlp/templates/ipaddress.html | 44 -- .../templates/ipxe-new-boot-entry.html | 165 ---- .../serversetup-bwlp/templates/ipxe_update.html | 54 -- .../serversetup-bwlp/templates/localboot.html | 59 -- .../templates/menu-assign-location.html | 69 -- .../serversetup-bwlp/templates/menu-edit.html | 368 --------- .../serversetup-bwlp/templates/menu-list.html | 100 --- 35 files changed, 3827 deletions(-) delete mode 100644 modules-available/serversetup-bwlp/api.inc.php delete mode 100644 modules-available/serversetup-bwlp/config.json delete mode 100644 modules-available/serversetup-bwlp/hooks/bootup.inc.php delete mode 100644 modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php delete mode 100644 modules-available/serversetup-bwlp/hooks/main-warning.inc.php delete mode 100644 modules-available/serversetup-bwlp/inc/bootentry.inc.php delete mode 100644 modules-available/serversetup-bwlp/inc/ipxe.inc.php delete mode 100644 modules-available/serversetup-bwlp/inc/ipxemenu.inc.php delete mode 100644 modules-available/serversetup-bwlp/inc/localboot.inc.php delete mode 100644 modules-available/serversetup-bwlp/inc/menuentry.inc.php delete mode 100644 modules-available/serversetup-bwlp/inc/pxelinux.inc.php delete mode 100644 modules-available/serversetup-bwlp/install.inc.php delete mode 100644 modules-available/serversetup-bwlp/lang/de/messages.json delete mode 100644 modules-available/serversetup-bwlp/lang/de/module.json delete mode 100644 modules-available/serversetup-bwlp/lang/de/permissions.json delete mode 100644 modules-available/serversetup-bwlp/lang/de/template-tags.json delete mode 100644 modules-available/serversetup-bwlp/lang/en/messages.json delete mode 100644 modules-available/serversetup-bwlp/lang/en/module.json delete mode 100644 modules-available/serversetup-bwlp/lang/en/permissions.json delete mode 100644 modules-available/serversetup-bwlp/lang/en/template-tags.json delete mode 100644 modules-available/serversetup-bwlp/lang/pt/messages.json delete mode 100644 modules-available/serversetup-bwlp/lang/pt/module.json delete mode 100644 modules-available/serversetup-bwlp/lang/pt/template-tags.json delete mode 100644 modules-available/serversetup-bwlp/page.inc.php delete mode 100644 modules-available/serversetup-bwlp/permissions/permissions.json delete mode 100644 modules-available/serversetup-bwlp/templates/bootentry-list.html delete mode 100644 modules-available/serversetup-bwlp/templates/download.html delete mode 100644 modules-available/serversetup-bwlp/templates/heading.html delete mode 100644 modules-available/serversetup-bwlp/templates/ipaddress.html delete mode 100644 modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html delete mode 100644 modules-available/serversetup-bwlp/templates/ipxe_update.html delete mode 100644 modules-available/serversetup-bwlp/templates/localboot.html delete mode 100644 modules-available/serversetup-bwlp/templates/menu-assign-location.html delete mode 100644 modules-available/serversetup-bwlp/templates/menu-edit.html delete mode 100644 modules-available/serversetup-bwlp/templates/menu-list.html (limited to 'modules-available/serversetup-bwlp') diff --git a/modules-available/serversetup-bwlp/api.inc.php b/modules-available/serversetup-bwlp/api.inc.php deleted file mode 100644 index 1df0e6e7..00000000 --- a/modules-available/serversetup-bwlp/api.inc.php +++ /dev/null @@ -1,254 +0,0 @@ - $v) { - $query .= $k . '=' . $v . '&'; - } - //$query = substr($query, 0, -1); - echo << $uuid]); - if ($row !== false && !empty($row['systemmodel'])) { - $model = $row['systemmodel']; - } -} -if ($model === false) { - // Otherwise use what iPXE sent us - function modfilt($str) - { - if (empty($str) || preg_match('/product\s+name|be\s+filled|unknown|default\s+string/i', $str)) - return false; - return trim(preg_replace('/\s+/', ' ', $str)); - } - $manuf = modfilt($manuf); - $product = modfilt($product); - if (!empty($product)) { - $model = $product; - if (!empty($manuf)) { - $model .= " ($manuf)"; - } - } -} -// Query -if ($model !== false) { - $row = Database::queryFirst("SELECT bootmethod FROM serversetup_localboot WHERE systemmodel = :model LIMIT 1", - ['model' => $model]); - if ($row !== false) { - $localboot = $row['bootmethod']; - } -} -if ($localboot === false || !isset($BOOT_METHODS[$localboot])) { - $localboot = Property::get(Localboot::PROPERTY_KEY, 'AUTO'); - if (!isset($BOOT_METHODS[$localboot])) { - $localboot = 'AUTO'; - } -} -if (isset($BOOT_METHODS[$localboot])) { - // Move preferred method first - $BOOT_METHODS[] = $BOOT_METHODS[$localboot]; - unset($BOOT_METHODS[$localboot]); - $BOOT_METHODS = array_reverse($BOOT_METHODS); -} - -if ($slxExtensions) { - $slxConsoleUpdate = '--update'; -} else { - $slxConsoleUpdate = ''; -} - -$output = <<getMenuDefinition('target', $platform, $slxExtensions); - -$output .= <<getItemsCode($platform); - -/* - -:i5 -chain -a /tftp/memtest.0 passes=1 onepass || goto membad -prompt Memory OK. Press a key. -goto init - -:i8 -set x:int32 0 -:again -console --left 60 --top 130 --right 67 --bottom 96 --picture bg-load --keep || -console --left 55 --top 88 --right 63 --bottom 64 --picture bg-menu --keep || -inc x -iseq \${x} 20 || goto again -prompt DONE. Press dein Knie. -goto slx_menu - -:membad -iseq \${errno} 0x1 || goto memaborted -params -param scrot \${vram} -imgfetch -a http://132.230.8.113/screen.php##params || -prompt Memory is bad. Press a key. -goto init - -:memaborted -params -param scrot \${vram} -imgfetch -a http://132.230.8.113/screen.php##params || -prompt Memory test aborted. Press a key. -goto init - -*/ - -$output .= << 0) { - EventLog::info('Imported old PXELinux menu, with ' . $num . ' additional IP-range based menus.'); - } else { - EventLog::info('Imported old PXELinux menu.'); - } -} diff --git a/modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php b/modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php deleted file mode 100644 index 166e80a8..00000000 --- a/modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php +++ /dev/null @@ -1,10 +0,0 @@ - Property::getServerIp() -]; -$task = Taskmanager::submit('CompileIPxeNew', $data); -if (!isset($task['id'])) -return false; -Property::set('ipxe-task-id', $task['id'], 15); -return $task['id']; \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/hooks/main-warning.inc.php b/modules-available/serversetup-bwlp/hooks/main-warning.inc.php deleted file mode 100644 index a2eba6ff..00000000 --- a/modules-available/serversetup-bwlp/hooks/main-warning.inc.php +++ /dev/null @@ -1,6 +0,0 @@ - $value) { - if (property_exists($this, $key)) { - $this->{$key} = $value; - } - } - } - } - - public abstract function supportsMode($mode); - - public abstract function toScript($failLabel, $mode); - - public abstract function toArray(); - - public abstract function addFormFields(&$array); - - /* - * - */ - - /** - * Return a BootEntry instance from the serialized data. - * - * @param string $jsonString serialized entry data - * @return BootEntry|null instance representing boot entry, null on error - */ - public static function fromJson($data) - { - if (is_string($data)) { - $data = json_decode($data, true); - } - if (isset($data['script'])) { - return new CustomBootEntry($data); - } - if (isset($data['executable'])) { - return new StandardBootEntry($data); - } - return null; - } - - public static function newStandardBootEntry($initData) - { - $ret = new StandardBootEntry($initData); - $list = []; - if ($ret->arch() !== StandardBootEntry::EFI) { - $list[] = StandardBootEntry::BIOS; - } - if ($ret->arch() === StandardBootEntry::EFI || $ret->arch() === StandardBootEntry::BOTH) { - $list[] = StandardBootEntry::EFI; - } - foreach ($list as $mode) { - if (empty($initData['executable'][$mode])) - return null; - } - return $ret; - } - - public static function newCustomBootEntry($initData) - { - if (empty($initData['script'])) - return null; - return new CustomBootEntry($initData); - } - - /** - * Return a BootEntry instance from database with the given id. - * - * @param string $id - * @return BootEntry|null|false false == unknown id, null = unknown entry type, BootEntry instance on success - */ - public static function fromDatabaseId($id) - { - $row = Database::queryFirst("SELECT data FROM serversetup_bootentry - WHERE entryid = :id LIMIT 1", ['id' => $id]); - if ($row === false) - return false; - return self::fromJson($row['data']); - } - -} - -class StandardBootEntry extends BootEntry -{ - protected $executable; - protected $initRd; - protected $commandLine; - protected $replace; - protected $autoUnload; - protected $resetConsole; - protected $arch; // Constants below - - const BIOS = 'PCBIOS'; // Only valid for legacy BIOS boot - const EFI = 'EFI'; // Only valid for EFI boot - const BOTH = 'PCBIOS-EFI'; // Supports both via distinct entry - const AGNOSTIC = 'agnostic'; // Supports both via same entry (PCBIOS entry) - - public function __construct($data = false) - { - if ($data instanceof PxeSection) { - // Gets arrayfied below - $this->executable = $data->kernel; - $this->initRd = $data->initrd; - $this->commandLine = ' ' . str_replace('vga=current', '', $data->append) . ' '; - $this->resetConsole = true; - $this->replace = true; - $this->autoUnload = true; - if (strpos($this->commandLine, ' quiet ') !== false) { - $this->commandLine .= ' loglevel=5 rd.systemd.show_status=auto'; - } - if ($data->ipAppend & 1) { - $this->commandLine .= ' ${ipappend1}'; - } - if ($data->ipAppend & 2) { - $this->commandLine .= ' ${ipappend2}'; - } - if ($data->ipAppend & 4) { - $this->commandLine .= ' SYSUUID=${uuid}'; - } - $this->commandLine = trim(preg_replace('/\s+/', ' ', $this->commandLine)); - } else { - parent::__construct($data); - } - // Convert legacy DB format - foreach (['executable', 'initRd', 'commandLine', 'replace', 'autoUnload', 'resetConsole'] as $key) { - if (!is_array($this->{$key})) { - $this->{$key} = [ 'PCBIOS' => $this->{$key}, 'EFI' => '' ]; - } - } - if ($this->arch === null) { - $this->arch = self::AGNOSTIC; - } - } - - public function arch() - { - return $this->arch; - } - - public function supportsMode($mode) - { - if ($mode === $this->arch || $this->arch === self::AGNOSTIC) - return true; - if ($mode === self::BIOS || $mode === self::EFI) { - return $this->arch === self::BOTH; - } - error_log('Unknown iPXE platform: ' . $mode); - return false; - } - - public function toScript($failLabel, $mode) - { - if (!$this->supportsMode($mode)) { - return "prompt Entry doesn't have an executable for mode $mode\n"; - } - if ($this->arch === self::AGNOSTIC) { - $mode = self::BIOS; - } - - $script = ''; - if ($this->resetConsole[$mode]) { - $script .= "console ||\n"; - } - if (!empty($this->initRd[$mode])) { - $script .= "imgfree ||\n"; - if (!is_array($this->initRd[$mode])) { - $script .= "initrd {$this->initRd[$mode]} || goto $failLabel\n"; - } else { - foreach ($this->initRd[$mode] as $initrd) { - $script .= "initrd $initrd || goto $failLabel\n"; - } - } - } - $script .= "boot "; - if ($this->autoUnload[$mode]) { - $script .= "-a "; - } - if ($this->replace[$mode]) { - $script .= "-r "; - } - $script .= $this->executable[$mode]; - $rdBase = basename($this->initRd[$mode]); - if (!empty($this->commandLine[$mode])) { - $script .= " initrd=$rdBase {$this->commandLine[$mode]}"; - } - $script .= " || goto $failLabel\n"; - if ($this->resetConsole[$mode]) { - $script .= "goto start ||\n"; - } - return $script; - } - - public function addFormFields(&$array) - { - $array[$this->arch . '_selected'] = 'selected'; - foreach ([self::BIOS, self::EFI] as $mode) { - $array['entries'][] = [ - 'is' . $mode => true, - 'mode' => $mode, - 'executable' => $this->executable[$mode], - 'initRd' => $this->initRd[$mode], - 'commandLine' => $this->commandLine[$mode], - 'replace_checked' => $this->replace[$mode] ? 'checked' : '', - 'autoUnload_checked' => $this->autoUnload[$mode] ? 'checked' : '', - 'resetConsole_checked' => $this->resetConsole[$mode] ? 'checked' : '', - ]; - } - $array['exec_checked'] = 'checked'; - } - - public function toArray() - { - return [ - 'executable' => $this->executable, - 'initRd' => $this->initRd, - 'commandLine' => $this->commandLine, - 'replace' => $this->replace, - 'autoUnload' => $this->autoUnload, - 'resetConsole' => $this->resetConsole, - 'arch' => $this->arch, - ]; - } -} - -class CustomBootEntry extends BootEntry -{ - protected $script; - - public function supportsMode($mode) - { - return true; - } - - public function toScript($failLabel, $mode) - { - return str_replace('%fail%', $failLabel, $this->script) . "\n"; - } - - public function addFormFields(&$array) - { - $array['entry'] = [ - 'script' => $this->script, - ]; - $array['script_checked'] = 'checked'; - } - - public function toArray() - { - return ['script' => $this->script]; - } -} diff --git a/modules-available/serversetup-bwlp/inc/ipxe.inc.php b/modules-available/serversetup-bwlp/inc/ipxe.inc.php deleted file mode 100644 index d34839f0..00000000 --- a/modules-available/serversetup-bwlp/inc/ipxe.inc.php +++ /dev/null @@ -1,453 +0,0 @@ -= :start AND endaddr <= :end", compact('start', 'end')); - $locations = []; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - foreach ($locations as &$loc) { - if ($row['startaddr'] <= $loc['startaddr'] && $row['endaddr'] >= $loc['endaddr']) { - $loc = false; - } elseif ($row['startaddr'] >= $loc['startaddr'] && $row['endaddr'] <= $loc['endaddr']) { - continue 2; - } - } - unset($loc); - $locations[] = $row; - } - $menu = PxeLinux::parsePxeLinux($content); - $key = $menu->hash(true); - if (isset($menus[$key])) { - $menuId = $menus[$key]; - $defId = null; - // Figure out the default label, get it's label name - foreach ($menu->sections as $section) { - if ($section->isDefault) { - $defId = $section; - } elseif ($defId === null && $section->label === $menu->timeoutLabel) { - $defId = $section; - } - } - if ($defId !== null) { - $defId = self::cleanLabelFixLocal($defId); - // Confirm it actually exists (it should since the menu seems identical) and get menuEntryId - $me = Database::queryFirst('SELECT m.defaultentryid, me.menuentryid FROM serversetup_bootentry be - INNER JOIN serversetup_menuentry me ON (be.entryid = me.entryid) - INNER JOIN serversetup_menu m ON (m.menuid = me.menuid) - WHERE be.entryid = :id AND me.menuid = :menuid', - ['id' => $defId, 'menuid' => $menuId]); - if ($me === false || $me['defaultentryid'] == $me['menuentryid']) { - $defId = null; // Not found, or is already default - don't override if it's the same - } else { - $defId = $me['menuentryid']; - } - } - } else { - $menuId = self::insertMenu($menu, 'Imported', false, 0, [], []); - $menus[$key] = $menuId; - $defId = null; - $importCount++; - } - if ($menuId === false) - continue; - foreach ($locations as $loc) { - if ($loc === false) - continue; - Database::exec('INSERT IGNORE INTO serversetup_menu_location (menuid, locationid, defaultentryid) - VALUES (:menuid, :locationid, :def)', [ - 'menuid' => $menuId, - 'locationid' => $loc['locationid'], - 'def' => $defId, - ]); - } - } - return $importCount; - } - - public static function importLegacyMenu($force = false) - { - if (!$force && false !== Database::queryFirst("SELECT entryid FROM serversetup_bootentry WHERE entryid = 'bwlp-default'")) - return false; // Already exists - // Now create the default entry - self::createDefaultEntries(); - $prepend = ['bwlp-default' => false, 'localboot' => false]; - $defaultLabel = 'bwlp-default'; - $menuTitle = 'bwLehrpool Bootauswahl'; - $pxeConfig = ''; - $timeoutSecs = 60; - // Try to import any customization - $oldMenu = Property::getBootMenu(); - if (is_array($oldMenu)) { - // - if (isset($oldMenu['timeout'])) { - $timeoutSecs = (int)$oldMenu['timeout']; - } - if (isset($oldMenu['defaultentry'])) { - if ($oldMenu['defaultentry'] === 'net') { - $defaultLabel = 'bwlp-default'; - } elseif ($oldMenu['defaultentry'] === 'hdd') { - $defaultLabel = 'localboot'; - } elseif ($oldMenu['defaultentry'] === 'custom') { - $defaultLabel = 'custom'; - } - } - if (!empty($oldMenu['custom'])) { - $pxeConfig = $oldMenu['custom']; - } - } - $append = [ - '', - 'bwlp-default-dbg' => false, - '', - 'poweroff' => false, - ]; - return self::insertMenu(PxeLinux::parsePxeLinux($pxeConfig), $menuTitle, $defaultLabel, $timeoutSecs, $prepend, $append); - } - - /** - * @param PxeMenu $pxeMenu - * @param string $menuTitle - * @param string|false $defaultLabel - * @param $defaultTimeoutSeconds - * @param $prepend - * @param $append - * @return bool|int - */ - private static function insertMenu($pxeMenu, $menuTitle, $defaultLabel, $defaultTimeoutSeconds, $prepend, $append) - { - $timeoutMs = []; - $menuEntries = $prepend; - settype($menuEntries, 'array'); - if (!empty($pxeMenu)) { - $pxe =& $pxeMenu; - if (!empty($pxe->title)) { - $menuTitle = $pxe->title; - } - if ($pxe->timeoutLabel !== null) { - $defaultLabel = $pxe->timeoutLabel; - } - $timeoutMs[] = $pxe->timeoutMs; - $timeoutMs[] = $pxe->totalTimeoutMs; - foreach ($pxe->sections as $section) { - if ($section->localBoot || preg_match('/chain\.c32$/i', $section->kernel)) { - $menuEntries['localboot'] = 'localboot'; - continue; - } - if ($section->label === null) { - if (!$section->isHidden && !empty($section->title)) { - $menuEntries[] = $section->title; - } - continue; - } - if (empty($section->kernel)) { - if (!$section->isHidden && !empty($section->title)) { - $menuEntries[] = $section->title; - } - continue; - } - $entry = self::pxe2BootEntry($section); - if ($entry === null) - continue; - $label = self::cleanLabelFixLocal($section); - if ($defaultLabel === $section->label) { - $defaultLabel = $label; - } - $hotkey = MenuEntry::filterKeyName($section->hotkey); - // Create boot entry - $data = $entry->toArray(); - Database::exec('INSERT IGNORE INTO serversetup_bootentry (entryid, hotkey, title, builtin, data) - VALUES (:label, :hotkey, :title, 0, :data)', [ - 'label' => $label, - 'hotkey' => $hotkey, - 'title' => self::sanitizeIpxeString($section->title), - 'data' => json_encode($data), - ]); - $menuEntries[$label] = $section; - } - } - if (is_array($append)) { - $menuEntries += $append; - } - if (empty($menuEntries)) - return false; - // Make menu - $timeoutMs = array_filter($timeoutMs, 'is_int'); - if (empty($timeoutMs)) { - $timeoutMs = (int)($defaultTimeoutSeconds * 1000); - } else { - $timeoutMs = min($timeoutMs); - } - $isDefault = (int)(Database::queryFirst('SELECT menuid FROM serversetup_menu WHERE isdefault = 1') === false); - Database::exec("INSERT INTO serversetup_menu (timeoutms, title, defaultentryid, isdefault) - VALUES (:timeoutms, :title, NULL, :isdefault)", [ - 'title' => self::sanitizeIpxeString($menuTitle), - 'timeoutms' => $timeoutMs, - 'isdefault' => $isDefault, - ]); - $menuId = Database::lastInsertId(); - if (!array_key_exists($defaultLabel, $menuEntries) && $timeoutMs > 0) { - $defaultLabel = array_keys($menuEntries)[0]; - } - // Link boot entries to menu - $defaultEntryId = null; - $order = 1000; - foreach ($menuEntries as $label => $entry) { - if (is_string($entry)) { - // Gap entry - Database::exec("INSERT INTO serversetup_menuentry - (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass) - VALUES (:menuid, :entryid, :hotkey, :title, :hidden, :sortval, '', '')", [ - 'menuid' => $menuId, - 'entryid' => null, - 'hotkey' => '', - 'title' => self::sanitizeIpxeString($entry), - 'hidden' => 0, - 'sortval' => $order += 100, - ]); - continue; - } - $data = Database::queryFirst("SELECT entryid, hotkey, title FROM serversetup_bootentry WHERE entryid = :entryid", ['entryid' => $label]); - if ($data === false) - continue; - $data['pass'] = ''; - $data['hidden'] = 0; - if ($entry instanceof PxeSection) { - $data['hidden'] = (int)$entry->isHidden; - // Prefer explicit data from this imported menu over the defaults - $data['title'] = self::sanitizeIpxeString($entry->title); - if (MenuEntry::getKeyCode($entry->hotkey) !== false) { - $data['hotkey'] = $entry->hotkey; - } - if (!empty($entry->passwd)) { - // Most likely it's a hash so we cannot recover; ask people to reset - $data['pass'] ='please_reset'; - } - } - $data['menuid'] = $menuId; - $data['sortval'] = $order += 100; - $res = Database::exec("INSERT INTO serversetup_menuentry - (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass) - VALUES (:menuid, :entryid, :hotkey, :title, :hidden, :sortval, :pass, :pass)", $data); - if ($res !== false && $label === $defaultLabel) { - $defaultEntryId = Database::lastInsertId(); - } - } - // Now we can set default entry - if (!empty($defaultEntryId)) { - Database::exec("UPDATE serversetup_menu SET defaultentryid = :entryid WHERE menuid = :menuid", - ['menuid' => $menuId, 'entryid' => $defaultEntryId]); - } - // TODO: masterpw? rather pointless.... - //$oldMenu['masterpasswordclear']; - return $menuId; - } - - private static function createDefaultEntries() - { - $query = 'INSERT IGNORE INTO serversetup_bootentry (entryid, hotkey, title, builtin, data) - VALUES (:entryid, :hotkey, :title, 1, :data)'; - Database::exec($query, - [ - 'entryid' => 'bwlp-default', - 'hotkey' => 'B', - 'title' => 'bwLehrpool-Umgebung starten', - 'data' => json_encode([ - 'executable' => '/boot/default/kernel', - 'initRd' => '/boot/default/initramfs-stage31', - 'commandLine' => 'slxbase=boot/default quiet splash loglevel=5 rd.systemd.show_status=auto intel_iommu=igfx_off ${ipappend1} ${ipappend2}', - 'replace' => true, - 'autoUnload' => true, - 'resetConsole' => true, - ]), - ]); - Database::exec($query, - [ - 'entryid' => 'bwlp-default-dbg', - 'hotkey' => '', - 'title' => 'bwLehrpool-Umgebung starten (nosplash, debug)', - 'data' => json_encode([ - 'executable' => '/boot/default/kernel', - 'initRd' => '/boot/default/initramfs-stage31', - 'commandLine' => 'slxbase=boot/default loglevel=7 intel_iommu=igfx_off ${ipappend1} ${ipappend2}', - 'replace' => true, - 'autoUnload' => true, - 'resetConsole' => true, - ]), - ]); - Database::exec($query, - [ - 'entryid' => 'localboot', - 'hotkey' => 'L', - 'title' => 'Lokales System starten', - 'data' => json_encode([ - 'script' => 'goto slx_localboot || goto %fail% ||', - ]), - ]); - Database::exec($query, - [ - 'entryid' => 'poweroff', - 'hotkey' => 'P', - 'title' => 'Power off', - 'data' => json_encode([ - 'script' => 'poweroff || goto %fail% ||', - ]), - ]); - Database::exec($query, - [ - 'entryid' => 'reboot', - 'hotkey' => 'R', - 'title' => 'Reboot', - 'data' => json_encode([ - 'script' => 'reboot || goto %fail% ||', - ]), - ]); - } - - /** - * Create unique label for a boot entry. It will try to figure out whether - * this is one of our default entries and if not, create a unique label - * representing the menu entry contents. - * Also it patches the entry if it's referencing the local bwlp install - * because side effects. - * - * @param PxeSection $section - * @return string - */ - private static function cleanLabelFixLocal($section) - { - $myip = Property::getServerIp(); - // Detect our "old" entry types - if (count($section->initrd) === 1 && preg_match(",$myip/boot/default/kernel\$,", $section->kernel) - && preg_match(",$myip/boot/default/initramfs-stage31\$,", $section->initrd[0])) { - // Kernel and initrd match, examine KCL - if ($section->append === 'slxbase=boot/default vga=current quiet splash') { - // Normal - return 'bwlp-default'; - } elseif ($section->append === 'slxbase=boot/default') { - // Debug output - return 'bwlp-default-dbg'; - } else { - // Transform to relative URL, leave KCL, fall through to generic label gen - $section->kernel = '/boot/default/kernel'; - $section->initrd = ['/boot/default/initramfs-stage31']; - } - } - // Generic -- "smart" hash of kernel, initrd and command line - $str = $section->kernel . ' ' . implode(',', $section->initrd); - $array = preg_split('/\s+/', $section->append, -1, PREG_SPLIT_NO_EMPTY); - sort($array); - $str .= ' ' . implode(' ', $array); - - return 'i-' . substr(md5($str), 0, 12); - } - - /** - * @param PxeSection $section - * @return BootEntry|null The according boot entry, null if it's unparsable - */ - private static function pxe2BootEntry($section) - { - if (preg_match('/(pxechain\.com|pxechn\.c32)$/i', $section->kernel)) { - // Chaining -- create script - $args = preg_split('/\s+/', $section->append); - $script = ''; - $file = false; - for ($i = 0; $i < count($args); ++$i) { - $arg = $args[$i]; - if ($arg === '-c') { // PXELINUX config file option - ++$i; - $script .= "set 209:string {$args[$i]} || goto %fail%\n"; - } elseif ($arg === '-p') { // PXELINUX prefix path option - ++$i; - $script .= "set 210:string {$args[$i]} || goto %fail%\n"; - } elseif ($arg === '-t') { // PXELINUX timeout option - ++$i; - $script .= "set 211:int32 {$args[$i]} || goto %fail%\n"; - } elseif ($arg === '-o') { // Overriding various DHCP options - ++$i; - if (preg_match('/^((?:0x)?[a-f0-9]{1,4})\.([bwlsh])=(.*)$/i', $args[$i], $out)) { - // TODO: 'q' (8byte) unsupported for now - $opt = intval($out[1], 0); - if ($opt > 0 && $opt < 255) { - static $optType = ['b' => 'uint8', 'w' => 'uint16', 'l' => 'int32', 's' => 'string', 'h' => 'hex']; - $type = $optType[$out[2]]; - $script .= "set {$opt}:{$type} {$args[$i]} || goto %fail%\n"; - } - } - } elseif ($arg{0} === '-') { - continue; - } elseif ($file === false) { - $file = self::parseFile($arg); - } - } - if ($file !== false) { - $url = parse_url($file); - if (isset($url['host'])) { - $script .= "set next-server {$url['host']} || goto %fail%\n"; - } - if (isset($url['path'])) { - $script .= "set filename {$url['path']} || goto %fail%\n"; - } - $script .= "chain -ar {$file} || goto %fail%\n"; - return new CustomBootEntry(['script' => $script]); - } - return null; - } - // "Normal" entry that should be convertible into a StandardBootEntry - $section->kernel = self::parseFile($section->kernel); - foreach ($section->initrd as &$initrd) { - $initrd = self::parseFile($initrd); - } - return BootEntry::newStandardBootEntry($section); - } - - /** - * Parse PXELINUX file notion. Basically, turn - * server::file into tftp://server/file. - * - * @param string $file - * @return string - */ - private static function parseFile($file) - { - if (preg_match(',^([^:/]+)::(.*)$,', $file, $out)) { - return 'tftp://' . $out[1] . '/' . $out[2]; - } - return $file; - } - - public static function sanitizeIpxeString($string) - { - return str_replace(['&', '|', ';', '$', "\r", "\n"], ['+', '/', ':', 'S', ' ', ' '], $string); - } - - public static function makeMd5Pass($plainpass, $salt) - { - if (empty($plainpass)) - return ''; - return md5(md5($plainpass) . '-' . $salt); - } - -} diff --git a/modules-available/serversetup-bwlp/inc/ipxemenu.inc.php b/modules-available/serversetup-bwlp/inc/ipxemenu.inc.php deleted file mode 100644 index 5c1a87d5..00000000 --- a/modules-available/serversetup-bwlp/inc/ipxemenu.inc.php +++ /dev/null @@ -1,142 +0,0 @@ - $menu]); - if (!is_array($menu)) { - $menu = ['menuid' => 'foo', 'title' => 'Invalid Menu ID: ' . (int)$menu]; - } - } - $this->menuid = (int)$menu['menuid']; - $this->timeoutMs = (int)$menu['timeoutms']; - $this->title = $menu['title']; - $this->defaultEntryId = $menu['defaultentryid']; - $res = Database::simpleQuery("SELECT e.menuentryid, e.entryid, e.hotkey, e.title, e.hidden, e.sortval, e.md5pass, - b.data AS bootentry - FROM serversetup_menuentry e - LEFT JOIN serversetup_bootentry b USING (entryid) - WHERE e.menuid = :menuid - ORDER BY e.sortval ASC, e.title ASC", ['menuid' => $menu['menuid']]); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $this->items[] = new MenuEntry($row); - } - } - - public function getMenuDefinition($targetVar, $mode, $slxExtensions) - { - $str = "menu -- {$this->title}\n"; - foreach ($this->items as $item) { - $str .= $item->getMenuItemScript("m_{$this->menuid}", $this->defaultEntryId, $mode, $slxExtensions); - } - if ($this->defaultEntryId === null) { - $defaultLabel = "mx_{$this->menuid}_poweroff"; - } else { - $defaultLabel = "m_{$this->menuid}_{$this->defaultEntryId}"; - } - $str .= "choose"; - if ($this->timeoutMs > 0) { - $str .= " --timeout {$this->timeoutMs}"; - } - $str .= " $targetVar || goto $defaultLabel || goto fail\n"; - if ($this->defaultEntryId === null) { - $str .= "goto skip_{$defaultLabel}\n" - . ":{$defaultLabel}\n" - . "poweroff || goto fail\n" - . ":skip_{$defaultLabel}\n"; - } - return $str; - } - - public function getItemsCode($mode) - { - $str = ''; - foreach ($this->items as $item) { - $str .= $item->getBootEntryScript("m_{$this->menuid}", 'fail', $mode); - $str .= "goto slx_menu\n"; - } - return $str; - } - - /* - * - */ - - public static function forLocation($locationId) - { - $chain = null; - if (Module::isAvailable('location')) { - $chain = Location::getLocationRootChain($locationId); - } - if (!empty($chain)) { - $res = Database::simpleQuery("SELECT m.menuid, m.timeoutms, m.title, IFNULL(ml.defaultentryid, m.defaultentryid) AS defaultentryid, ml.locationid - FROM serversetup_menu m - INNER JOIN serversetup_menu_location ml USING (menuid) - WHERE ml.locationid IN (:chain)", ['chain' => $chain]); - if ($res->rowCount() > 0) { - // Make the location id key, preserving order (closest location is first) - $chain = array_flip($chain); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - // Overwrite the value (numeric ascending values, useless) with menu array of according location - $chain[(int)$row['locationid']] = $row; - } - // Use first one that was found - foreach ($chain as $menu) { - if (is_array($menu)) { - return new IPxeMenu($menu); - } - } - // Should never end up here, but we'd just fall through and use the default - } - } - // We're here, no specific menu, use default - $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid - FROM serversetup_menu - ORDER BY isdefault DESC LIMIT 1"); - if ($menu === false) { - return new EmptyIPxeMenu; - } - return new IPxeMenu($menu); - } - - public static function forClient($ip, $uuid) - { - $locationId = 0; - if (Module::isAvailable('location')) { - $locationId = Location::getFromIpAndUuid($ip, $uuid); - } - return self::forLocation($locationId); - } - -} - -class EmptyIPxeMenu extends IPxeMenu -{ - - /** @noinspection PhpMissingParentConstructorInspection */ - public function __construct() - { - $this->title = 'No menu defined'; - $this->menuid = -1; - $this->items[] = new MenuEntry([ - 'title' => 'Please create a menu in Server-Setup first' - ]); - $this->items[] = new MenuEntry([ - 'title' => 'Bitte erstellen Sie zunächst ein Menü' - ]); - } - -} \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/inc/localboot.inc.php b/modules-available/serversetup-bwlp/inc/localboot.inc.php deleted file mode 100644 index 3ab81862..00000000 --- a/modules-available/serversetup-bwlp/inc/localboot.inc.php +++ /dev/null @@ -1,15 +0,0 @@ - 'iseq efi ${platform} && exit 1 || sanboot --no-describe', - 'EXIT' => 'exit 1', - 'COMBOOT' => 'chain /tftp/chain.c32 hd0', - 'SANBOOT' => 'sanboot --no-describe', - ]; - -} \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/inc/menuentry.inc.php b/modules-available/serversetup-bwlp/inc/menuentry.inc.php deleted file mode 100644 index d243fd23..00000000 --- a/modules-available/serversetup-bwlp/inc/menuentry.inc.php +++ /dev/null @@ -1,177 +0,0 @@ - $value) { - if (property_exists($this, $key)) { - $this->{$key} = $value; - } - } - $this->hotkey = self::getKeyCode($row['hotkey']); - if (!empty($row['bootentry'])) { - $this->bootEntry = BootEntry::fromJson($row['bootentry']); - } - $this->gap = (array_key_exists('entryid', $row) && $row['entryid'] === null); - } - settype($this->hidden, 'bool'); - settype($this->gap, 'bool'); - settype($this->sortval, 'int'); - settype($this->menuentryid, 'int'); - } - - public function getMenuItemScript($lblPrefix, $requestedDefaultId, $mode, $slxExtensions) - { - if ($this->bootEntry !== null && !$this->bootEntry->supportsMode($mode)) - return ''; - $str = 'item '; - if ($this->gap) { - $str .= '--gap '; - } else { - if ($this->hidden && $slxExtensions) { - if ($this->hotkey === false) - return ''; // Hidden entries without hotkey are illegal - $str .= '--hidden '; - } - if ($this->hotkey !== false) { - $str .= '--key ' . $this->hotkey . ' '; - } - if ($this->menuentryid == $requestedDefaultId) { - $str .= '--default '; - } - $str .= "{$lblPrefix}_{$this->menuentryid} "; - } - if (empty($this->title)) { - $str .= '${}'; - } else { - $str .= $this->title; - } - return $str . " || prompt Could not create menu item for {$lblPrefix}_{$this->menuentryid}\n"; - } - - public function getBootEntryScript($lblPrefix, $failLabel, $mode) - { - if ($this->bootEntry === null || !$this->bootEntry->supportsMode($mode)) - return ''; - $str = ":{$lblPrefix}_{$this->menuentryid}\n"; - if (!empty($this->md5pass)) { - $str .= "set slx_hash {$this->md5pass} || goto $failLabel\n" - . "set slx_salt {$this->menuentryid} || goto $failLabel\n" - . "set slx_pw_ok {$lblPrefix}_ok || goto $failLabel\n" - . "set slx_pw_fail slx_menu || goto $failLabel\n" - . "goto slx_pass_check || goto $failLabel\n" - . ":{$lblPrefix}_ok\n"; - } - return $str . $this->bootEntry->toScript($failLabel, $mode); - } - - /* - * - */ - - private static function getKeyArray() - { - static $data = false; - if ($data === false) { - $data = [ - 'F5' => 0x107e, - 'F6' => 0x127e, - 'F7' => 0x137e, - 'F8' => 0x147e, - 'F9' => 0x157e, - 'F10' => 0x167e, - 'F11' => 0x187e, - 'F12' => 0x197e, - ]; - for ($i = 1; $i <= 26; ++$i) { - $letter = chr(0x40 + $i); - $data['SHIFT_' . $letter] = 0x40 + $i; - if ($letter !== 'C') { - $data['CTRL_' . $letter] = $i; - } - $data[$letter] = 0x60 + $i; - } - for ($i = 0; $i <= 9; ++$i) { - $data[chr(0x30 + $i)] = 0x30 + $i; - } - asort($data, SORT_NUMERIC); - } - return $data; - } - - /** - * Get all the known/supported keys, usable for menu items. - * - * @return string[] list of known key names - */ - public static function getKeyList() - { - return array_keys(self::getKeyArray()); - } - - /** - * Get the key code ipxe expects for the given named - * key. Returns false if the key name is unknown. - * - * @param string $keyName - * @return false|string Key code as hex string, or false if not found - */ - public static function getKeyCode($keyName) - { - $data = self::getKeyArray(); - if (isset($data[$keyName])) - return '0x' . dechex($data[$keyName]); - return false; - } - - /** - * @param string $keyName desired key name - * @return string $keyName if it's known, empty string otherwise - */ - public static function filterKeyName($keyName) - { - $data = self::getKeyArray(); - if (isset($data[$keyName])) - return $keyName; - return ''; - } - -} diff --git a/modules-available/serversetup-bwlp/inc/pxelinux.inc.php b/modules-available/serversetup-bwlp/inc/pxelinux.inc.php deleted file mode 100644 index 1d022fef..00000000 --- a/modules-available/serversetup-bwlp/inc/pxelinux.inc.php +++ /dev/null @@ -1,302 +0,0 @@ - ['string', 'title'], - 'menu default' => ['true', 'isDefault'], - 'menu hide' => ['true', 'isHidden'], - 'menu disabled' => ['true', 'isDisabled'], - 'menu indent' => ['int', 'indent'], - 'kernel' => ['string', 'kernel'], - 'com32' => ['string', 'kernel'], - 'pxe' => ['string', 'kernel'], - 'initrd' => ['string', 'initrd'], - 'append' => ['string', 'append'], - 'ipappend' => ['int', 'ipAppend'], - 'sysappend' => ['int', 'ipAppend'], - 'localboot' => ['int', 'localBoot'], - ]; - $globalPropMap = [ - 'timeout' => ['int', 'timeoutMs', 100], - 'totaltimeout' => ['int', 'totalTimeoutMs', 100], - 'menu title' => ['string', 'title'], - 'menu clear' => ['true', 'menuClear'], - 'menu immediate' => ['true', 'immediateHotkeys'], - 'ontimeout' => ['string', 'timeoutLabel'], - ]; - $lines = preg_split('/[\r\n]+/', $input); - $section = null; - $count = count($lines); - for ($li = 0; $li < $count; ++$li) { - $line =& $lines[$li]; - if (!preg_match('/^\s*([^m]\S*|menu\s+\S+)(\s+.*?|)\s*$/i', $line, $out)) - continue; - $val = trim($out[2]); - $key = trim($out[1]); - $key = strtolower($key); - $key = preg_replace('/\s+/', ' ', $key); - if ($key === 'label') { - if ($section !== null) { - $menu->sections[] = $section; - } - $section = new PxeSection($val); - } elseif ($key === 'menu separator') { - if ($section !== null) { - $menu->sections[] = $section; - $section = null; - } - $menu->sections[] = new PxeSection(null); - } elseif (self::handleKeyword($key, $val, $globalPropMap, $menu)) { - continue; - } elseif ($section === null) { - continue; - } elseif ($key === 'text' && strtolower($val) === 'help') { - $text = ''; - while (++$li < $count) { - $line =& $lines[$li]; - if (strtolower(trim($line)) === 'endtext') - break; - $text .= $line . "\n"; - } - $section->helpText = $text; - } elseif (self::handleKeyword($key, $val, $sectionPropMap, $section)) { - continue; - } - } - if ($section !== null) { - $menu->sections[] = $section; - } - foreach ($menu->sections as $section) { - $section->mangle(); - } - return $menu; - } - - /** - * Check if keyword is valid and if so, add its interpreted value - * to the given object. The map to look up the keyword has to be passed - * as well as the object to set the value in. Map and object should - * obviously match. - * @param string $key keyword of parsed line - * @param string $val raw value of currently parsed line (empty if not present) - * @param array $map Map in which $key is looked up as key - * @param PxeMenu|PxeSection The object to set the parsed and sanitized value in - * @return bool true if the value was found in the map (and set in the object), false otherwise - */ - private static function handleKeyword($key, $val, $map, $object) - { - if (!isset($map[$key])) - return false; - $opt = $map[$key]; - // opt[0] is the type the value should be cast to; special case "true" means - // this is a bool option that will be set as soon as the keyword is present, - // as it doesn't have any parameters - if ($opt[0] === 'true') { - $val = true; - } else { - settype($val, $opt[0]); - } - // If opt[2] is present it's a multiplier for the value - if (isset($opt[2])) { - $val *= $opt[2]; - } - $object->{$opt[1]} = $val; - return true; - } - -} - -/** - * Class representing a parsed pxelinux menu. Members - * will be set to their annotated type if present or - * be null otherwise, except for present-only boolean - * options, which will default to false. - */ -class PxeMenu -{ - - /** - * @var string menu title, shown at the top of the menu - */ - public $title; - /** - * @var int initial timeout after which $timeoutLabel would be executed - */ - public $timeoutMs; - /** - * @var int if the user canceled the timeout by pressing a key, this timeout would still eventually - * trigger and launch the $timeoutLabel section - */ - public $totalTimeoutMs; - /** - * @var string label of section which will execute if the timeout expires - */ - public $timeoutLabel; - /** - * @var bool hide menu and just show background after triggering an entry - */ - public $menuClear = false; - /** - * @var bool boot the associated entry directly if its corresponding hotkey is pressed instead of just highlighting - */ - public $immediateHotkeys = false; - /** - * @var PxeSection[] list of sections the menu contains - */ - public $sections = []; - - public function hash($fuzzy) - { - $ctx = hash_init('md5'); - if (!$fuzzy) { - hash_update($ctx, $this->title); - hash_update($ctx, $this->timeoutLabel); - } - hash_update($ctx, $this->timeoutMs); - foreach ($this->sections as $section) { - if ($fuzzy) { - hash_update($ctx, mb_strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $section->title))); - } else { - hash_update($ctx, $section->label); - hash_update($ctx, $section->title); - hash_update($ctx, $section->indent); - hash_update($ctx, $section->helpText); - hash_update($ctx, $section->isDefault); - hash_update($ctx, $section->hotkey); - } - hash_update($ctx, $section->kernel); - hash_update($ctx, $section->append); - hash_update($ctx, $section->ipAppend); - hash_update($ctx, $section->passwd); - hash_update($ctx, $section->isHidden); - hash_update($ctx, $section->isDisabled); - hash_update($ctx, $section->localBoot); - foreach ($section->initrd as $initrd) { - hash_update($ctx, $initrd); - } - } - return hash_final($ctx, false); - } - -} - -/** - * Class representing a parsed pxelinux menu entry. Members - * will be set to their annotated type if present or - * be null otherwise, except for present-only boolean - * options, which will default to false. - */ -class PxeSection -{ - - /** - * @var string label used internally in PXEMENU definition to address this entry - */ - public $label; - /** - * @var string MENU LABEL of PXEMENU - title of entry displayed to the user - */ - public $title; - /** - * @var int Number of spaces to prefix the title with - */ - public $indent; - /** - * @var string help text to display when the entry is highlighted - */ - public $helpText; - /** - * @var string Kernel to load - */ - public $kernel; - /** - * @var string|string[] initrd to load for the kernel. - * If mangle() has been called this will be an array, - * otherwise it's a comma separated list. - */ - public $initrd; - /** - * @var string command line options to pass to the kernel - */ - public $append; - /** - * @var int IPAPPEND from PXEMENU. Bitmask of valid options 1 and 2. - */ - public $ipAppend; - /** - * @var string Password protecting the entry. This is most likely in crypted form. - */ - public $passwd; - /** - * @var bool whether this section is marked as default (booted after timeout) - */ - public $isDefault = false; - /** - * @var bool Menu entry is not visible (can only be triggered by timeout) - */ - public $isHidden = false; - /** - * @var bool Disable this entry, making it unselectable - */ - public $isDisabled = false; - /** - * @var int Value of the LOCALBOOT field - */ - public $localBoot; - /** - * @var string hotkey to trigger item. Only valid after calling mangle() - */ - public $hotkey; - - public function __construct($label) { $this->label = $label; } - - public function mangle() - { - if (($i = strpos($this->title, '^')) !== false) { - $this->hotkey = strtoupper($this->title{$i+1}); - $this->title = substr($this->title, 0, $i) . substr($this->title, $i + 1); - } - if (strpos($this->append, 'initrd=') !== false) { - $parts = preg_split('/\s+/', $this->append); - $this->append = ''; - for ($i = 0; $i < count($parts); ++$i) { - if (preg_match('/^initrd=(.*)$/', $parts[$i], $out)) { - if (!empty($this->initrd)) { - $this->initrd .= ','; - } - $this->initrd .= $out[1]; - } else { - $this->append .= ' ' . $parts[$i]; - } - } - $this->append = trim($this->append); - } - if (is_string($this->initrd)) { - $this->initrd = explode(',', $this->initrd); - } elseif (!is_array($this->initrd)) { - $this->initrd = []; - } - } - -} - diff --git a/modules-available/serversetup-bwlp/install.inc.php b/modules-available/serversetup-bwlp/install.inc.php deleted file mode 100644 index 25579c13..00000000 --- a/modules-available/serversetup-bwlp/install.inc.php +++ /dev/null @@ -1,89 +0,0 @@ -compileTask !== null) - return $this->compileTask; - $this->compileTask = Property::get('ipxe-task-id'); - if ($this->compileTask !== false) { - $this->compileTask = Taskmanager::status($this->compileTask); - if (!Taskmanager::isTask($this->compileTask) || Taskmanager::isFinished($this->compileTask)) { - $this->compileTask = false; - } - } - return $this->compileTask; - } - - protected function doPreprocess() - { - User::load(); - - if (!User::isLoggedIn()) { - Message::addError('main.no-permission'); - Util::redirect('?do=Main'); - } - - if (Request::any('action') === 'getimage') { - User::assertPermission("download"); - $this->handleGetImage(); - } - - $this->currentMenu = Property::getBootMenu(); - - $action = Request::post('action'); - - if ($action === false) { - $this->currentAddress = Property::getServerIp(); - $this->getLocalAddresses(); - } - - if ($action === 'compile') { - User::assertPermission("edit.address"); - if ($this->getCompileTask() === false) { - Trigger::ipxe(); - } - Util::redirect('?do=serversetup'); - } - - if ($action === 'ip') { - User::assertPermission("edit.address"); - // New address is to be set - $this->getLocalAddresses(); - $this->updateLocalAddress(); - } - - if ($action === 'savebootentry') { - User::assertPermission('ipxe.bootentry.edit'); - $this->saveBootEntry(); - } - - if ($action === 'deleteBootentry') { - User::assertPermission('ipxe.bootentry.edit'); - $this->deleteBootEntry(); - } - - if ($action === 'savemenu') { - User::assertPermission('ipxe.menu.edit'); - $this->saveMenu(); - } - - if ($action === 'savelocation') { - // Permcheck in function - $this->saveLocationMenu(); - Util::redirect('?do=locations'); - } - - if ($action === 'savelocalboot') { - User::assertPermission('ipxe.localboot.edit'); - $this->saveLocalboot(); - } - - if ($action === 'deleteMenu') { - // Permcheck in function - $this->deleteMenu(); - } - - if ($action === 'setDefaultMenu') { - User::assertPermission('ipxe.menu.edit', 0); - $this->setDefaultMenu(); - } - - if (Request::isPost()) { - Util::redirect('?do=serversetup'); - } - - User::assertPermission('access-page'); - - if (User::hasPermission('ipxe.*')) { - Dashboard::addSubmenu('?do=serversetup&show=menu', Dictionary::translate('submenu_menu', true)); - Dashboard::addSubmenu('?do=serversetup&show=bootentry', Dictionary::translate('submenu_bootentry', true)); - } - if (User::hasPermission('edit.address')) { - Dashboard::addSubmenu('?do=serversetup&show=address', Dictionary::translate('submenu_address', true)); - } - if (User::hasPermission('download')) { - Dashboard::addSubmenu('?do=serversetup&show=download', Dictionary::translate('submenu_download', true)); - } - if (User::hasPermission('ipxe.localboot.*')) { - Dashboard::addSubmenu('?do=serversetup&show=localboot', Dictionary::translate('submenu_localboot', true)); - } - if (Request::get('show') === false) { - $subs = Dashboard::getSubmenus(); - if (empty($subs)) { - User::assertPermission('download'); - } else { - Util::redirect($subs[0]['url']); - } - } - } - - protected function doRender() - { - Render::addTemplate("heading"); - - $task = $this->getCompileTask(); - if ($task !== false) { - $files = []; - if ($task['data'] && $task['data']['files']) { - foreach ($task['data']['files'] as $k => $v) { - $files[] = ['name' => $k, 'namehyphen' => str_replace(['/', '.'], '-', $k)]; - } - } - Render::addTemplate('ipxe_update', array('taskid' => $task['id'], 'files' => $files)); - } - - switch (Request::get('show')) { - case 'editbootentry': - User::assertPermission('ipxe.bootentry.edit'); - $this->showEditBootEntry(); - break; - case 'editmenu': - User::assertPermission('ipxe.menu.view'); - $this->showEditMenu(); - break; - case 'download': - User::assertPermission('download'); - $this->showDownload(); - break; - case 'menu': - User::assertPermission('ipxe.menu.view'); - $this->showMenuList(); - break; - case 'bootentry': - User::assertPermission('ipxe.bootentry.view'); - $this->showBootentryList(); - break; - case 'address': - User::assertPermission('edit.address'); - $this->showEditAddress(); - break; - case 'assignlocation': - // Permcheck in function - $this->showEditLocation(); - break; - case 'localboot': - User::assertPermission('ipxe.localboot.*'); - $this->showLocalbootConfig(); - break; - default: - Util::redirect('?do=serversetup'); - break; - } - } - - private function showDownload() - { - $list = glob('/srv/openslx/www/boot/download/*', GLOB_NOSORT); - usort($list, function ($a, $b) { - return strcmp(substr($a, -4), substr($b, -4)) * 100 + strcmp($a, $b); - }); - $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], - ]; - foreach ($list as $file) { - if ($file{0} === '.') - continue; - if (is_file($file)) { - $base = basename($file); - $features = []; - foreach (preg_split('/[\-\.\/]+/', $base, -1, PREG_SPLIT_NO_EMPTY) as $p) { - if (array_key_exists($p, $strings)) { - $features += $strings[$p]; - } - } - asort($features); - $files[] = [ - 'name' => $base, - 'size' => Util::readableFileSize(filesize($file)), - 'modified' => Util::prettyTime(filemtime($file)), - 'class' => substr($base, -4) === '.usb' ? 'slx-bold' : '', - 'features' => implode(', ', array_keys($features)), - ]; - } - } - Render::addTemplate('download', ['files' => $files]); - } - - private function makeSelectArray($list, $default) - { - $ret = []; - foreach (array_keys($list) as $k) { - $ret[] = [ - 'key' => $k, - 'selected' => ($k === $default ? 'selected' : ''), - ]; - } - return $ret; - } - - private function showLocalbootConfig() - { - // Default setting - $default = Property::get(Localboot::PROPERTY_KEY, 'AUTO'); - if (!array_key_exists($default, Localboot::BOOT_METHODS)) { - $default = 'AUTO'; - } - $optionList = $this->makeSelectArray(Localboot::BOOT_METHODS, $default); - // Exceptions - $cutoff = strtotime('-90 days'); - $models = []; - $res = Database::simpleQuery('SELECT m.systemmodel, cnt, sl.bootmethod FROM ( - SELECT m2.systemmodel, Count(*) AS cnt FROM machine m2 - WHERE m2.lastseen > :cutoff - GROUP BY systemmodel - ) m - LEFT JOIN serversetup_localboot sl USING (systemmodel) - ORDER BY systemmodel', ['cutoff' => $cutoff]); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['options'] = $this->makeSelectArray(Localboot::BOOT_METHODS, $row['bootmethod']); - $models[] = $row; - } - // Output - $data = [ - 'default' => $default, - 'options' => $optionList, - 'exceptions' => $models, - ]; - Render::addTemplate('localboot', $data); - } - - private function showBootentryList() - { - $allowEdit = User::hasPermission('ipxe.bootentry.edit'); - - $res = Database::simpleQuery("SELECT be.entryid, be.hotkey, be.title, be.builtin, Count(*) AS refs FROM serversetup_bootentry be - INNER JOIN serversetup_menuentry sm USING (entryid) - GROUP BY be.entryid - ORDER BY be.title ASC"); - $bootentryTable = []; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $bootentryTable[] = $row; - } - - Render::addTemplate('bootentry-list', array( - 'bootentryTable' => $bootentryTable, - 'allowEdit' => $allowEdit, - )); - } - - private function showMenuList() - { - $allowedEdit = User::getAllowedLocations('ipxe.menu.edit'); - - // TODO Permission::addGlobalTags($perms, null, ['edit.menu', 'edit.address', 'download']); - - $res = Database::simpleQuery("SELECT m.menuid, m.title, m.isdefault, GROUP_CONCAT(l.locationid) AS locations, - GROUP_CONCAT(ll.locationname SEPARATOR ', ') AS locnames - FROM serversetup_menu m - LEFT JOIN serversetup_menu_location l USING (menuid) - LEFT JOIN location ll USING (locationid) - GROUP BY menuid - ORDER BY title"); - $menuTable = []; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if (empty($row['locations'])) { - $locations = []; - $row['allowEdit'] = in_array(0, $allowedEdit); - } else { - $locations = explode(',', $row['locations']); - $row['allowEdit'] = empty(array_diff($locations, $allowedEdit)); - } - $row['locationCount'] = empty($locations) ? '' : count($locations); - $menuTable[] = $row; - } - - Render::addTemplate('menu-list', array( - 'menuTable' => $menuTable, - 'showSetDefault' => User::hasPermission('ipxe.menu.edit', 0) - )); - } - - private function hasMenuPermission($menuid, $permission) - { - $allowedEditLocations = User::getAllowedLocations($permission); - $allowEdit = in_array(0, $allowedEditLocations); - if (!$allowEdit) { - // Get locations - $locations = Database::queryColumnArray('SELECT locationid FROM serversetup_menu_location - WHERE menuid = :menuid', compact('menuid')); - if (!empty($locations)) { - $allowEdit = count(array_diff($locations, $allowedEditLocations)) === 0; - } - } - return $allowEdit; - } - - private function showEditMenu() - { - $id = Request::get('id', false, 'int'); - // if = edit, else = add new - if ($id !== 0) { - $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid, isdefault - FROM serversetup_menu WHERE menuid = :id", compact('id')); - } else { - $menu = []; - $menu['menuid'] = 0; - $menu['timeoutms'] = 0; - $menu['title'] = ''; - $menu['defaultentryid'] = null; - $menu['isdefault'] = false; - } - - if ($menu === false) { - Message::addError('invalid-menu-id', $id); - Util::redirect('?do=serversetup&show=menu'); - } - $highlight = Request::get('highlight', false, 'string'); - if ($id !== 0 && !$this->hasMenuPermission($id, 'ipxe.menu.edit')) { - $menu['readonly'] = 'readonly'; - $menu['disabled'] = 'disabled'; - $menu['plainpass'] = ''; - } - if (!User::hasPermission('ipxe.menu.edit', 0)) { - $menu['globalMenuWarning'] = true; - } - - $menu['timeout'] = round($menu['timeoutms'] / 1000); - $menu['entries'] = []; - $res = Database::simpleQuery("SELECT menuentryid, entryid, hotkey, title, hidden, sortval, plainpass FROM - serversetup_menuentry WHERE menuid = :id ORDER BY sortval ASC", compact('id')); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($row['entryid'] == $highlight) { - $row['highlight'] = 'active'; - } - $menu['entries'][] = $row; - } - $menu['keys'] = array_map(function ($item) { return ['key' => $item]; }, MenuEntry::getKeyList()); - $menu['entrylist'] = Database::queryAll("SELECT entryid, title, hotkey, data FROM serversetup_bootentry ORDER BY title ASC"); - foreach ($menu['entrylist'] as &$bootentry) { - //$bootentry['json'] = $bootentry['data']; - $bootentry['data'] = json_decode($bootentry['data'], true); - if (array_key_exists('arch', $bootentry['data'])) { - $bootentry['data']['PCBIOS'] = array('executable' => $bootentry['data']['executable']['PCBIOS'], - 'initRd' => $bootentry['data']['initRd']['PCBIOS'], - 'commandLine' => $bootentry['data']['commandLine']['PCBIOS']); - $bootentry['data']['EFI'] = array('executable' => $bootentry['data']['executable']['EFI'], - 'initRd' => $bootentry['data']['initRd']['EFI'], - 'commandLine' => $bootentry['data']['commandLine']['EFI']); - - if ($bootentry['data']['arch'] === 'PCBIOS') { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_biosOnly', true); - unset($bootentry['data']['EFI']); - } else if ($bootentry['data']['arch'] === 'EFI') { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_efiOnly', true); - unset($bootentry['data']['PCBIOS']); - } else { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archBoth', true); - } - - } elseif (!array_key_exists('script', $bootentry['data'])) { - $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic', true); - $bootentry['data']['archAgnostic'] = array('executable' => $bootentry['data']['executable'], - 'initRd' => $bootentry['data']['initRd'], - 'commandLine' => $bootentry['data']['commandLine']); - } - } - foreach ($menu['entries'] as &$entry) { - $entry['isdefault'] = ($entry['menuentryid'] == $menu['defaultentryid']); - // TODO: plainpass only when permissions - } - - Permission::addGlobalTags($menu['perms'], 0, ['ipxe.menu.edit']); - Render::addTemplate('menu-edit', $menu); - } - - private function showEditBootEntry() - { - $params = []; - $id = Request::get('id', false, 'string'); - if ($id === false) { - $params['exec_checked'] = 'checked'; - $params['entryid'] = 'u-' . dechex(mt_rand(0x1000, 0xffff)) . '-' . dechex(time()); - $params['entries'] = [ - ['mode' => 'PCBIOS'], - ['mode' => 'EFI'], - ]; - } else { - // Query existing entry - $row = Database::queryFirst('SELECT entryid, title, builtin, data FROM serversetup_bootentry - WHERE entryid = :id LIMIT 1', ['id' => $id]); - if ($row === false) { - Message::addError('invalid-boot-entry', $id); - Util::redirect('?do=serversetup'); - } - $entry = BootEntry::fromJson($row['data']); - if ($entry === null) { - Message::addError('unknown-bootentry-type', $id); - Util::redirect('?do=serversetup'); - } - $entry->addFormFields($params); - $params['title'] = $row['title']; - $params['entryid'] = $row['entryid']; - $params['builtin'] = $row['builtin']; - $params['menus'] = Database::queryAll('SELECT m.menuid, m.title FROM serversetup_menu m - INNER JOIN serversetup_menuentry me ON (me.menuid = m.menuid) - WHERE me.entryid = :entryid', ['entryid' => $row['entryid']]); - } - - Render::addTemplate('ipxe-new-boot-entry', $params); - } - - private function showEditAddress() - { - Render::addTemplate('ipaddress', array( - 'ips' => $this->addrListTask['data']['addresses'], - 'chooseHintClass' => $this->hasIpSet ? '' : 'alert alert-danger', - 'disabled' => ($this->getCompileTask() === false) ? '' : 'disabled', - )); - } - - // ----------------------------------------------------------------------------------------------- - - private function getLocalAddresses() - { - $this->addrListTask = Taskmanager::submit('LocalAddressesList', array()); - - if ($this->addrListTask === false) { - $this->addrListTask['data']['addresses'] = false; - return false; - } - - if (!Taskmanager::isFinished($this->addrListTask)) { // TODO: Async if just displaying - $this->addrListTask = Taskmanager::waitComplete($this->addrListTask['id'], 4000); - } - - if (Taskmanager::isFailed($this->addrListTask) || !isset($this->addrListTask['data']['addresses'])) { - $this->addrListTask['data']['addresses'] = false; - return false; - } - - $sortIp = array(); - foreach (array_keys($this->addrListTask['data']['addresses']) as $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; - } - if ($this->currentAddress === $item['ip']) { - $item['default'] = true; - $this->hasIpSet = true; - } - $sortIp[] = $item['ip']; - } - unset($item); - array_multisort($sortIp, SORT_STRING, $this->addrListTask['data']['addresses']); - return true; - } - - private function deleteBootEntry() { - $id = Request::post('deleteid', false, 'string'); - if ($id === false) { - Message::addError('main.parameter-missing', 'deleteid'); - return; - } - Database::exec("DELETE FROM serversetup_bootentry WHERE entryid = :entryid", array("entryid" => $id)); - // TODO: Redirect to &show=bootentry - Message::addSuccess('bootentry-deleted'); - } - - private function setDefaultMenu() - { - $id = Request::post('menuid', false, 'int'); - if ($id === false) { - Message::addError('main.parameter-missing', 'menuid'); - return; - } - Database::exec('UPDATE serversetup_menu SET isdefault = (menuid = :menuid)', ['menuid' => $id]); - Message::addSuccess('menu-set-default'); - } - - private function deleteMenu() - { - $id = Request::post('deleteid', false, 'int'); - if ($id === false) { - Message::addError('main.parameter-missing', 'deleteid'); - return; - } - if (!$this->hasMenuPermission($id, 'ipxe.menu.edit')) { - Message::addError('locations.no-permission-location', $id); - return; - } - Database::exec("DELETE FROM serversetup_menu WHERE menuid = :menuid", array("menuid" => $id)); - Message::addSuccess('menu-deleted'); - } - - private function saveMenu() - { - $id = Request::post('menuid', false, 'int'); - if ($id === false) { - Message::addError('main.parameter-missing', 'menuid'); - return; - } - - $insertParams = [ - 'title' => IPxe::sanitizeIpxeString(Request::post('title', '', 'string')), - 'timeoutms' => abs(Request::post('timeout', 0, 'int') * 1000), - ]; - if ($id === 0) { - Database::exec("INSERT INTO serversetup_menu (title, timeoutms, isdefault) VALUES (:title, :timeoutms, 0)", $insertParams); - $menu['menuid'] = $id = Database::lastInsertId(); - } else { - $menu = Database::queryFirst("SELECT m.menuid - FROM serversetup_menu m - WHERE menuid = :id", compact('id')); - if ($menu === false) { - Message::addError('no-such-menu', $id); - return; - } - $insertParams['menuid'] = $id; - Database::exec('UPDATE serversetup_menu SET title = :title, timeoutms = :timeoutms - WHERE menuid = :menuid', $insertParams); - } - - $keepIds = []; - $entries = Request::post('entry', false, 'array'); - $wantedDefaultEntryId = Request::post('defaultentry', null, 'string'); - $defaultEntryId = null; - - if ($entries) { - foreach ($entries as $key => $entry) { - if (!isset($entry['sortval'])) { - error_log(print_r($entry, true)); - continue; - } - // Fallback defaults - $entry += [ - 'entryid' => null, - 'title' => '', - 'hidden' => 0, - 'plainpass' => '', - ]; - $params = [ - 'title' => IPxe::sanitizeIpxeString($entry['title']), - 'sortval' => (int)$entry['sortval'], - 'menuid' => $menu['menuid'], - ]; - if (empty($entry['entryid'])) { - // Spacer - $params += [ - 'entryid' => null, - 'hotkey' => '', - 'hidden' => 0, // Doesn't make any sense - 'plainpass' => '', // Doesn't make any sense - ]; - } else { - $params += [ - 'entryid' => $entry['entryid'], // TODO validate? - 'hotkey' => MenuEntry::filterKeyName($entry['hotkey']), - 'hidden' => (int)$entry['hidden'], // TODO (needs hotkey to make sense) - 'plainpass' => $entry['plainpass'], - ]; - } - if (is_numeric($key)) { - if ((string)$key === $wantedDefaultEntryId) { // Check now that we have generated our key - $defaultEntryId = $key; - } - $keepIds[] = $key; - $params['menuentryid'] = $key; - $params['md5pass'] = IPxe::makeMd5Pass($entry['plainpass'], $key); - $ret = Database::exec('UPDATE serversetup_menuentry - SET entryid = :entryid, hotkey = :hotkey, title = :title, hidden = :hidden, sortval = :sortval, - plainpass = :plainpass, md5pass = :md5pass - WHERE menuid = :menuid AND menuentryid = :menuentryid', $params, true); - } else { - $ret = Database::exec("INSERT INTO serversetup_menuentry - (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass) - VALUES (:menuid, :entryid, :hotkey, :title, :hidden, :sortval, :plainpass, '')", $params, true); - if ($ret) { - $newKey = Database::lastInsertId(); - if ((string)$key === $wantedDefaultEntryId) { // Check now that we have generated our key - $defaultEntryId = $newKey; - } - $keepIds[] = (int)$newKey; - if (!empty($entry['plainpass'])) { - Database::exec('UPDATE serversetup_menuentry SET md5pass = :md5pass WHERE menuentryid = :id', [ - 'md5pass' => IPxe::makeMd5Pass($entry['plainpass'], $newKey), - 'id' => $newKey, - ]); - } - } - } - - if ($ret === false) { - Message::addWarning('error-saving-entry', $entry['title'], Database::lastError()); - } - } - Database::exec('DELETE FROM serversetup_menuentry WHERE menuid = :menuid AND menuentryid NOT IN (:keep)', - ['menuid' => $menu['menuid'], 'keep' => $keepIds]); - // Set default entry - Database::exec('UPDATE serversetup_menu SET defaultentryid = :default WHERE menuid = :menuid', - ['menuid' => $menu['menuid'], 'default' => $defaultEntryId]); - } else { - Database::exec('DELETE FROM serversetup_menuentry WHERE menuid = :menuid', ['menuid' => $menu['menuid']]); - Database::exec('UPDATE serversetup_menu SET defaultentryid = NULL WHERE menuid = :menuid', ['menuid' => $menu['menuid']]); - } - - Message::addSuccess('menu-saved'); - } - - private function updateLocalAddress() - { - $newAddress = Request::post('ip', 'none', 'string'); - $valid = false; - foreach ($this->addrListTask['data']['addresses'] as $item) { - if ($item['ip'] !== $newAddress) - continue; - $valid = true; - break; - } - if ($valid) { - Property::setServerIp($newAddress); - Util::redirect('?do=ServerSetup'); - } else { - Message::addError('invalid-ip', $newAddress); - } - Util::redirect(); - } - - private function handleGetImage() - { - $file = "/opt/openslx/ipxe/openslx-bootstick.raw"; - if (!is_readable($file)) { - Message::addError('image-not-found'); - return; - } - Header('Content-Type: application/octet-stream'); - Header('Content-Disposition: attachment; filename="openslx-bootstick-' . Property::getServerIp() . '-raw.img"'); - readfile($file); - exit; - } - - private function saveBootEntry() - { - $oldEntryId = Request::post('entryid', false, 'string'); - $newId = Request::post('newid', false, 'string'); - if (!preg_match('/^[a-z0-9\-_]{1,16}$/', $newId)) { - Message::addError('main.parameter-empty', 'newid'); - return; - } - $data = Request::post('entry', false); - if (!is_array($data)) { - Message::addError('missing-bootentry-data'); - return; - } - $type = Request::post('type', false, 'string'); - if ($type === 'exec') { - $entry = BootEntry::newStandardBootEntry($data); - } elseif ($type === 'script') { - $entry = BootEntry::newCustomBootEntry($data); - } else { - Message::addError('unknown-bootentry-type', $type); - return; - } - if ($entry === null) { - Message::addError('main.empty-field'); - Util::redirect('?do=serversetup&show=bootentry'); - } - $params = [ - 'entryid' => $newId, - 'title' => Request::post('title', '', 'string'), - 'data' => json_encode($entry->toArray()), - ]; - // New or update? - if (empty($oldEntryId)) { - // New entry - Database::exec('INSERT INTO serversetup_bootentry (entryid, title, builtin, data) - VALUES (:entryid, :title, 0, :data)', $params); - Message::addSuccess('boot-entry-created', $newId); - } else { - // Edit existing entry - $params['oldid'] = $oldEntryId; - Database::exec('UPDATE serversetup_bootentry SET entryid = :entryid, title = :title, data = :data - WHERE entryid = :oldid', $params); - Message::addSuccess('boot-entry-updated', $newId); - } - Util::redirect('?do=serversetup&show=bootentry'); - } - - private function showEditLocation() - { - $locationId = Request::get('locationid', false, 'int'); - $loc = Location::get($locationId); - if ($loc === false) { - Message::addError('locations.invalid-location-id', $locationId); - return; - } - User::assertPermission('ipxe.menu.assign', $locationId); - // List of menu entries - $res = Database::simpleQuery('SELECT menuentryid, title FROM serversetup_menuentry'); - $menuEntries = $res->fetchAll(PDO::FETCH_KEY_PAIR); - // List of menus - $data = [ - 'locationid' => $locationId, - 'locationName' => $loc['locationname'], - ]; - $res = Database::simpleQuery('SELECT m.menuid, m.title, ml.locationid, ml.defaultentryid, GROUP_CONCAT(me.menuentryid) AS entries FROM serversetup_menu m - LEFT JOIN serversetup_menu_location ml ON (m.menuid = ml.menuid AND ml.locationid = :locationid) - INNER JOIN serversetup_menuentry me ON (m.menuid = me.menuid AND me.entryid IS NOT NULL) - GROUP BY menuid - ORDER BY m.title ASC', ['locationid' => $locationId]); - $menus = []; - $hasDefault = false; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $eids = explode(',', $row['entries']); - $row['entries'] = []; - foreach ($eids as $eid) { - $row['entries'][] = [ - 'id' => $eid, - 'title' => $menuEntries[$eid], - 'selected' => ($eid == $row['defaultentryid'] ? 'selected' : ''), - ]; - } - if ($row['locationid'] !== null) { - $hasDefault = true; - $row['menu_selected'] = 'checked'; - } - $menus[] = $row; - } - if (!$hasDefault) { - $data['default_selected'] = 'checked'; - } - $data['list'] = $menus; - Render::addTemplate('menu-assign-location', $data); - } - - private function saveLocationMenu() - { - $locationId = Request::post('locationid', false, 'int'); - $loc = Location::get($locationId); - if ($loc === false) { - Message::addError('locations.invalid-location-id', $locationId); - return; - } - User::assertPermission('ipxe.menu.assign', $locationId); - $menuId = Request::post('menuid', false, 'int'); - if ($menuId === 0) { - Database::exec('DELETE FROM serversetup_menu_location WHERE locationid = :locationid', - ['locationid' => $locationId]); - Message::addSuccess('location-use-default', $loc['locationname']); - return; - } - $defaultEntryId = Request::post('defaultentryid-' . $menuId, 0, 'int'); - if ($defaultEntryId === 0) { - $defaultEntryId = null; - } - Database::exec('INSERT INTO serversetup_menu_location (menuid, locationid, defaultentryid) - VALUES (:menuid, :locationid, :defaultentryid) - ON DUPLICATE KEY UPDATE menuid = :menuid, defaultentryid = :defaultentryid', [ - 'menuid' => $menuId, - 'locationid' => $locationId, - 'defaultentryid' => $defaultEntryId - ]); - Message::addSuccess('location-menu-assigned', $loc['locationname']); - } - - private function saveLocalboot() - { - $default = Request::post('default', 'AUTO', 'string'); - if (!array_key_exists($default, Localboot::BOOT_METHODS)) { - Message::addError('localboot-invalid-method', $default); - return; - } - Property::set(Localboot::PROPERTY_KEY, $default); - $overrides = Request::post('override', [], 'array'); - Database::exec('TRUNCATE TABLE serversetup_localboot'); - foreach ($overrides as $model => $mode) { - if (empty($mode)) // No override - continue; - if (!array_key_exists($mode, Localboot::BOOT_METHODS)) { - Message::addWarning('localboot-invalid-method', $mode); - continue; - } - Database::exec('INSERT INTO serversetup_localboot (systemmodel, bootmethod) - VALUES (:model, :mode)', compact('model', 'mode')); - } - Message::addSuccess('localboot-saved'); - Util::redirect('?do=serversetup&show=localboot'); - } - -} diff --git a/modules-available/serversetup-bwlp/permissions/permissions.json b/modules-available/serversetup-bwlp/permissions/permissions.json deleted file mode 100644 index 33cc9cea..00000000 --- a/modules-available/serversetup-bwlp/permissions/permissions.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "access-page": { - "location-aware": false - }, - "download": { - "location-aware": false - }, - "edit.address": { - "location-aware": false - }, - "ipxe.bootentry.view": { - "location-aware": false - }, - "ipxe.bootentry.edit": { - "location-aware": false - }, - "ipxe.menu.view": { - "location-aware": false - }, - "ipxe.menu.edit": { - "location-aware": false - }, - "ipxe.menu.assign": { - "location-aware": true - }, - "ipxe.localboot.edit": { - "location-aware": false - } -} \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/bootentry-list.html b/modules-available/serversetup-bwlp/templates/bootentry-list.html deleted file mode 100644 index 0cf005c5..00000000 --- a/modules-available/serversetup-bwlp/templates/bootentry-list.html +++ /dev/null @@ -1,83 +0,0 @@ -

{{lang_bootentryHead}}

- -

- {{lang_bootentryIntro}} -

- - - - - - - - - - - - - {{#bootentryTable}} - - - - - - - - {{/bootentryTable}} - -
{{lang_bootentryTitle}}{{lang_hotkey}}{{lang_refCount}}{{lang_edit}}{{lang_delete}}
- {{title}} - - {{hotkey}} - - {{refs}} - - {{#allowEdit}} - - - - {{/allowEdit}} - - {{#allowEdit}} - - {{/allowEdit}} -
-
- {{#allowEdit}} - - - {{lang_addBootentry}} - - {{/allowEdit}} -
- - -
- - -
- - \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/download.html b/modules-available/serversetup-bwlp/templates/download.html deleted file mode 100644 index 62064b66..00000000 --- a/modules-available/serversetup-bwlp/templates/download.html +++ /dev/null @@ -1,53 +0,0 @@ -
-
- {{lang_downloadBootImage}} -
-
- - {{#files}} - - - - - - - {{/files}} -
{{name}}{{size}}{{modified}}({{features}})
-

- - - {{lang_usbImgHelpBtn}} - -

-

- {{lang_additionalInfoLink}} {{lang_ipxeWikiUrl}} -

-
-
- - \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/heading.html b/modules-available/serversetup-bwlp/templates/heading.html deleted file mode 100644 index e2aa0bff..00000000 --- a/modules-available/serversetup-bwlp/templates/heading.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/ipaddress.html b/modules-available/serversetup-bwlp/templates/ipaddress.html deleted file mode 100644 index ea19c417..00000000 --- a/modules-available/serversetup-bwlp/templates/ipaddress.html +++ /dev/null @@ -1,44 +0,0 @@ -
-
- {{lang_bootAddress}} -
-
-
- {{lang_chooseIP}} -
-
- - - - {{#ips}} - - - {{#default}} - - {{/default}} - {{^default}} - - {{/default}} - - {{/ips}} -
{{ip}} - {{lang_active}} - - -
-

- {{lang_recompileHint}} -

-
-
- - -
-
-
\ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html b/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html deleted file mode 100644 index 7e82b5cc..00000000 --- a/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html +++ /dev/null @@ -1,165 +0,0 @@ -

{{lang_newBootEntryHead}}

- -{{#builtin}} -
- {{lang_editBuiltinWarn}} -
-{{/builtin}} - -
-
- {{lang_bootEntryData}} -
-
-
- - - - -
-
- - -
-
- - -
-
- -
- - -
-
- - -
-
- - -
- -
-
- {{#entries}} -
-
-
-

{{mode}}

-
- - -
-
- - -
-
- - -
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- {{/entries}} -
-
- -
-
- - -
-
- - {{#builtin}} -
- {{lang_editBuiltinWarn}} -
- {{/builtin}} - -

{{lang_referencingMenus}}:

- - -
- -
-
-
-
- - \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/ipxe_update.html b/modules-available/serversetup-bwlp/templates/ipxe_update.html deleted file mode 100644 index 344d3905..00000000 --- a/modules-available/serversetup-bwlp/templates/ipxe_update.html +++ /dev/null @@ -1,54 +0,0 @@ -
-
{{lang_menuGeneration}}
-
-
- {{#files}} -
- - {{name}} -
- {{/files}} -
-
-
- {{lang_generationFailed}} -
-
-
{{lang_menuGeneration}}
-
-
- - diff --git a/modules-available/serversetup-bwlp/templates/localboot.html b/modules-available/serversetup-bwlp/templates/localboot.html deleted file mode 100644 index 3037de2a..00000000 --- a/modules-available/serversetup-bwlp/templates/localboot.html +++ /dev/null @@ -1,59 +0,0 @@ -

{{lang_localBootHead}}

- -

{{lang_localBootIntro}}

- -
- - - - -
-
- - -
- -
-

- {{lang_localBootExceptions}} -

- - - - - - - {{#exceptions}} - - - - - - {{/exceptions}} -
{{lang_systemmodel}}{{lang_count}}{{lang_override}}
{{systemmodel}}{{cnt}} - -
- -
- - -
- -
diff --git a/modules-available/serversetup-bwlp/templates/menu-assign-location.html b/modules-available/serversetup-bwlp/templates/menu-assign-location.html deleted file mode 100644 index 077d137e..00000000 --- a/modules-available/serversetup-bwlp/templates/menu-assign-location.html +++ /dev/null @@ -1,69 +0,0 @@ -

{{lang_assignMenuToLocation}}

-

{{locationName}}

- -
- - - - - - - - - - - - - - - - - - - {{#list}} - - - - - - {{/list}} - -
{{lang_menuTitle}}{{lang_menuEntryOverride}}
-
- - -
-
- {{lang_useDefaultMenu}} -
-
- - -
-
- {{title}} - - -
- -
- -
- -
- -
- - \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/menu-edit.html b/modules-available/serversetup-bwlp/templates/menu-edit.html deleted file mode 100644 index 1598a2b7..00000000 --- a/modules-available/serversetup-bwlp/templates/menu-edit.html +++ /dev/null @@ -1,368 +0,0 @@ -

{{lang_editMenuHead}}

- - - - -
-
- {{title}} - {{^title}} - {{lang_newMenu}} - {{/title}} -
-
-
- - - - -
-
- -
-
- -
-
-
-
- -
-
-
- - {{lang_seconds}} -
-
-
-
- - - - - - - - - - - - - - - {{#entries}} - - - - - - - - - - - - - - - - - {{/entries}} - -
{{lang_entryId}}{{lang_title}}{{lang_hotkey}}{{lang_password}}
- - -
- - -
-
- - - - - - - - - -
- - -
-
- -
-
-
- -
-
- {{lang_cancel}} - -
-
- - -
-
- - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/menu-list.html b/modules-available/serversetup-bwlp/templates/menu-list.html deleted file mode 100644 index 545f22a9..00000000 --- a/modules-available/serversetup-bwlp/templates/menu-list.html +++ /dev/null @@ -1,100 +0,0 @@ -

{{lang_listOfMenus}}

- -

- {{lang_menuListIntro}} -

- - - - - - - - - - - - - {{#menuTable}} - - - - - - - - {{/menuTable}} - -
{{lang_menuTitle}}{{lang_locationCount}}{{lang_isDefault}}{{lang_edit}}{{lang_delete}}
- {{title}} - - {{locationCount}} - - {{^isdefault}} - {{#showSetDefault}} -
- - - -
- {{/showSetDefault}} - {{/isdefault}} - {{#isdefault}} - - {{/isdefault}} -
- {{#allowEdit}} - - - - {{/allowEdit}} - - {{#allowDelete}} - - {{/allowDelete}} -
- - -
- - - -
- - -
- - \ No newline at end of file -- cgit v1.2.3-55-g7522