Ack with one change. The package that contains zipl is 's390utils-base' not 'zipl' because, you know, the latter would make sense. David Lehman <dlehman@xxxxxxxxxx> wrote: > --- > pyanaconda/bootloader.py | 211 ++++++++++++++++++++++++++++++++++++++++++---- > 1 files changed, 194 insertions(+), 17 deletions(-) > > diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py > index eb8f799..96f337a 100644 > --- a/pyanaconda/bootloader.py > +++ b/pyanaconda/bootloader.py > @@ -177,10 +177,23 @@ class LinuxBootLoaderImage(BootLoaderImage): > > class BootLoader(object): > """TODO: > + - simplify choices to (mbr|boot device)? > + - mbr is mbr of msdos disklabel > + - boot device is one of: > + - /boot (regardless of type) on non-EFI x86 > + - GPT boot partition > + - EFI system partition or md > + - PReP partition > + > - iSeries bootloader? > - same as pSeries, except optional, I think > - upgrade of non-grub bootloaders > - detection of existing bootloaders > + - improve password encryption for grub > + - fix handling of kickstart-provided already-encrypted > + password > + - consider re-implementing ArgumentList as something else, like > + perhaps collections.OrderedDict > - resolve overlap between Platform checkFoo methods and > _is_valid_target_device and _is_valid_boot_device > - split certain parts of _is_valid_target_device and > @@ -854,12 +867,10 @@ class GRUB(BootLoader): > def grub_conf_device_line(self): > return "" > > - def write_config_console(self, config): > - """ Write console-related configuration. """ > - if not self.console: > - return > - > - if self.console.startswith("ttyS"): > + @property > + def serial_command(self): > + command = "" > + if self.console and self.console.startswith("ttyS"): > unit = self.console[-1] > speed = "9600" > for opt in self.console_options.split(","): > @@ -867,7 +878,17 @@ class GRUB(BootLoader): > speed = opt > break > > - config.write("serial --unit=%s --speed=%s\n" % (unit, speed)) > + command = "serial --unit=%s --speed=%s" % (unit, speed) > + > + return command > + > + def write_config_console(self, config): > + """ Write console-related configuration. """ > + if not self.console: > + return > + > + if self.console.startswith("ttyS"): > + config.write("%s\n" % self.serial_command) > config.write("terminal --timeout=%s serial console\n" > % self.timeout) > > @@ -1030,16 +1051,11 @@ class GRUB(BootLoader): > # installation > # > > - def install(self, install_root=""): > - rc = iutil.execWithRedirect("grub-install", ["--just-copy"], > - stdout="/dev/tty5", stderr="/dev/tty5", > - root=install_root) > - if rc: > - raise BootLoaderError("bootloader install failed") > - > - boot = self.stage2_device > + @property > + def install_targets(self): > + """ List of (stage1, stage2) tuples representing install targets. """ > targets = [] > - if boot.type != "mdarray": > + if self.stage2_device.type != "mdarray": > targets.append((self.stage1_device, self.stage2_device)) > else: > if [d for d in self.stage2_device.parents if d.type != "partition"]: > @@ -1070,7 +1086,16 @@ class GRUB(BootLoader): > > targets.append((stage1dev, stage2dev)) > > - for (stage1dev, stage2dev) in targets: > + return targets > + > + def install(self, install_root=""): > + rc = iutil.execWithRedirect("grub-install", ["--just-copy"], > + stdout="/dev/tty5", stderr="/dev/tty5", > + root=install_root) > + if rc: > + raise BootLoaderError("bootloader install failed") > + > + for (stage1dev, stage2dev) in self.install_targets: > cmd = ("root %(stage2dev)s\n" > "install --stage2=%(config_dir)s/stage2" > " /%(grub_config_dir)s/stage1 d %(stage1dev)s" > @@ -1206,6 +1231,157 @@ class EFIGRUB(GRUB): > def update(self, install_root=""): > self.write(install_root=install_root) > > +class GRUB2(GRUB): > + """ GRUBv2 > + > + - configuration > + - password (insecure), password_pbkdf2 > + - http://www.gnu.org/software/grub/manual/grub.html#Invoking-grub_002dmkpasswd_002dpbkdf2 > + - --users per-entry specifies which users can access, otherwise > + entry is unrestricted > + - /etc/grub/custom.cfg > + > + - how does grub resolve names of md arrays? > + > + - disable automatic use of grub-mkconfig? > + - on upgrades? > + > + - BIOS boot partition (GPT) > + - parted /dev/sda set <partition_number> bios_grub on > + - can't contain a filesystem > + - 31KiB min, 1MiB recommended > + > + """ > + name = "GRUB2" > + packages = ["grub2", "gettext"] > + _config_file = "grub.cfg" > + _config_dir = "grub2" > + config_file_mode = 0600 > + defaults_file = "/etc/default/grub" > + can_dual_boot = True > + can_update = True > + > + # requirements for bootloader target devices > + target_device_types = ["disk", "partition", "mdarray"] > + target_device_raid_levels = [mdraid.RAID1] > + target_device_format_types = [] > + target_device_disklabel_types = ["msdos", "gpt"] > + target_device_mountpoints = ["/boot", "/"] > + > + # for UI use, eg: "mdarray": N_("RAID Device") > + target_descriptions = {"msdos": N_("Master Boot Record"), > + "partition": N_("First sector of boot partition"), > + "mdarray": N_("RAID Device")} > + > + # these are disklabel-specific descriptions for stage1 targets > + partition_descriptions = {"msdos": N_("First sector of boot partition"), > + "gpt": N_("BIOS boot partition")} > + > + # requirements for boot devices > + boot_device_types = ["partition", "mdarray", "lvmlv"] > + boot_device_raid_levels = [mdraid.RAID4, mdraid.RAID1, mdraid.RAID4, > + mdraid.RAID5, mdraid.RAID6, mdraid.RAID10] > + boot_device_format_types = ["ext4", "ext3", "ext2"] > + boot_device_mountpoints = ["/boot", "/"] > + boot_device_min_size = 50 > + boot_device_max_size = None > + non_linux_boot_device_format_types = [] > + > + # > + # grub-related conveniences > + # > + > + def grub_device_name(self, device): > + """ Return a grub-friendly representation of device. > + > + Disks and partitions use the (hdX,Y) notation, while lvm and > + md devices just use their names. > + """ > + drive = None > + name = device.name > + > + if device.isDisk: > + drive = device > + elif hasattr(device, "disk"): > + drive = device.disk > + > + if drive is not None: > + name = "(hd%d" % self.drives.index(drive) > + if hasattr(device, "disk"): > + name += ",%d" % device.partedPartition.number > + name += ")" > + return name > + > + def device_description(self, device): > + idx = self._device_type_index(device, self.target_device_types) > + if idx is None: > + raise ValueError("'%s' not a valid stage1 type" % device.type) > + > + label_type = device.disks[0].format.labelType > + if device.isDisk: > + desc = self.target_descriptions[label_type] > + elif device.type == "partition": > + desc = self.partition_descriptions[label_type] > + else: > + desc = super(GRUB2, self).device_description(device) > + > + return desc > + > + def write_defaults(self, install_root=""): > + defaults_file = "%s%s" % (install_root, self.defaults_file) > + defaults = open(defaults_file, "w+") > + defaults.write("GRUB_TIMEOUT=%d\n" % self.timeout) > + defaults.write("GRUB_DISTRIBUTOR=\"%s\"\n" % productName) > + if self.console and self.console.startswith("ttyS"): > + defaults.write("GRUB_TERMINAL=\"serial console\"\n") > + defaults.write("GRUB_SERIAL_COMMAND=\"%s\"\n" % self.serial_command) > + defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args) > + defaults.close() > + > + def write_password_config(self, install_root=""): > + if not self.password: > + return > + > + # FIXME: this is useless since we currently have no way to propagate > + # --users="" to each menu entry > + header = open(install_root + "/etc/grub.d/01_users", "w") > + header.write("#!/bin/sh -e\n\n") > + header.write("cat << EOF\n") > + header.write("set superusers=\"root\"\n") > + if self.encrypt_password: > + password = "password_pbkdf2 root " + self.encrypted_password > + else: > + password = "password root " + self.password > + > + header.write("%s\n" % password) > + header.write("EOF\n") > + header.close() > + > + def write_config(self, install_root=""): > + self.write_device_map(install_root=install_root) > + self.write_defaults(install_root=install_root) > + self.write_password_config(install_root=install_root) > + rc = iutil.execWithRedirect("grub2-mkconfig", > + ["-o", self.config_file], > + root=install_root, > + stdout="/dev/tty5", stderr="/dev/tty5") > + if rc: > + raise BootLoaderError("failed to write bootloader configuration") > + > + # > + # installation > + # > + > + def install(self, install_root=""): > + # XXX will installing to multiple drives work as expected with GRUBv2? > + for (stage1dev, stage2dev) in self.install_targets: > + rc = iutil.execWithRedirect("grub2-install", > + [self.grub_device_name(stage1dev)], > + stdout="/dev/tty5", stderr="/dev/tty5", > + root=install_root) > + if rc: > + raise BootLoaderError("bootloader install failed") > + > > class YabootSILOBase(BootLoader): > def write_config_password(self, config): > @@ -1395,6 +1571,7 @@ class MacYaboot(Yaboot): > class ZIPL(BootLoader): > name = "ZIPL" > config_file = "/etc/zipl.conf" > + packages = ["zipl"] > > # list of strings representing options for bootloader target device types > target_device_types = ["disk", "partition"] > -- > 1.7.3.4 > > _______________________________________________ > Anaconda-devel-list mailing list > Anaconda-devel-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/anaconda-devel-list -- David Cantrell <dcantrell@xxxxxxxxxx> Supervisor, Installer Engineering Team Red Hat, Inc. | Seattle, WA | UTC-7 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list