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)
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.")
def _add_single_efi_boot_target(self, partition): boot_disk = partition.disk boot_part_num = str(partition.parted_partition.number) # Disable writing to efi nvram # 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=util.getSysroot() # ) rc = self.efibootmgr() if rc: raise BootLoaderError( "Failed to set new efi boot target. This is most " "likely a kernel or firmware bug.")
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.execInSysroot("grub2-set-default", [default_entry]) 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.execInSysroot("grub2-editenv", ["-", "set", "menu_auto_hide=1", "boot_success=1"]) if rc: log.error("failed to set menu_auto_hide=1") # now tell grub2 to generate the main configuration file rc = util.execInSysroot("grub2-mkconfig", ["-o", self.config_file]) if rc: raise BootLoaderError("failed to write boot loader configuration")
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.")
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")
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.")
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")
def install(self, args=None): args = ["--install", self._config_dir] rc = util.execInSysroot("extlinux", args) if rc: raise BootLoaderError("boot loader install failed")