Source code for kiwi.boot.image.dracut

# Copyright (c) 2015 SUSE Linux GmbH.  All rights reserved.
#
# This file is part of kiwi.
#
# kiwi is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kiwi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kiwi.  If not, see <http://www.gnu.org/licenses/>
#
import os
import logging

# project
from kiwi.command import Command
from kiwi.system.kernel import Kernel
from kiwi.boot.image.base import BootImageBase
from kiwi.defaults import Defaults
from kiwi.system.profile import Profile
from kiwi.system.setup import SystemSetup

log = logging.getLogger('kiwi')


[docs]class BootImageDracut(BootImageBase): """ **Implements creation of dracut boot(initrd) images.** """
[docs] def post_init(self): """ Post initialization method Initialize empty list of dracut caller options """ self.dracut_options = [] self.included_files = [] self.included_files_install = [] self.modules = [] self.install_modules = [] self.omit_modules = [] self.omit_install_modules = [] self.available_modules = self._get_modules()
[docs] def include_file(self, filename, install_media=False): """ Include file to dracut boot image :param string filename: file path name """ self.included_files.append('--install') self.included_files.append(filename) if install_media: self.included_files_install.append('--install') self.included_files_install.append(filename)
[docs] def include_module(self, module, install_media=False): """ Include module to dracut boot image :param string module: module to include :param bool install_media: include the module for install initrds """ warn_msg = 'module "{0}" not included in initrd'.format(module) if self._module_available(module): if install_media and module not in self.install_modules: self.install_modules.append(module) elif module not in self.modules: self.modules.append(module) else: log.warning(warn_msg)
[docs] def omit_module(self, module, install_media=False): """ Omit module to dracut boot image :param string module: module to omit :param bool install_media: omit the module for install initrds """ if install_media and module not in self.omit_install_modules: self.omit_install_modules.append(module) elif module not in self.omit_modules: self.omit_modules.append(module)
[docs] def write_system_config_file(self, config, config_file=None): """ Writes modules configuration into a dracut configuration file. :param dict config: a dictionary containing the modules to add and omit :param string conf_file: configuration file to write """ dracut_config = [] if not config_file: config_file = os.path.normpath( self.boot_root_directory + Defaults.get_dracut_conf_name() ) if config.get('modules'): modules = [ module for module in config['modules'] if self._module_available(module) ] dracut_config.append( 'add_dracutmodules+=" {0} "\n'.format(' '.join(modules)) ) if config.get('omit_modules'): dracut_config.append( 'omit_dracutmodules+=" {0} "\n'.format( ' '.join(config['omit_modules']) ) ) if config.get('install_items'): dracut_config.append( 'install_items+=" {0} "\n'.format( ' '.join(config['install_items']) ) ) if dracut_config: with open(config_file, 'w') as config: config.writelines(dracut_config)
[docs] def prepare(self): """ Prepare dracut caller environment * Setup machine_id(s) to be generic and rebuild by dracut on boot """ setup = SystemSetup( self.xml_state, self.boot_root_directory ) setup.setup_machine_id() self.dracut_options.append('--install') self.dracut_options.append('/.profile')
[docs] def create_initrd(self, mbrid=None, basename=None, install_initrd=False): """ Create kiwi .profile environment to be included in dracut initrd. Call dracut as chroot operation to create the initrd and move the result into the image build target directory :param object mbrid: unused :param string basename: base initrd file name :param bool install_initrd: installation media initrd """ if self.is_prepared(): log.info('Creating generic dracut initrd archive') self._create_profile_environment() kernel_info = Kernel(self.boot_root_directory) kernel_details = kernel_info.get_kernel(raise_on_not_found=True) if basename: dracut_initrd_basename = basename else: dracut_initrd_basename = self.initrd_base_name if install_initrd: included_files = self.included_files_install modules_args = [ '--add', ' {0} '.format(' '.join(self.install_modules)) ] if self.install_modules else [] omit_modules_args = [ '--omit', ' {0} '.format( ' '.join(self.omit_install_modules) ) ] if self.omit_install_modules else [] else: included_files = self.included_files modules_args = [ '--add', ' {0} '.format(' '.join(self.modules)) ] if self.modules else [] omit_modules_args = [ '--omit', ' {0} '.format(' '.join(self.omit_modules)) ] if self.omit_modules else [] dracut_initrd_basename += '.xz' options = self.dracut_options + modules_args +\ omit_modules_args + included_files dracut_call = Command.run( [ 'chroot', self.boot_root_directory, 'dracut', '--verbose', '--no-hostonly', '--no-hostonly-cmdline', '--xz' ] + options + [ dracut_initrd_basename, kernel_details.version ], stderr_to_stdout=True ) log.debug(dracut_call.output) Command.run( [ 'mv', os.sep.join( [self.boot_root_directory, dracut_initrd_basename] ), self.target_dir ] ) self.initrd_filename = os.sep.join( [self.target_dir, dracut_initrd_basename] )
def _get_modules(self): cmd = Command.run( [ 'chroot', self.boot_root_directory, 'dracut', '--list-modules', '--no-kernel' ] ) return cmd.output.splitlines() def _module_available(self, module): warn_msg = 'dracut module "{0}" not found in the root tree' if module in self.available_modules: return True log.warning(warn_msg.format(module)) return False def _create_profile_environment(self): profile = Profile(self.xml_state) defaults = Defaults() defaults.to_profile(profile) profile.create( Defaults.get_profile_file(self.boot_root_directory) )