Source

vinstall / vinstall / controller / bootloader.py

Full commit
#-*- coding: utf-8 -*-

"""Bootloader options for the Vector installer

"""


import os
from itertools import chain
from vinstall.backend import bootloader, utils, sp
from vinstall.backend.media import Disk, Partition
from vinstall.core import Render, Controller, model, log


LOG = log.get_logger("bootloader")


class Bootloader(Controller):
    """Select a bootloader

    """
    def init(self):
        """Find the disks available in the system.

        """
        self.disks = [ i for i in Disk.all() if not i.is_read_only() ]
        self.partitions = [ i for i in Partition.all() if i.query_filesystem()
                != "xfs" ]
        self.targets = self.disks + self.partitions
        self.bootloaders = [ u"Lilo", u"Grub2", u"None" ]

    def render(self):
        """Show bootloader options

        """
        title = u"Bootloader"
        intro = u"Select a bootloader to boot your system"

        bootloaders = model.DropdownOptionList()
        bootloaders.label = u"Select a bootloader"
        for i in self.bootloaders:
            bootloaders.add_option(i)

        location = model.DropdownOptionList()
        location.label = u"Install the bootloader in"
        for i in self.targets:
            location.add_option(unicode(i))

        return Render(title, intro, bootloaders, location)

    def next(self):
        """Return next step

        """
        return None

    def previous(self):
        """Return previous step

        """
        from vinstall.controller import usersetup
        return usersetup.UserSetup

    def command(self, bootloader, target):
        """Schedule command for later execution

        """
        LOG.debug("Bootloader: %s", bootloader)
        LOG.debug("Target; %s", target)
        yield self.set_bind_mounts, tuple(), "Mounting pseudo filesystems"
        yield self.install_bootloader, (bootloader, target), "Installing bootloader"
        yield self.clear_bind_mounts, tuple(), "Clearing bind mounts"

    def install_bootloader(self, bloader, target):
        """Install the bootloader

        """
        bloader = self.bootloaders[bloader]
        disk = self.targets[target]
        target = disk.path()

        if bloader.lower() == "lilo":
            self.install_lilo(target)
        elif bloader == "Grub2":
            self.install_grub(target)
        else:
            return

    def install_lilo(self, target):
        """ Install LILO to target

        """
        LOG.debug("Installing LILO to %s", target)
        lilo = bootloader.Lilo(target)
        for system in bootloader.OperatingSystem.all():
            lilo.add_os(system)
        with utils.Chroot("/mnt/TARGET"):
            self.mkinitrd()
            lilo.backup_config()
            lilo.write_config()
            lilo.install()

    def install_grub(self, target):
        """ Install Grub2 to target

        """
        LOG.debug("Installing Grub2 to %s", target)
        grub2 = bootloader.Grub2(target)
        with utils.Chroot("/mnt/TARGET"):
            self.mkinitrd()
            grub2.backup_config()
            grub2.install()
            grub2.write_config()

    def mkinitrd(self):
        LOG.debug("Creating initrd")
        command = "mkinitrd -c -u -m i810:i915:intel:nouveau:radeon:vmwgfx"
        try:
            sp.call(command.split())
        except Exception as e:
            # initrd not supported
            LOG.info("Initrd not supported: %s", e)

    def set_bind_mounts(self):
        """Bind mount some paths into the target.
        Later steps will need this when we chroot there

        """
        LOG.debug("Bind mounting filesystems")
        for point in ("sys","proc","dev"):
            cmd = "mount -o bind /%s /mnt/TARGET/%s" % (point, point)
            sp.check_call(cmd.split())

    def clear_bind_mounts(self):
        """Clear the mountpoints that were mounted for the configuration

        """
        for mpoint in ("sys","proc","dev"):
            cmd = "umount -f /mnt/TARGET/%s" % mpoint
            sp.check_call(cmd.split())