127 lines
5 KiB
Python
127 lines
5 KiB
Python
#
|
|
# 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")
|