# # Copyright (C) 2019 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. You should have received a copy of the # GNU General Public License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # import os from pyanaconda.modules.storage.bootloader.base import BootLoader, BootLoaderArguments,\ BootLoaderError from pyanaconda.core.util import execWithRedirect from pyanaconda.core.configuration.anaconda import conf from pyanaconda.core.product import get_product_name from pyanaconda.anaconda_loggers import get_module_logger log = get_module_logger(__name__) __all__ = ["EXTLINUX"] class EXTLINUX(BootLoader): name = "EXTLINUX" _config_file = "extlinux.conf" _config_dir = "/boot/extlinux" stage2_format_types = ["ext4", "ext3", "ext2"] stage2_device_types = ["partition"] stage2_bootable = True # The extlinux bootloader doesn't have BLS support, the old grubby is needed packages = ["syslinux-extlinux", "grubby-deprecated"] @property def config_file(self): return "%s/%s" % (self._config_dir, self._config_file) @property def boot_prefix(self): """ Prefix, if any, to paths in /boot. """ if self.stage2_device.format.mountpoint == "/": prefix = "/boot" else: prefix = "" return prefix def write_config_console(self, config): if not self.console: return console_arg = "console=%s" % self.console if self.console_options: console_arg += ",%s" % self.console_options self.boot_args.add(console_arg) def write_config_images(self, config): self.write_config_console(config) for image in self.images: args = BootLoaderArguments() args.update(["root=%s" % image.device.fstab_spec, "ro"]) if image.device.type == "btrfs subvolume": args.add("rootflags=subvol=%s" % image.device.name) args.update(self.boot_args) log.info("bootloader.py: used boot args: %s ", args) # extlinux labels cannot have spaces label = "%s(%s)" % (self.image_label(image), image.version) label = label.replace(" ", "") stanza = ("label %(label)s\n" "\tkernel %(boot_prefix)s/%(kernel)s\n" "\tinitrd %(boot_prefix)s/%(initrd)s\n" "\tappend %(args)s\n\n" % {"label": label, "kernel": image.kernel, "initrd": image.initrd, "args": args, "boot_prefix": self.boot_prefix}) config.write(stanza) def write_config_header(self, config): header = ("# extlinux.conf generated by anaconda\n\n" "ui menu.c32\n\n" "menu autoboot Welcome to %(productName)s. Automatic boot in # second{,s}. Press a key for options.\n" "menu title %(productName)s Boot Options.\n" "menu hidden\n\n" "timeout %(timeout)d\n" "#totaltimeout 9000\n\n" % {"productName": get_product_name(), "timeout": self.timeout * 10}) config.write(header) if self.default is not None: config.write("default %(default)s\n\n" % {"default": self.image_label(self.default).replace(" ", "")}) self.write_config_password(config) def write_config_password(self, config): if self.password: config.write("menu master passwd %s\n" % self.password) config.write("menu notabmsg Press [Tab] and enter the password to edit options") def write_config_post(self): etc_extlinux = os.path.normpath(conf.target.system_root + "/etc/" + self._config_file) if not os.access(etc_extlinux, os.R_OK): try: os.symlink("../boot/%s" % self._config_file, etc_extlinux) except OSError as e: log.warning("failed to create /etc/extlinux.conf symlink: %s", e) # # installation # def install(self, args=None): args = ["--install", self._config_dir] rc = execWithRedirect("extlinux", args, root=conf.target.system_root) if rc: raise BootLoaderError("boot loader install failed")