def __import_system_description_elements(self): self.xml_state.copy_displayname(self.boot_xml_state) self.xml_state.copy_name(self.boot_xml_state) self.xml_state.copy_repository_sections( target_state=self.boot_xml_state, wipe=True) self.xml_state.copy_drivers_sections(self.boot_xml_state) strip_description = XMLDescription( Defaults.get_boot_image_strip_file()) strip_xml_state = XMLState(strip_description.load()) strip_xml_state.copy_strip_sections(self.boot_xml_state) preferences_subsection_names = [ 'bootloader_theme', 'bootsplash_theme', 'locale', 'packagemanager', 'rpm_check_signatures', 'showlicense' ] self.xml_state.copy_preferences_subsections( preferences_subsection_names, self.boot_xml_state) self.xml_state.copy_bootincluded_packages(self.boot_xml_state) self.xml_state.copy_bootincluded_archives(self.boot_xml_state) self.xml_state.copy_bootdelete_packages(self.boot_xml_state) type_attributes = [ 'bootkernel', 'bootloader', 'bootprofile', 'boottimeout', 'btrfs_root_is_snapshot', 'devicepersistency', 'filesystem', 'firmware', 'fsmountoptions', 'hybrid', 'hybridpersistent', 'hybridpersistent_filesystem', 'installboot', 'installprovidefailsafe', 'kernelcmdline', 'ramonly', 'vga', 'wwid_wait_timeout' ] self.xml_state.copy_build_type_attributes(type_attributes, self.boot_xml_state) self.xml_state.copy_systemdisk_section(self.boot_xml_state) self.xml_state.copy_machine_section(self.boot_xml_state) self.xml_state.copy_oemconfig_section(self.boot_xml_state)
def __load_boot_xml_description(self): log.info('Loading Boot XML description') boot_description_directory = self.__boot_description_directory() boot_config_file = boot_description_directory + '/config.xml' if not os.path.exists(boot_config_file): raise KiwiConfigFileNotFound( 'no Boot XML description found in %s' % boot_description_directory) boot_description = XMLDescription(boot_config_file) self.boot_xml_data = boot_description.load() self.boot_config_file = boot_config_file boot_image_profile = self.xml_state.build_type.get_bootprofile() if not boot_image_profile: boot_image_profile = 'default' boot_kernel_profile = self.xml_state.build_type.get_bootkernel() if not boot_kernel_profile: boot_kernel_profile = 'std' self.boot_xml_state = XMLState( self.boot_xml_data, [boot_image_profile, boot_kernel_profile]) log.info('--> loaded %s', self.boot_config_file) if self.boot_xml_state.build_type: log.info('--> Selected build type: %s', self.boot_xml_state.get_build_type_name()) if self.boot_xml_state.profiles: log.info('--> Selected boot profiles: image: %s, kernel: %s', boot_image_profile, boot_kernel_profile)
def load_xml_description(self, description_directory): from logger import log log.info('Loading XML description') config_file = description_directory + '/config.xml' if not os.path.exists(config_file): # alternative config file lookup location config_file = description_directory + '/image/config.xml' if not os.path.exists(config_file): # glob config file search, first match wins glob_match = description_directory + '/*.kiwi' for kiwi_file in glob.iglob(glob_match): config_file = kiwi_file break if not os.path.exists(config_file): raise KiwiConfigFileNotFound( 'no XML description found in %s' % description_directory ) description = XMLDescription( config_file ) self.xml_data = description.load() self.config_file = config_file.replace('//', '/') self.xml_state = XMLState( self.xml_data, self.global_args['--profile'], self.global_args['--type'] ) log.info('--> loaded %s', self.config_file) if self.xml_state.build_type: log.info( '--> Selected build type: %s', self.xml_state.get_build_type_name() ) if self.xml_state.profiles: log.info( '--> Selected profiles: %s', ','.join(self.xml_state.profiles) )
def __load_boot_xml_description(self): log.info('Loading Boot XML description') boot_description_directory = self.__boot_description_directory() boot_config_file = boot_description_directory + '/config.xml' if not os.path.exists(boot_config_file): raise KiwiConfigFileNotFound( 'no Boot XML description found in %s' % boot_description_directory ) boot_description = XMLDescription( boot_config_file ) self.boot_xml_data = boot_description.load() self.boot_config_file = boot_config_file boot_image_profile = self.xml_state.build_type.get_bootprofile() if not boot_image_profile: boot_image_profile = 'default' boot_kernel_profile = self.xml_state.build_type.get_bootkernel() if not boot_kernel_profile: boot_kernel_profile = 'std' self.boot_xml_state = XMLState( self.boot_xml_data, [boot_image_profile, boot_kernel_profile] ) log.info('--> loaded %s', self.boot_config_file) if self.boot_xml_state.build_type: log.info( '--> Selected build type: %s', self.boot_xml_state.get_build_type_name() ) if self.boot_xml_state.profiles: log.info( '--> Selected boot profiles: image: %s, kernel: %s', boot_image_profile, boot_kernel_profile )
class BootImageKiwi(BootImageBase): """ Implements preparation and creation of kiwi boot(initrd) images The kiwi initrd is a customized first boot initrd which allows to control the first boot an appliance. The kiwi initrd replaces itself after first boot by the result of dracut. """ def prepare(self): """ prepare new root system suitable to create an initrd from it """ self.__load_boot_xml_description() boot_image_name = self.boot_xml_state.xml_data.get_name() self.__import_system_description_elements() log.info('Preparing boot image') system = System(xml_state=self.boot_xml_state, root_dir=self.boot_root_directory, allow_existing=True) manager = system.setup_repositories() system.install_bootstrap(manager) system.install_system(manager) profile = Profile(self.boot_xml_state) profile.add('kiwi_initrdname', boot_image_name) defaults = Defaults() defaults.to_profile(profile) setup = SystemSetup(self.boot_xml_state, self.__boot_description_directory(), self.boot_root_directory) setup.import_shell_environment(profile) setup.import_description() setup.import_overlay_files(follow_links=True) setup.call_config_script() system.pinch_system(manager=manager, force=True) setup.call_image_script() setup.create_init_link_from_linuxrc() def create_initrd(self, mbrid=None): if self.is_prepared(): log.info('Creating initrd cpio archive') initrd_file_name = ''.join([ self.target_dir, '/', self.xml_state.xml_data.get_name(), '.initrd' ]) # we can't simply exclude boot when building the archive # because the file boot/mbrid must be preserved. Because of # that we create a copy of the boot directory and remove # everything in boot/ except for boot/mbrid. The original # boot directory should not be changed because we rely # on other data in boot/ e.g the kernel to be available # for the entire image building process self.temp_boot_root_directory = mkdtemp() Command.run([ 'rsync', '-zav', self.boot_root_directory + '/', self.temp_boot_root_directory ]) boot_directory = self.temp_boot_root_directory + '/boot' Path.wipe(boot_directory) if mbrid: log.info('--> Importing mbrid: %s', mbrid.get_id()) Path.create(boot_directory) image_identifier = boot_directory + '/mbrid' mbrid.write(image_identifier) cpio = ArchiveCpio(initrd_file_name) # the following is a list of directories which were needed # during the process of creating an image but not when the # image is actually booting with this initrd exclude_from_archive = ['/var/cache', '/image', '/usr/lib/grub2'] cpio.create(source_dir=self.temp_boot_root_directory, exclude=exclude_from_archive) log.info('--> xz compressing archive') compress = Compress(initrd_file_name) compress.xz() self.initrd_filename = compress.compressed_filename def __import_system_description_elements(self): self.xml_state.copy_displayname(self.boot_xml_state) self.xml_state.copy_name(self.boot_xml_state) self.xml_state.copy_repository_sections( target_state=self.boot_xml_state, wipe=True) self.xml_state.copy_drivers_sections(self.boot_xml_state) strip_description = XMLDescription( Defaults.get_boot_image_strip_file()) strip_xml_state = XMLState(strip_description.load()) strip_xml_state.copy_strip_sections(self.boot_xml_state) preferences_subsection_names = [ 'bootloader_theme', 'bootsplash_theme', 'locale', 'packagemanager', 'rpm_check_signatures', 'showlicense' ] self.xml_state.copy_preferences_subsections( preferences_subsection_names, self.boot_xml_state) self.xml_state.copy_bootincluded_packages(self.boot_xml_state) self.xml_state.copy_bootincluded_archives(self.boot_xml_state) self.xml_state.copy_bootdelete_packages(self.boot_xml_state) type_attributes = [ 'bootkernel', 'bootloader', 'bootprofile', 'boottimeout', 'btrfs_root_is_snapshot', 'devicepersistency', 'filesystem', 'firmware', 'fsmountoptions', 'hybrid', 'hybridpersistent', 'hybridpersistent_filesystem', 'installboot', 'installprovidefailsafe', 'kernelcmdline', 'ramonly', 'vga', 'wwid_wait_timeout' ] self.xml_state.copy_build_type_attributes(type_attributes, self.boot_xml_state) self.xml_state.copy_systemdisk_section(self.boot_xml_state) self.xml_state.copy_machine_section(self.boot_xml_state) self.xml_state.copy_oemconfig_section(self.boot_xml_state) def __load_boot_xml_description(self): log.info('Loading Boot XML description') boot_description_directory = self.__boot_description_directory() boot_config_file = boot_description_directory + '/config.xml' if not os.path.exists(boot_config_file): raise KiwiConfigFileNotFound( 'no Boot XML description found in %s' % boot_description_directory) boot_description = XMLDescription(boot_config_file) self.boot_xml_data = boot_description.load() self.boot_config_file = boot_config_file boot_image_profile = self.xml_state.build_type.get_bootprofile() if not boot_image_profile: boot_image_profile = 'default' boot_kernel_profile = self.xml_state.build_type.get_bootkernel() if not boot_kernel_profile: boot_kernel_profile = 'std' self.boot_xml_state = XMLState( self.boot_xml_data, [boot_image_profile, boot_kernel_profile]) log.info('--> loaded %s', self.boot_config_file) if self.boot_xml_state.build_type: log.info('--> Selected build type: %s', self.boot_xml_state.get_build_type_name()) if self.boot_xml_state.profiles: log.info('--> Selected boot profiles: image: %s, kernel: %s', boot_image_profile, boot_kernel_profile) def __boot_description_directory(self): boot_description = self.xml_state.build_type.get_boot() if boot_description: if not boot_description[0] == '/': boot_description = \ Defaults.get_boot_image_description_path() + '/' + \ boot_description return boot_description
class CliTask(object): """ Base class for all task classes, loads the task and provides the interface to the command options and the XML description """ def __init__(self, should_perform_task_setup=True): from logger import log self.cli = Cli() # want some help self.cli.show_and_exit_on_help_request() # load/import task module self.task = self.cli.load_command() # get command specific args self.command_args = self.cli.get_command_args() # get global args self.global_args = self.cli.get_global_args() if should_perform_task_setup: # set log level if self.global_args['--debug']: log.setLogLevel(logging.DEBUG) else: log.setLogLevel(logging.INFO) # set log file if self.global_args['--logfile']: log.set_logfile( self.global_args['--logfile'] ) def load_xml_description(self, description_directory): from logger import log log.info('Loading XML description') config_file = description_directory + '/config.xml' if not os.path.exists(config_file): # alternative config file lookup location config_file = description_directory + '/image/config.xml' if not os.path.exists(config_file): # glob config file search, first match wins glob_match = description_directory + '/*.kiwi' for kiwi_file in glob.iglob(glob_match): config_file = kiwi_file break if not os.path.exists(config_file): raise KiwiConfigFileNotFound( 'no XML description found in %s' % description_directory ) description = XMLDescription( config_file ) self.xml_data = description.load() self.config_file = config_file.replace('//', '/') self.xml_state = XMLState( self.xml_data, self.global_args['--profile'], self.global_args['--type'] ) log.info('--> loaded %s', self.config_file) if self.xml_state.build_type: log.info( '--> Selected build type: %s', self.xml_state.get_build_type_name() ) if self.xml_state.profiles: log.info( '--> Selected profiles: %s', ','.join(self.xml_state.profiles) ) def quadruple_token(self, option): tokens = option.split(',', 3) return [tokens.pop(0) if len(tokens) else None for _ in range(0, 4)]
class BootImageKiwi(BootImageBase): """ Implements preparation and creation of kiwi boot(initrd) images The kiwi initrd is a customized first boot initrd which allows to control the first boot an appliance. The kiwi initrd replaces itself after first boot by the result of dracut. """ def prepare(self): """ prepare new root system suitable to create an initrd from it """ self.__load_boot_xml_description() boot_image_name = self.boot_xml_state.xml_data.get_name() self.__import_system_description_elements() log.info('Preparing boot image') system = System( xml_state=self.boot_xml_state, root_dir=self.boot_root_directory, allow_existing=True ) manager = system.setup_repositories() system.install_bootstrap( manager ) system.install_system( manager ) profile = Profile(self.boot_xml_state) profile.add('kiwi_initrdname', boot_image_name) defaults = Defaults() defaults.to_profile(profile) setup = SystemSetup( self.boot_xml_state, self.__boot_description_directory(), self.boot_root_directory ) setup.import_shell_environment(profile) setup.import_description() setup.import_overlay_files( follow_links=True ) setup.call_config_script() system.pinch_system( manager=manager, force=True ) setup.call_image_script() setup.create_init_link_from_linuxrc() def create_initrd(self, mbrid=None): if self.is_prepared(): log.info('Creating initrd cpio archive') initrd_file_name = ''.join( [ self.target_dir, '/', self.xml_state.xml_data.get_name(), '.initrd' ] ) # we can't simply exclude boot when building the archive # because the file boot/mbrid must be preserved. Because of # that we create a copy of the boot directory and remove # everything in boot/ except for boot/mbrid. The original # boot directory should not be changed because we rely # on other data in boot/ e.g the kernel to be available # for the entire image building process self.temp_boot_root_directory = mkdtemp() Command.run( [ 'rsync', '-zav', self.boot_root_directory + '/', self.temp_boot_root_directory ] ) boot_directory = self.temp_boot_root_directory + '/boot' Path.wipe(boot_directory) if mbrid: log.info( '--> Importing mbrid: %s', mbrid.get_id() ) Path.create(boot_directory) image_identifier = boot_directory + '/mbrid' mbrid.write(image_identifier) cpio = ArchiveCpio(initrd_file_name) # the following is a list of directories which were needed # during the process of creating an image but not when the # image is actually booting with this initrd exclude_from_archive = [ '/var/cache', '/image', '/usr/lib/grub2' ] cpio.create( source_dir=self.temp_boot_root_directory, exclude=exclude_from_archive ) log.info( '--> xz compressing archive' ) compress = Compress(initrd_file_name) compress.xz() self.initrd_filename = compress.compressed_filename def __import_system_description_elements(self): self.xml_state.copy_displayname( self.boot_xml_state ) self.xml_state.copy_name( self.boot_xml_state ) self.xml_state.copy_repository_sections( target_state=self.boot_xml_state, wipe=True ) self.xml_state.copy_drivers_sections( self.boot_xml_state ) strip_description = XMLDescription( Defaults.get_boot_image_strip_file() ) strip_xml_state = XMLState(strip_description.load()) strip_xml_state.copy_strip_sections( self.boot_xml_state ) preferences_subsection_names = [ 'bootloader_theme', 'bootsplash_theme', 'locale', 'packagemanager', 'rpm_check_signatures', 'showlicense' ] self.xml_state.copy_preferences_subsections( preferences_subsection_names, self.boot_xml_state ) self.xml_state.copy_bootincluded_packages( self.boot_xml_state ) self.xml_state.copy_bootincluded_archives( self.boot_xml_state ) self.xml_state.copy_bootdelete_packages( self.boot_xml_state ) type_attributes = [ 'bootkernel', 'bootloader', 'bootprofile', 'boottimeout', 'btrfs_root_is_snapshot', 'devicepersistency', 'filesystem', 'firmware', 'fsmountoptions', 'hybrid', 'hybridpersistent', 'hybridpersistent_filesystem', 'installboot', 'installprovidefailsafe', 'kernelcmdline', 'ramonly', 'vga', 'wwid_wait_timeout' ] self.xml_state.copy_build_type_attributes( type_attributes, self.boot_xml_state ) self.xml_state.copy_systemdisk_section( self.boot_xml_state ) self.xml_state.copy_machine_section( self.boot_xml_state ) self.xml_state.copy_oemconfig_section( self.boot_xml_state ) def __load_boot_xml_description(self): log.info('Loading Boot XML description') boot_description_directory = self.__boot_description_directory() boot_config_file = boot_description_directory + '/config.xml' if not os.path.exists(boot_config_file): raise KiwiConfigFileNotFound( 'no Boot XML description found in %s' % boot_description_directory ) boot_description = XMLDescription( boot_config_file ) self.boot_xml_data = boot_description.load() self.boot_config_file = boot_config_file boot_image_profile = self.xml_state.build_type.get_bootprofile() if not boot_image_profile: boot_image_profile = 'default' boot_kernel_profile = self.xml_state.build_type.get_bootkernel() if not boot_kernel_profile: boot_kernel_profile = 'std' self.boot_xml_state = XMLState( self.boot_xml_data, [boot_image_profile, boot_kernel_profile] ) log.info('--> loaded %s', self.boot_config_file) if self.boot_xml_state.build_type: log.info( '--> Selected build type: %s', self.boot_xml_state.get_build_type_name() ) if self.boot_xml_state.profiles: log.info( '--> Selected boot profiles: image: %s, kernel: %s', boot_image_profile, boot_kernel_profile ) def __boot_description_directory(self): boot_description = self.xml_state.build_type.get_boot() if boot_description: if not boot_description[0] == '/': boot_description = \ Defaults.get_boot_image_description_path() + '/' + \ boot_description return boot_description
def __import_system_description_elements(self): self.xml_state.copy_displayname( self.boot_xml_state ) self.xml_state.copy_name( self.boot_xml_state ) self.xml_state.copy_repository_sections( target_state=self.boot_xml_state, wipe=True ) self.xml_state.copy_drivers_sections( self.boot_xml_state ) strip_description = XMLDescription( Defaults.get_boot_image_strip_file() ) strip_xml_state = XMLState(strip_description.load()) strip_xml_state.copy_strip_sections( self.boot_xml_state ) preferences_subsection_names = [ 'bootloader_theme', 'bootsplash_theme', 'locale', 'packagemanager', 'rpm_check_signatures', 'showlicense' ] self.xml_state.copy_preferences_subsections( preferences_subsection_names, self.boot_xml_state ) self.xml_state.copy_bootincluded_packages( self.boot_xml_state ) self.xml_state.copy_bootincluded_archives( self.boot_xml_state ) self.xml_state.copy_bootdelete_packages( self.boot_xml_state ) type_attributes = [ 'bootkernel', 'bootloader', 'bootprofile', 'boottimeout', 'btrfs_root_is_snapshot', 'devicepersistency', 'filesystem', 'firmware', 'fsmountoptions', 'hybrid', 'hybridpersistent', 'hybridpersistent_filesystem', 'installboot', 'installprovidefailsafe', 'kernelcmdline', 'ramonly', 'vga', 'wwid_wait_timeout' ] self.xml_state.copy_build_type_attributes( type_attributes, self.boot_xml_state ) self.xml_state.copy_systemdisk_section( self.boot_xml_state ) self.xml_state.copy_machine_section( self.boot_xml_state ) self.xml_state.copy_oemconfig_section( self.boot_xml_state )