def get_grub_path(root_path, filename, raise_on_error=True): """ Provides grub path to given search file Depending on the distribution grub could be installed below a grub2 or grub directory. grub could also reside in /usr/lib as well as in /usr/share. Therefore this information needs to be dynamically looked up :param string root_path: root path to start the lookup from :param string filename: filename to search :param bool raise_on_error: raise on not found, defaults to True The method returns the path to the given grub search file. By default it raises a KiwiBootLoaderGrubDataError exception if the file could not be found in any of the search locations. If raise_on_error is set to False and no file could be found the function returns None :return: filepath :rtype: str """ install_dirs = ['usr/share', 'usr/lib'] lookup_list = [] for grub_name in ['grub2', 'grub']: for install_dir in install_dirs: grub_path = os.path.join(root_path, install_dir, grub_name, filename) if os.path.exists(grub_path): return grub_path lookup_list.append(grub_path) if raise_on_error: raise KiwiBootLoaderGrubDataError( 'grub path {0} not found in {1}'.format(filename, lookup_list))
def _find_grub_data(self, lookup_path): grub_path = Defaults.get_grub_path(lookup_path) if grub_path: return grub_path raise KiwiBootLoaderGrubDataError('No grub2 installation found in %s' % lookup_path)
def install(self): """ Install bootloader on disk device """ log.info('Installing grub2 on disk %s', self.device) if self.target_removable: self.install_arguments.append('--removable') if self.arch == 'x86_64' or self.arch == 'i686' or self.arch == 'i586': self.target = 'i386-pc' self.install_device = self.device self.modules = ' '.join( Defaults.get_grub_bios_modules(multiboot=True)) self.install_arguments.append('--skip-fs-probe') elif self.arch.startswith('ppc64'): if not self.custom_args or 'prep_device' not in self.custom_args: raise KiwiBootLoaderGrubInstallError( 'prep device name required for grub2 installation on ppc') self.target = 'powerpc-ieee1275' self.install_device = self.custom_args['prep_device'] self.modules = ' '.join(Defaults.get_grub_ofw_modules()) self.install_arguments.append('--skip-fs-probe') self.install_arguments.append('--no-nvram') else: raise KiwiBootLoaderGrubPlatformError( 'host architecture %s not supported for grub2 installation' % self.arch) self.root_mount = MountManager(device=self.custom_args['root_device']) self.boot_mount = MountManager(device=self.custom_args['boot_device'], mountpoint=self.root_mount.mountpoint + '/boot') self.root_mount.mount() if not self.root_mount.device == self.boot_mount.device: self.boot_mount.mount() if self.volumes: for volume_path in Path.sort_by_hierarchy( sorted(self.volumes.keys())): volume_mount = MountManager( device=self.volumes[volume_path]['volume_device'], mountpoint=self.root_mount.mountpoint + '/' + volume_path) self.volumes_mount.append(volume_mount) volume_mount.mount( options=[self.volumes[volume_path]['volume_options']]) self.device_mount = MountManager( device='/dev', mountpoint=self.root_mount.mountpoint + '/dev') self.proc_mount = MountManager(device='/proc', mountpoint=self.root_mount.mountpoint + '/proc') self.sysfs_mount = MountManager(device='/sys', mountpoint=self.root_mount.mountpoint + '/sys') self.device_mount.bind_mount() self.proc_mount.bind_mount() self.sysfs_mount.bind_mount() # check if a grub installation could be found in the image system grub_directory = Defaults.get_grub_path(self.root_mount.mountpoint + '/usr/lib') if not grub_directory: raise KiwiBootLoaderGrubDataError( 'No grub2 installation found in %s' % self.root_mount.mountpoint) grub_directory = grub_directory.replace(self.root_mount.mountpoint, '') module_directory = grub_directory + '/' + self.target boot_directory = '/boot' # wipe existing grubenv to allow the grub installer to create a new one grubenv_glob = os.sep.join( [self.root_mount.mountpoint, 'boot', '*', 'grubenv']) for grubenv in glob.glob(grubenv_glob): Path.wipe(grubenv) # install grub2 boot code Command.run([ 'chroot', self.root_mount.mountpoint, self._get_grub2_install_tool_name(self.root_mount.mountpoint) ] + self.install_arguments + [ '--directory', module_directory, '--boot-directory', boot_directory, '--target', self.target, '--modules', self.modules, self.install_device ]) if self.firmware and self.firmware.efi_mode() == 'uefi': shim_install = self._get_shim_install_tool_name( self.root_mount.mountpoint) # if shim-install does _not_ exist the fallback mechanism # has applied at the bootloader/config level and we expect # no further tool calls to be required if shim_install: self.efi_mount = MountManager( device=self.custom_args['efi_device'], mountpoint=self.root_mount.mountpoint + '/boot/efi') self.efi_mount.mount() # Before we call shim-install, the grub installer binary is # replaced by a noop. Actually there is no reason for # shim-install to call the grub installer because it should # only setup the system for EFI secure boot which does not # require any bootloader code in the master boot record. # In addition kiwi has called the grub installer right # before self._disable_grub2_install(self.root_mount.mountpoint) Command.run([ 'chroot', self.root_mount.mountpoint, 'shim-install', '--removable', self.install_device ]) # restore the grub installer noop self._enable_grub2_install(self.root_mount.mountpoint)
def install(self): """ Install bootloader on disk device """ log.info('Installing grub2 on disk %s', self.device) if self.target_removable: self.install_arguments.append('--removable') if Defaults.is_x86_arch(self.arch): self.target = 'i386-pc' self.install_device = self.device self.modules = ' '.join( Defaults.get_grub_bios_modules(multiboot=True)) self.install_arguments.append('--skip-fs-probe') elif self.arch.startswith('ppc64'): if not self.custom_args or 'prep_device' not in self.custom_args: raise KiwiBootLoaderGrubInstallError( 'prep device name required for grub2 installation on ppc') self.target = 'powerpc-ieee1275' self.install_device = self.custom_args['prep_device'] self.modules = ' '.join(Defaults.get_grub_ofw_modules()) self.install_arguments.append('--skip-fs-probe') self.install_arguments.append('--no-nvram') elif self.arch.startswith('s390'): self.target = 's390x-emu' self.install_device = self.device self.modules = ' '.join(Defaults.get_grub_s390_modules()) self.install_arguments.append('--skip-fs-probe') self.install_arguments.append('--no-nvram') else: raise KiwiBootLoaderGrubPlatformError( 'host architecture %s not supported for grub2 installation' % self.arch) self._mount_device_and_volumes() # check if a grub installation could be found in the image system module_directory = Defaults.get_grub_path(self.root_mount.mountpoint, self.target, raise_on_error=False) if not module_directory: raise KiwiBootLoaderGrubDataError( 'No grub2 installation found in {0} for target {1}'.format( self.root_mount.mountpoint, self.target)) module_directory = module_directory.replace(self.root_mount.mountpoint, '') boot_directory = '/boot' # wipe existing grubenv to allow the grub installer to create a new one grubenv_glob = os.sep.join( [self.root_mount.mountpoint, 'boot', '*', 'grubenv']) for grubenv in glob.glob(grubenv_glob): Path.wipe(grubenv) # install grub2 boot code if self.firmware.get_partition_table_type() == 'dasd': # On s390 and in CDL mode (4k DASD) the call of grub2-install # does not work because grub2-install is not able to identify # a 4k fdasd partitioned device as a grub supported device # and fails. As grub2-install is only used to invoke # grub2-zipl-setup and has no other job to do we can # circumvent this problem by directly calling grub2-zipl-setup # instead. Command.run([ 'chroot', self.root_mount.mountpoint, 'grub2-zipl-setup', '--keep' ]) zipl_config_file = ''.join( [self.root_mount.mountpoint, '/boot/zipl/config']) zipl2grub_config_file_orig = ''.join([ self.root_mount.mountpoint, '/etc/default/zipl2grub.conf.in.orig' ]) if os.path.exists(zipl2grub_config_file_orig): Command.run([ 'mv', zipl2grub_config_file_orig, zipl2grub_config_file_orig.replace('.orig', '') ]) if os.path.exists(zipl_config_file): Command.run( ['mv', zipl_config_file, zipl_config_file + '.kiwi']) else: Command.run([ 'chroot', self.root_mount.mountpoint, self._get_grub2_install_tool_name(self.root_mount.mountpoint) ] + self.install_arguments + [ '--directory', module_directory, '--boot-directory', boot_directory, '--target', self.target, '--modules', self.modules, self.install_device ])
def install(self): # noqa: C901 """ Install bootloader on disk device """ log.info('Installing grub2 on disk %s', self.device) if self.target_removable: self.install_arguments.append('--removable') if Defaults.is_x86_arch(self.arch): self.target = 'i386-pc' self.install_device = self.device self.modules = ' '.join( Defaults.get_grub_bios_modules(multiboot=True) ) self.install_arguments.append('--skip-fs-probe') elif self.arch.startswith('ppc64'): if not self.custom_args or 'prep_device' not in self.custom_args: raise KiwiBootLoaderGrubInstallError( 'prep device name required for grub2 installation on ppc' ) self.target = 'powerpc-ieee1275' self.install_device = self.custom_args['prep_device'] self.modules = ' '.join(Defaults.get_grub_ofw_modules()) self.install_arguments.append('--skip-fs-probe') self.install_arguments.append('--no-nvram') elif self.arch.startswith('s390'): self.target = 's390x-emu' self.install_device = self.device self.modules = ' '.join(Defaults.get_grub_s390_modules()) self.install_arguments.append('--skip-fs-probe') self.install_arguments.append('--no-nvram') else: raise KiwiBootLoaderGrubPlatformError( 'host architecture %s not supported for grub2 installation' % self.arch ) self.root_mount = MountManager( device=self.custom_args['root_device'] ) if 's390' in self.arch: self.boot_mount = MountManager( device=self.custom_args['boot_device'], mountpoint=self.root_mount.mountpoint + '/boot/zipl' ) else: self.boot_mount = MountManager( device=self.custom_args['boot_device'], mountpoint=self.root_mount.mountpoint + '/boot' ) if self.custom_args.get('efi_device'): self.efi_mount = MountManager( device=self.custom_args['efi_device'], mountpoint=self.root_mount.mountpoint + '/boot/efi' ) self.root_mount.mount() if not self.root_mount.device == self.boot_mount.device: self.boot_mount.mount() if self.efi_mount: self.efi_mount.mount() if self.volumes: for volume_path in Path.sort_by_hierarchy( sorted(self.volumes.keys()) ): volume_mount = MountManager( device=self.volumes[volume_path]['volume_device'], mountpoint=self.root_mount.mountpoint + '/' + volume_path ) self.volumes_mount.append(volume_mount) volume_mount.mount( options=[self.volumes[volume_path]['volume_options']] ) self.device_mount = MountManager( device='/dev', mountpoint=self.root_mount.mountpoint + '/dev' ) self.proc_mount = MountManager( device='/proc', mountpoint=self.root_mount.mountpoint + '/proc' ) self.sysfs_mount = MountManager( device='/sys', mountpoint=self.root_mount.mountpoint + '/sys' ) self.device_mount.bind_mount() self.proc_mount.bind_mount() self.sysfs_mount.bind_mount() # check if a grub installation could be found in the image system module_directory = Defaults.get_grub_path( self.root_mount.mountpoint, self.target, raise_on_error=False ) if not module_directory: raise KiwiBootLoaderGrubDataError( 'No grub2 installation found in {0} for target {1}'.format( self.root_mount.mountpoint, self.target ) ) module_directory = module_directory.replace( self.root_mount.mountpoint, '' ) boot_directory = '/boot' # wipe existing grubenv to allow the grub installer to create a new one grubenv_glob = os.sep.join( [self.root_mount.mountpoint, 'boot', '*', 'grubenv'] ) for grubenv in glob.glob(grubenv_glob): Path.wipe(grubenv) # install grub2 boot code if self.firmware.get_partition_table_type() == 'dasd': # On s390 and in CDL mode (4k DASD) the call of grub2-install # does not work because grub2-install is not able to identify # a 4k fdasd partitioned device as a grub supported device # and fails. As grub2-install is only used to invoke # grub2-zipl-setup and has no other job to do we can # circumvent this problem by directly calling grub2-zipl-setup # instead. Command.run( [ 'chroot', self.root_mount.mountpoint, 'grub2-zipl-setup', '--keep' ] ) zipl_config_file = ''.join( [ self.root_mount.mountpoint, '/boot/zipl/config' ] ) zipl2grub_config_file_orig = ''.join( [ self.root_mount.mountpoint, '/etc/default/zipl2grub.conf.in.orig' ] ) if os.path.exists(zipl2grub_config_file_orig): Command.run( [ 'mv', zipl2grub_config_file_orig, zipl2grub_config_file_orig.replace('.orig', '') ] ) if os.path.exists(zipl_config_file): Command.run( ['mv', zipl_config_file, zipl_config_file + '.kiwi'] ) else: Command.run( [ 'chroot', self.root_mount.mountpoint, self._get_grub2_install_tool_name( self.root_mount.mountpoint ) ] + self.install_arguments + [ '--directory', module_directory, '--boot-directory', boot_directory, '--target', self.target, '--modules', self.modules, self.install_device ] ) if self.firmware and self.firmware.efi_mode() == 'uefi': shim_install = self._get_shim_install_tool_name( self.root_mount.mountpoint ) # if shim-install does _not_ exist the fallback mechanism # has applied at the bootloader/config level and we expect # no further tool calls to be required if shim_install: # Before we call shim-install, the grub installer binary is # replaced by a noop. Actually there is no reason for # shim-install to call the grub installer because it should # only setup the system for EFI secure boot which does not # require any bootloader code in the master boot record. # In addition kiwi has called the grub installer right # before self._disable_grub2_install(self.root_mount.mountpoint) Command.run( [ 'chroot', self.root_mount.mountpoint, 'shim-install', '--removable', self.install_device ] ) # restore the grub installer noop self._enable_grub2_install(self.root_mount.mountpoint)