def setup(self): self.rpm_host = Rpm() self.rpm_image = Rpm('root_dir') self.macro_file = os.sep.join([ Defaults.get_custom_rpm_macros_path(), Defaults.get_custom_rpm_bootstrap_macro_name() ])
def clean_leftovers(self) -> None: """ Cleans package manager related data not needed in the resulting image such as custom macros """ Rpm(self.root_dir, Defaults.get_custom_rpm_image_macro_name()).wipe_config()
def clean_leftovers(self) -> None: """ Cleans package manager related data not needed in the resulting image such as custom macros """ Rpm(self.root_dir, Defaults.get_custom_rpm_image_macro_name()).wipe_config() id_file = os.path.normpath( os.sep.join([self.root_dir, self.anonymousId_file])) if os.path.exists(id_file): os.unlink(id_file)
def process(self): # noqa: C901 """ Prepare and install a new system for chroot access """ self.manual = Help() if self._help(): return Privileges.check_for_root_permissions() self.load_xml_description(self.command_args['--description']) abs_root_path = os.path.abspath(self.command_args['--root']) prepare_checks = self.checks_before_command_args prepare_checks.update( {'check_target_directory_not_in_shared_cache': [abs_root_path]}) self.run_checks(prepare_checks) if self.command_args['--ignore-repos']: self.xml_state.delete_repository_sections() elif self.command_args['--ignore-repos-used-for-build']: self.xml_state.delete_repository_sections_used_for_build() if self.command_args['--set-repo']: self.xml_state.set_repository( *self.sextuple_token(self.command_args['--set-repo'])) if self.command_args['--add-repo']: for add_repo in self.command_args['--add-repo']: self.xml_state.add_repository(*self.sextuple_token(add_repo)) if self.command_args['--set-container-tag']: self.xml_state.set_container_config_tag( self.command_args['--set-container-tag']) if self.command_args['--add-container-label']: for add_label in self.command_args['--add-container-label']: try: (name, value) = add_label.split('=', 1) self.xml_state.add_container_config_label(name, value) except Exception: log.warning('Container label {0} ignored. Invalid format: ' 'expected labelname=value'.format(add_label)) if self.command_args['--set-container-derived-from']: self.xml_state.set_derived_from_image_uri( self.command_args['--set-container-derived-from']) self.run_checks(self.checks_after_command_args) log.info('Preparing system') system = SystemPrepare(self.xml_state, abs_root_path, self.command_args['--allow-existing-root']) manager = system.setup_repositories(self.command_args['--clear-cache'], self.command_args['--signing-key']) system.install_bootstrap(manager, self.command_args['--add-bootstrap-package']) system.install_system(manager) if self.command_args['--add-package']: system.install_packages(manager, self.command_args['--add-package']) if self.command_args['--delete-package']: system.delete_packages(manager, self.command_args['--delete-package']) profile = Profile(self.xml_state) defaults = Defaults() defaults.to_profile(profile) setup = SystemSetup(self.xml_state, abs_root_path) setup.import_shell_environment(profile) setup.import_description() setup.import_overlay_files() setup.import_image_identifier() setup.setup_groups() setup.setup_users() setup.setup_keyboard_map() setup.setup_locale() setup.setup_plymouth_splash() setup.setup_timezone() setup.setup_permissions() # make sure manager instance is cleaned up now del manager # setup permanent image repositories after cleanup setup.import_repositories_marked_as_imageinclude() setup.call_config_script() # handle uninstall package requests, gracefully uninstall # with dependency cleanup system.pinch_system(force=False) # handle delete package requests, forced uninstall without # any dependency resolution system.pinch_system(force=True) # delete any custom rpm macros created Rpm(abs_root_path, Defaults.get_custom_rpm_image_macro_name()).wipe_config() # make sure system instance is cleaned up now del system
def __init__(self, root_dir, macro_file=None): self.rpmdb_host = Rpm() self.rpmdb_image = Rpm(root_dir, macro_file) self.root_dir = root_dir
class RpmDataBase: """ **Setup RPM database configuration** """ def __init__(self, root_dir, macro_file=None): self.rpmdb_host = Rpm() self.rpmdb_image = Rpm(root_dir, macro_file) self.root_dir = root_dir def has_rpm(self): """ Check if rpmdb binary was found in root_dir to indicate that the rpm system is present. """ rpm_search_env = { 'PATH': os.sep.join([self.root_dir, 'usr', 'bin']) } rpm_bin = Path.which( 'rpmdb', custom_env=rpm_search_env, access_mode=os.X_OK ) if not rpm_bin: return False return True def rebuild_database(self): """ Rebuild image rpm database taking current macro setup into account """ Command.run( ['chroot', self.root_dir, 'rpmdb', '--rebuilddb'] ) def init_database(self): Command.run( ['rpm', '--root', self.root_dir, '--initdb'] ) def set_macro_from_string(self, setting): """ Setup given macro setting in image rpm configuration. The following format for the setting is expected: macro_base_key_name%macro_value. If this expression is not matched the macro setup will be skipped. Please note the macro_base_key_name includes the name of the macro as rpm expects it exlcuding the leading '%' character. Also note macro defintions must happen before calling set_database_* methods in order to become effective :param string setting: macro key and value as one string """ match = re.match('(.*)%(.*)', setting) if match: self.rpmdb_image.set_config_value( match.group(1), match.group(2) ) def write_config(self): self.rpmdb_image.write_config() def import_signing_key_to_image(self, key): """ Import the given signing key to the image rpm database """ Command.run( [ 'rpm', '--root', self.root_dir, '--import', key, '--dbpath', self.rpmdb_host.expand_query('%_dbpath') ] ) def set_database_to_host_path(self): """ Setup dbpath to point to the host rpm dbpath configuration and write the configuration file """ self.rpmdb_image.set_config_value( '_dbpath', self.rpmdb_host.get_query('_dbpath') ) self.rpmdb_image.write_config() def link_database_to_host_path(self): """ Create a link from host database location to image database location. The link is only created if both locations differ and if the host database location does not exist. """ rpm_host_dbpath = self.rpmdb_host.expand_query('%_dbpath') rpm_image_dbpath = self.rpmdb_image.expand_query('%_dbpath') if rpm_host_dbpath != rpm_image_dbpath: root_rpm_host_dbpath = os.path.normpath( os.sep.join([self.root_dir, rpm_host_dbpath]) ) if not os.path.exists(root_rpm_host_dbpath): Path.create(os.path.dirname(root_rpm_host_dbpath)) host_to_root = ''.join( '../' for i in os.path.dirname( rpm_host_dbpath ).lstrip(os.sep).split(os.sep) ) Command.run( [ 'ln', '-s', os.path.normpath( os.sep.join([host_to_root, rpm_image_dbpath]) ), root_rpm_host_dbpath ] ) def set_database_to_image_path(self): """ Setup dbpath to point to the image rpm dbpath configuration Rebuild the database such that it gets moved to the standard path and delete KIWI's custom macro setup """ self.rpmdb_image.wipe_config() rpm_image_dbpath = self.rpmdb_image.expand_query('%_dbpath') rpm_host_dbpath = self.rpmdb_host.expand_query('%_dbpath') if rpm_image_dbpath != rpm_host_dbpath: root_rpm_image_dbpath = os.path.normpath( os.sep.join([self.root_dir, rpm_image_dbpath]) ) root_rpm_host_dbpath = os.path.normpath( os.sep.join([self.root_dir, rpm_host_dbpath]) ) if os.path.islink(root_rpm_host_dbpath): self.rebuild_database() return if os.path.islink(root_rpm_image_dbpath): os.unlink(root_rpm_image_dbpath) else: Path.wipe(root_rpm_image_dbpath) self.rpmdb_image.set_config_value( '_dbpath', rpm_host_dbpath ) self.rpmdb_image.set_config_value( '_dbpath_rebuild', self.rpmdb_image.get_query('_dbpath') ) self.rpmdb_image.write_config() self.rebuild_database() self.rpmdb_image.wipe_config() root_rpm_alternatives = os.sep.join( [root_rpm_host_dbpath, 'alternatives'] ) if os.path.exists(root_rpm_alternatives): Command.run( ['mv', root_rpm_alternatives, root_rpm_image_dbpath] ) Path.wipe(root_rpm_host_dbpath)
class TestRpm: def setup(self): self.rpm_host = Rpm() self.rpm_image = Rpm('root_dir') self.macro_file = os.sep.join([ Defaults.get_custom_rpm_macros_path(), Defaults.get_custom_rpm_bootstrap_macro_name() ]) def setup_method(self, cls): self.setup() @patch('kiwi.utils.rpm.Command.run') def test_expand_query(self, mock_Command_run): self.rpm_host.expand_query('foo') mock_Command_run.assert_called_once_with(['rpm', '-E', 'foo']) mock_Command_run.reset_mock() self.rpm_image.expand_query('foo') mock_Command_run.assert_called_once_with( ['chroot', 'root_dir', 'rpm', '-E', 'foo']) @patch('kiwi.utils.rpm.Command.run') def test_get_query(self, mock_Command_run): rpmdb_call = Mock() rpmdb_call.output = '%_dbpath %{_usr}/lib/sysimage/rpm' mock_Command_run.return_value = rpmdb_call assert self.rpm_host.get_query('_dbpath') == \ '%{_usr}/lib/sysimage/rpm' mock_Command_run.assert_called_once_with(['rpmdb', '--showrc']) mock_Command_run.reset_mock() assert self.rpm_image.get_query('_dbpath') == \ '%{_usr}/lib/sysimage/rpm' mock_Command_run.assert_called_once_with( ['chroot', 'root_dir', 'rpmdb', '--showrc']) def test_set_config_value(self): self.rpm_host.set_config_value('key', 'value') assert self.rpm_host.custom_config[0] == '%key\tvalue' @patch('kiwi.utils.rpm.Path.wipe') def test_wipe_config(self, mock_Path_wipe): self.rpm_host.wipe_config() mock_Path_wipe.assert_called_once_with(os.sep + self.macro_file) mock_Path_wipe.reset_mock() self.rpm_image.wipe_config() mock_Path_wipe.assert_called_once_with( os.sep.join(['root_dir', self.macro_file])) @patch('kiwi.utils.rpm.Path.create') def test_write_config(self, mock_Path_create): self.rpm_host.set_config_value('key', 'value') m_open = mock_open() with patch('builtins.open', m_open, create=True): self.rpm_host.write_config() m_open.assert_called_once_with(os.sep + self.macro_file, 'w') assert m_open.return_value.write.call_args_list == [ call('%key\tvalue\n') ] self.rpm_image.set_config_value('foo', 'bar') m_open.reset_mock() with patch('builtins.open', m_open, create=True): self.rpm_image.write_config() m_open.assert_called_once_with( os.sep.join(['root_dir', self.macro_file]), 'w') assert m_open.return_value.write.call_args_list == [ call('%foo\tbar\n') ]
def process(self): # noqa: C901 """ Build a system image from the specified description. The build command combines the prepare and create commands """ self.manual = Help() if self._help(): return Privileges.check_for_root_permissions() abs_target_dir_path = os.path.abspath( self.command_args['--target-dir'] ) build_dir = os.sep.join([abs_target_dir_path, 'build']) image_root = os.sep.join([build_dir, 'image-root']) Path.create(build_dir) if not self.global_args['--logfile']: log.set_logfile( os.sep.join([abs_target_dir_path, 'build', 'image-root.log']) ) self.load_xml_description( self.command_args['--description'] ) self.runtime_checker.check_minimal_required_preferences() self.runtime_checker.check_efi_mode_for_disk_overlay_correctly_setup() self.runtime_checker.check_boot_description_exists() self.runtime_checker.check_consistent_kernel_in_boot_and_system_image() self.runtime_checker.check_docker_tool_chain_installed() self.runtime_checker.check_volume_setup_defines_multiple_fullsize_volumes() self.runtime_checker.check_volume_setup_has_no_root_definition() self.runtime_checker.check_volume_label_used_with_lvm() self.runtime_checker.check_xen_uniquely_setup_as_server_or_guest() self.runtime_checker.check_target_directory_not_in_shared_cache( abs_target_dir_path ) self.runtime_checker.check_mediacheck_only_for_x86_arch() self.runtime_checker.check_dracut_module_for_live_iso_in_package_list() self.runtime_checker.check_dracut_module_for_disk_overlay_in_package_list() self.runtime_checker.check_dracut_module_for_disk_oem_in_package_list() self.runtime_checker.check_dracut_module_for_oem_install_in_package_list() if self.command_args['--ignore-repos']: self.xml_state.delete_repository_sections() elif self.command_args['--ignore-repos-used-for-build']: self.xml_state.delete_repository_sections_used_for_build() if self.command_args['--set-repo']: self.xml_state.set_repository( *self.sextuple_token(self.command_args['--set-repo']) ) if self.command_args['--add-repo']: for add_repo in self.command_args['--add-repo']: self.xml_state.add_repository( *self.sextuple_token(add_repo) ) if self.command_args['--set-container-tag']: self.xml_state.set_container_config_tag( self.command_args['--set-container-tag'] ) if self.command_args['--add-container-label']: for add_label in self.command_args['--add-container-label']: try: (name, value) = add_label.split('=', 1) self.xml_state.add_container_config_label(name, value) except Exception: log.warning( 'Container label {0} ignored. Invalid format: ' 'expected labelname=value'.format(add_label) ) if self.command_args['--set-container-derived-from']: self.xml_state.set_derived_from_image_uri( self.command_args['--set-container-derived-from'] ) self.runtime_checker.check_repositories_configured() self.runtime_checker.check_image_include_repos_publicly_resolvable() log.info('Preparing new root system') system = SystemPrepare( self.xml_state, image_root, self.command_args['--allow-existing-root'] ) manager = system.setup_repositories( self.command_args['--clear-cache'], self.command_args['--signing-key'] ) system.install_bootstrap(manager) system.install_system( manager ) if self.command_args['--add-package']: system.install_packages( manager, self.command_args['--add-package'] ) if self.command_args['--delete-package']: system.delete_packages( manager, self.command_args['--delete-package'] ) profile = Profile(self.xml_state) defaults = Defaults() defaults.to_profile(profile) setup = SystemSetup( self.xml_state, image_root ) setup.import_shell_environment(profile) setup.import_description() setup.import_overlay_files() setup.import_image_identifier() setup.setup_groups() setup.setup_users() setup.setup_keyboard_map() setup.setup_locale() setup.setup_plymouth_splash() setup.setup_timezone() setup.setup_permissions() # make sure manager instance is cleaned up now del manager # setup permanent image repositories after cleanup setup.import_repositories_marked_as_imageinclude() setup.call_config_script() # handle uninstall package requests, gracefully uninstall # with dependency cleanup system.pinch_system(force=False) # handle delete package requests, forced uninstall without # any dependency resolution system.pinch_system(force=True) # delete any custom rpm macros created Rpm( image_root, Defaults.get_custom_rpm_image_macro_name() ).wipe_config() # make sure system instance is cleaned up now del system setup.call_image_script() # make sure setup instance is cleaned up now del setup log.info('Creating system image') image_builder = ImageBuilder( self.xml_state, abs_target_dir_path, image_root, custom_args={ 'signing_keys': self.command_args['--signing-key'], 'xz_options': self.runtime_config.get_xz_options() } ) result = image_builder.create() result.print_results() result.dump( os.sep.join([abs_target_dir_path, 'kiwi.result']) )
class RpmDataBase(object): """ **Setup RPM database configuration** """ def __init__(self, root_dir, macro_file=None): self.rpmdb_host = Rpm() self.rpmdb_image = Rpm(root_dir, macro_file) self.root_dir = root_dir def has_rpm(self): """ Check if rpm binary was found in root_dir """ rpm_search_env = {'PATH': os.sep.join([self.root_dir, 'usr', 'bin'])} rpm_bin = Path.which('rpm', custom_env=rpm_search_env, access_mode=os.X_OK) if not rpm_bin: return False return True def rebuild_database(self): """ Rebuild image rpm database taking current macro setup into account """ Command.run(['chroot', self.root_dir, 'rpmdb', '--rebuilddb']) def set_macro_from_string(self, setting): """ Setup given macro setting in image rpm configuration. The following format for the setting is expected: macro_base_key_name%macro_value. If this expression is not matched the macro setup will be skipped. Please note the macro_base_key_name includes the name of the macro as rpm expects it exlcuding the leading '%' character. Also note macro defintions must happen before calling set_database_* methods in order to become effective :param string setting: macro key and value as one string """ match = re.match('(.*)%(.*)', setting) if match: self.rpmdb_image.set_config_value(match.group(1), match.group(2)) def write_config(self): self.rpmdb_image.write_config() def set_database_to_host_path(self): """ Setup dbpath to point to the host rpm dbpath configuration and write the configuration file """ self.rpmdb_image.set_config_value('_dbpath', self.rpmdb_host.get_query('_dbpath')) self.rpmdb_image.write_config() def set_database_to_image_path(self): """ Setup dbpath to point to the image rpm dbpath configuration Rebuild the database such that it gets moved to the standard path and delete KIWI's custom macro setup """ self.rpmdb_image.wipe_config() rpm_image_dbpath = self.rpmdb_image.expand_query('%_dbpath') if rpm_image_dbpath != self.rpmdb_host.expand_query('%_dbpath'): self.rpmdb_image.set_config_value( '_dbpath_rebuild', self.rpmdb_image.get_query('_dbpath')) Path.wipe(os.sep.join([self.root_dir, rpm_image_dbpath])) self.rpmdb_image.write_config() self.rebuild_database() self.rpmdb_image.wipe_config()