Esempio n. 1
0
    def _check_boot_drive(self, storage, boot_drive, usable_disks):
        """Check the specified boot drive."""
        # Resolve the disk identifier.
        matched_disks = device_matches(boot_drive, devicetree=storage.devicetree, disks_only=True)

        if not matched_disks:
            raise BootLoaderError(_("No match found for given boot drive "
                                    "\"{}\".").format(boot_drive))

        if len(matched_disks) > 1:
            raise BootLoaderError(_("More than one match found for given boot drive "
                                    "\"{}\".").format(boot_drive))

        if matched_disks[0] not in usable_disks:
            raise BootLoaderError(_("Requested boot drive \"{}\" doesn't exist or cannot "
                                    "be used.").format(boot_drive))
Esempio n. 2
0
    def install(self, args=None):
        buf = util.execWithCapture("zipl", [], root=conf.target.system_root)
        for line in buf.splitlines():
            if line.startswith("Preparing boot device: "):
                # Output here may look like:
                #     Preparing boot device: dasdb (0200).
                #     Preparing boot device: dasdl.
                # We want to extract the device name and pass that.
                name = re.sub(r".+?: ", "", line)
                self.stage1_name = re.sub(r"(\s\(.+\))?\.$", "", name)
            # a limitation of s390x is that the kernel parameter list must not
            # exceed 896 bytes; there is nothing we can do about this, so just
            # catch the error and show it to the user instead of crashing
            elif line.startswith("Error: The length of the parameters "):
                raise BootLoaderError(line)

        if not self.stage1_name:
            raise BootLoaderError("could not find IPL device")

        # do the reipl
        util.reIPL(self.stage1_name)
Esempio n. 3
0
    def _add_single_efi_boot_target(self, partition):
        boot_disk = partition.disk
        boot_part_num = str(partition.parted_partition.number)

        rc = self.efibootmgr(
            "-c", "-w", "-L", productName.split("-")[0],  # pylint: disable=no-member
            "-d", boot_disk.path, "-p", boot_part_num,
            "-l", self.efi_dir_as_efifs_dir + self._efi_binary,  # pylint: disable=no-member
            root=conf.target.system_root
        )
        if rc:
            raise BootLoaderError("Failed to set new efi boot target. This is most "
                                  "likely a kernel or firmware bug.")
Esempio n. 4
0
    def write_config(self):
        config_path = "%s%s" % (conf.target.system_root, self.efi_config_file)

        with open(config_path, "w") as fd:
            grub_dir = self.config_dir
            if self.stage2_device.format.type != "btrfs":
                fs_uuid = self.stage2_device.format.uuid
            else:
                fs_uuid = self.stage2_device.format.vol_uuid

            if fs_uuid is None:
                raise BootLoaderError("Could not get stage2 filesystem UUID")

            grub_dir = util.execWithCapture("grub2-mkrelpath", [grub_dir],
                                            root=conf.target.system_root)
            if not grub_dir:
                raise BootLoaderError("Could not get GRUB directory path")

            fd.write("search --no-floppy --fs-uuid --set=dev %s\n" % fs_uuid)
            fd.write("set prefix=($dev)%s\n" % grub_dir)
            fd.write("export $prefix\n")
            fd.write("configfile $prefix/grub.cfg\n")

        super().write_config()
Esempio n. 5
0
    def write_config(self):
        self.write_config_console(None)
        # See if we have a password and if so update the boot args before we
        # write out the defaults file.
        if self.password or self.encrypted_password:
            self.boot_args.add("rd.shell=0")
        self.write_defaults()

        # if we fail to setup password auth we should complete the
        # installation so the system is at least bootable
        try:
            self.write_password_config()
        except (BootLoaderError, OSError, RuntimeError) as e:
            log.error("boot loader password setup failed: %s", e)

        # make sure the default entry is the OS we are installing
        if self.default is not None:
            machine_id_path = conf.target.system_root + "/etc/machine-id"
            if not os.access(machine_id_path, os.R_OK):
                log.error("failed to read machine-id, default entry not set")
                return

            with open(machine_id_path, "r") as fd:
                machine_id = fd.readline().strip()

            default_entry = "%s-%s" % (machine_id, self.default.version)
            rc = util.execWithRedirect("grub2-set-default", [default_entry],
                                       root=conf.target.system_root)
            if rc:
                log.error("failed to set default menu entry to %s",
                          productName)

        # set menu_auto_hide grubenv variable if we should enable menu_auto_hide
        # set boot_success so that the menu is hidden on the boot after install
        if conf.bootloader.menu_auto_hide:
            rc = util.execWithRedirect(
                "grub2-editenv",
                ["-", "set", "menu_auto_hide=1", "boot_success=1"],
                root=conf.target.system_root)
            if rc:
                log.error("failed to set menu_auto_hide=1")

        # now tell grub2 to generate the main configuration file
        rc = util.execWithRedirect("grub2-mkconfig", ["-o", self.config_file],
                                   root=conf.target.system_root)
        if rc:
            raise BootLoaderError("failed to write boot loader configuration")
Esempio n. 6
0
    def remove_efi_boot_target(self):
        buf = self.efibootmgr(capture=True)
        for line in buf.splitlines():
            try:
                (slot, _product) = line.split(None, 1)
            except ValueError:
                continue

            if _product == productName.split("-")[0]:           # pylint: disable=no-member
                slot_id = slot[4:8]
                # slot_id is hex, we can't use .isint and use this regex:
                if not re.match("^[0-9a-fA-F]+$", slot_id):
                    log.warning("failed to parse efi boot slot (%s)", slot)
                    continue

                rc = self.efibootmgr("-b", slot_id, "-B")
                if rc:
                    raise BootLoaderError("Failed to remove old efi boot entry. This is most "
                                          "likely a kernel or firmware bug.")
Esempio n. 7
0
    def _encrypt_password(self):
        """Make sure self.encrypted_password is set up properly."""
        if self.encrypted_password:
            return

        if not self.password:
            raise RuntimeError("cannot encrypt empty password")

        (pread, pwrite) = os.pipe()
        passwords = "%s\n%s\n" % (self.password, self.password)
        os.write(pwrite, passwords.encode("utf-8"))
        os.close(pwrite)
        buf = util.execWithCapture("grub2-mkpasswd-pbkdf2", [],
                                   stdin=pread,
                                   root=conf.target.system_root)
        os.close(pread)
        self.encrypted_password = buf.split()[-1].strip()
        if not self.encrypted_password.startswith("grub.pbkdf2."):
            raise BootLoaderError("failed to encrypt boot loader password")
Esempio n. 8
0
    def _get_boot_drive(self, storage, bootloader_proxy):
        """Get the boot drive.

        When bootloader doesn't have --boot-drive parameter then use this logic as fallback:

        1) If present, use the first valid disk from driveorder parameter.
        2) If present and usable, use a disk where a valid stage1 device is placed.
        3) Use the first usable disk from Blivet if there is one.
        4) Raise an exception.
        """
        boot_drive = bootloader_proxy.Drive
        drive_order = storage.bootloader.disk_order
        usable_disks_list = self._get_usable_disks(storage)
        usable_disks_set = set(usable_disks_list)

        # Use a disk from --boot-drive.
        if boot_drive:
            log.debug("Use the requested boot drive.")
            self._check_boot_drive(storage, boot_drive, usable_disks_set)
            return boot_drive

        # Or use the first disk from --driveorder.
        if drive_order:
            log.debug("Use the first usable drive from the drive order.")
            return drive_order[0]

        # Or find a disk with a valid stage1 device.
        found_drive = self._find_drive_with_stage1(storage, usable_disks_set)
        if found_drive:
            log.debug("Use a usable drive with a valid stage1 device.")
            return found_drive

        # Or use the first usable drive.
        if usable_disks_list:
            log.debug("Use the first usable drive.")
            return usable_disks_list[0]

        # Or raise an exception.
        raise BootLoaderError("No usable boot drive was found.")
Esempio n. 9
0
    def install(self, args=None):
        if args is None:
            args = []

        # XXX will installing to multiple drives work as expected with GRUBv2?
        for (stage1dev, stage2dev) in self.install_targets:
            grub_args = args + ["--no-floppy", stage1dev.path]
            if stage1dev == stage2dev:
                # This is hopefully a temporary hack. GRUB2 currently refuses
                # to install to a partition's boot block without --force.
                grub_args.insert(0, '--force')
            else:
                if self.keep_mbr:
                    grub_args.insert(0, '--grub-setup=/bin/true')
                    log.info("bootloader.py: mbr update by grub2 disabled")
                else:
                    log.info("bootloader.py: mbr will be updated for grub2")

            rc = util.execWithRedirect("grub2-install", grub_args,
                                       root=conf.target.system_root,
                                       env_prune=['MALLOC_PERTURB_'])
            if rc:
                raise BootLoaderError("boot loader install failed")
Esempio n. 10
0
    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")
Esempio n. 11
0
    def install(self, args=None):
        args = ["--install", self._config_dir]
        rc = util.execInSysroot("extlinux", args)

        if rc:
            raise BootLoaderError("boot loader install failed")