def setup(self, mock_get_logfile, mock_root_bind, mock_root_init): Defaults.set_platform_name('x86_64') mock_get_logfile.return_value = None description = XMLDescription(description='../data/example_config.xml', derived_from='derived/description') self.description_dir = os.path.dirname(description.description_origin) self.xml = description.load() self.manager = MagicMock(return_value=MagicMock()) self.manager.package_requests = ['foo'] self.manager.collection_requests = ['foo'] self.manager.product_requests = ['foo'] root_init = MagicMock() mock_root_init.return_value = root_init root_bind = MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind self.state = XMLState(self.xml) self.system = SystemPrepare(xml_state=self.state, root_dir='root_dir', allow_existing=True) mock_root_init.assert_called_once_with('root_dir', True) root_init.create.assert_called_once_with() mock_root_bind.assert_called_once_with(root_init) root_bind.setup_intermediate_config.assert_called_once_with() root_bind.mount_kernel_file_systems.assert_called_once_with()
def setup(self, mock_root_bind, mock_root_init): description = XMLDescription( description='../data/example_config.xml', derived_from='derived/description' ) self.xml = description.load() self.manager = mock.MagicMock( return_value=mock.MagicMock() ) self.manager.package_requests = ['foo'] self.manager.collection_requests = ['foo'] self.manager.product_requests = ['foo'] root_init = mock.MagicMock() mock_root_init.return_value = root_init root_bind = mock.MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind self.state = XMLState( self.xml ) self.system = SystemPrepare( xml_state=self.state, root_dir='root_dir', allow_existing=True ) mock_root_init.assert_called_once_with( 'root_dir', True ) root_init.create.assert_called_once_with() mock_root_bind.assert_called_once_with( root_init ) root_bind.setup_intermediate_config.assert_called_once_with() root_bind.mount_kernel_file_systems.assert_called_once_with()
def prepare(self): """ Prepare new root system suitable to create a kiwi 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 = SystemPrepare(xml_state=self.boot_xml_state, root_dir=self.boot_root_directory, allow_existing=True) manager = system.setup_repositories(signing_keys=self.signing_keys) 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) self.setup = SystemSetup(self.boot_xml_state, self.boot_root_directory) profile.create(Defaults.get_profile_file(self.boot_root_directory)) self.setup.import_description() self.setup.import_overlay_files(follow_links=True) self.setup.call_config_script() system.pinch_system(manager=manager, force=True) # make sure system instance is cleaned up before setting up del system self.setup.call_image_script() self.setup.create_init_link_from_linuxrc()
def test_init_with_derived_from_image(self, mock_get_logfile, mock_root_bind, mock_root_init, mock_root_import): mock_get_logfile.return_value = 'logfile' description = XMLDescription(description='../data/example_config.xml', derived_from='derived/description') xml = description.load() root_init = mock.MagicMock() mock_root_init.return_value = root_init root_import = mock.Mock() root_import.sync_data = mock.Mock() mock_root_import.return_value = root_import root_bind = mock.MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind state = XMLState(xml, profiles=['vmxFlavour'], build_type='docker') uri = mock.Mock() get_derived_from_image_uri = mock.Mock(return_value=uri) state.get_derived_from_image_uri = get_derived_from_image_uri system = SystemPrepare( xml_state=state, root_dir='root_dir', ) mock_root_init.assert_called_once_with('root_dir', False) root_init.create.assert_called_once_with() mock_root_import.assert_called_once_with('root_dir', uri, state.build_type.get_image()) root_import.sync_data.assert_called_once_with() mock_root_bind.assert_called_once_with(root_init) root_bind.setup_intermediate_config.assert_called_once_with() root_bind.mount_kernel_file_systems.assert_called_once_with() assert system.issue_message == '{headline}: {reason}'
def PrepareKiwiRootfsSection(descdir, destdir, offset=None): # initialize state state = XMLState(XMLDescription(descdir + '/config.xml').load()) # collct signing keys repokeys = glob(descdir + '/*.key') # install chroot system = SystemPrepare(xml_state=state, root_dir=destdir, allow_existing=True) pkgmanager = system.setup_repositories(clear_cache=False, signing_keys=repokeys) system.install_bootstrap(manager=pkgmanager, plus_packages=None) pkgmanager.root_dir = destdir system.install_system(manager=pkgmanager) # configure chroot setup = SystemSetup(xml_state=state, root_dir=destdir) setup.import_description() setup.setup_groups() setup.setup_users() setup.call_config_script() # clean del pkgmanager del setup del system return KiwiRootfsSection(path=destdir, state=state, offset=offset)
class SystemUpdateTask(CliTask): """ Implements update and maintenance of root systems Attributes * :attr:`manual` Instance of Help """ def process(self): """ Update root system with latest repository updates and optionally allow to add or delete packages. the options to add or delete packages can be used multiple times """ self.manual = Help() if self._help(): return Privileges.check_for_root_permissions() abs_root_path = os.path.abspath(self.command_args['--root']) self.load_xml_description( abs_root_path ) package_requests = False if self.command_args['--add-package']: package_requests = True if self.command_args['--delete-package']: package_requests = True log.info('Updating system') self.system = SystemPrepare( self.xml_state, abs_root_path, allow_existing=True ) manager = self.system.setup_repositories() if not package_requests: self.system.update_system(manager) else: if self.command_args['--add-package']: self.system.install_packages( manager, self.command_args['--add-package'] ) if self.command_args['--delete-package']: self.system.delete_packages( manager, self.command_args['--delete-package'] ) def _help(self): if self.command_args['help']: self.manual.show('kiwi::system::update') else: return False return self.manual
def process(self): """ Update root system with latest repository updates and optionally allow to add or delete packages. the options to add or delete packages can be used multiple times """ self.manual = Help() if self._help(): return Privileges.check_for_root_permissions() abs_root_path = os.path.abspath(self.command_args['--root']) self.load_xml_description( abs_root_path ) package_requests = False if self.command_args['--add-package']: package_requests = True if self.command_args['--delete-package']: package_requests = True log.info('Updating system') self.system = SystemPrepare( self.xml_state, abs_root_path, allow_existing=True ) manager = self.system.setup_repositories() if not package_requests: self.system.update_system(manager) else: if self.command_args['--add-package']: self.system.install_packages( manager, self.command_args['--add-package'] ) if self.command_args['--delete-package']: self.system.delete_packages( manager, self.command_args['--delete-package'] )
def test_install_bootstrap_archive_target_dir( self, mock_tar, mock_poll, mock_root_bind, mock_root_init ): Defaults.set_platform_name('x86_64') description = XMLDescription( description='../data/example_config_target_dir.xml' ) self.xml = description.load() root_bind = MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind self.state = XMLState( self.xml ) self.system = SystemPrepare( xml_state=self.state, root_dir='root_dir', allow_existing=True ) tar = Mock() mock_tar.return_value = tar self.system.install_bootstrap(self.manager) tar.extract.assert_called_once_with('root_dir/foo')
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
class TestSystemPrepare(object): @patch('kiwi.system.prepare.RootInit') @patch('kiwi.system.prepare.RootBind') def setup(self, mock_root_bind, mock_root_init): description = XMLDescription(description='../data/example_config.xml', derived_from='derived/description') self.xml = description.load() self.manager = mock.MagicMock(return_value=mock.MagicMock()) self.manager.package_requests = ['foo'] self.manager.collection_requests = ['foo'] self.manager.product_requests = ['foo'] root_init = mock.MagicMock() mock_root_init.return_value = root_init root_bind = mock.MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind self.state = XMLState(self.xml) self.system = SystemPrepare(xml_state=self.state, root_dir='root_dir', allow_existing=True) mock_root_init.assert_called_once_with('root_dir', True) root_init.create.assert_called_once_with() mock_root_bind.assert_called_once_with(root_init) root_bind.setup_intermediate_config.assert_called_once_with() root_bind.mount_kernel_file_systems.assert_called_once_with() @raises(KiwiBootStrapPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_bootstrap_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.install_bootstrap(self.manager) @raises(KiwiBootStrapPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') def test_install_bootstrap_archives_raises(self, mock_tar, mock_poll): mock_tar.side_effect = Exception self.system.install_bootstrap(self.manager) @raises(KiwiSystemUpdateFailed) @patch('kiwi.system.prepare.CommandProcess.poll') def test_update_system_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.update_system(self.manager) @raises(KiwiSystemInstallPackagesFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.install_packages(self.manager, ['package']) @raises(KiwiInstallPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_system_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.install_system(self.manager) @raises(KiwiInstallPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') def test_install_system_archives_raises(self, mock_tar, mock_poll): mock_tar.side_effect = KiwiInstallPhaseFailed self.system.install_system(self.manager) @raises(KiwiInstallPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_pinch_system_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.pinch_system(self.manager) @raises(KiwiSystemDeletePackagesFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_delete_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.delete_packages(self.manager, ['package']) @patch('kiwi.system.prepare.Repository') @patch('kiwi.system.prepare.Uri') @patch('kiwi.system.prepare.PackageManager') @patch('kiwi.xml_state.XMLState.get_package_manager') @patch('os.path.exists') def test_setup_repositories(self, mock_exists, mock_package_manager, mock_manager, mock_uri, mock_repo): mock_exists.return_value = True mock_package_manager.return_value = 'package-manager-name' uri = mock.Mock() mock_uri.return_value = uri self.system.root_bind = mock.Mock() uri.is_remote = mock.Mock(return_value=False) uri.translate = mock.Mock(return_value='uri') uri.alias = mock.Mock(return_value='uri-alias') repo = mock.Mock() mock_repo.return_value = repo self.system.setup_repositories() mock_repo.assert_called_once_with(self.system.root_bind, 'package-manager-name') # mock local repos will be translated and bind mounted assert uri.translate.call_args_list == [call(), call()] assert self.system.root_bind.mount_shared_directory.call_args_list == [ call('uri'), call('uri') ] assert uri.alias.call_args_list == [call(), call()] assert repo.add_repo.call_args_list == [ call('uri-alias', 'uri', 'yast2', 42, None, None), call('uri-alias', 'uri', 'rpm-md', None, None, None) ] @patch('kiwi.system.prepare.Repository') @patch('kiwi.system.prepare.Uri') @patch('kiwi.system.prepare.PackageManager') @patch('kiwi.xml_state.XMLState.get_package_manager') @patch('os.path.exists') @patch('kiwi.logger.log.warning') def test_setup_repositories_local_not_existing(self, mock_log_warn, mock_exists, mock_package_manager, mock_manager, mock_uri, mock_repo): mock_exists.return_value = False mock_package_manager.return_value = 'package-manager-name' uri = mock.Mock() mock_uri.return_value = uri self.system.root_bind = mock.Mock() uri.is_remote = mock.Mock(return_value=False) uri.translate = mock.Mock(return_value='uri') uri.alias = mock.Mock(return_value='uri-alias') repo = mock.Mock() mock_repo.return_value = repo self.system.setup_repositories() assert mock_log_warn.called @patch('kiwi.xml_state.XMLState.get_bootstrap_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_bootstrap(self, mock_exists, mock_tar, mock_poll, mock_collection_type): mock_exists.return_value = True tar = mock.Mock() tar.extract = mock.Mock() mock_tar.return_value = tar mock_collection_type.return_value = 'onlyRequired' self.system.install_bootstrap(self.manager) self.manager.process_only_required.assert_called_once_with() self.manager.request_package.assert_any_call('filesystem') self.manager.request_package.assert_any_call('zypper') self.manager.request_collection.assert_called_once_with( 'bootstrap-collection') self.manager.request_product.assert_called_once_with('kiwi') self.manager.process_install_requests_bootstrap.assert_called_once_with( ) mock_tar.assert_called_once_with('../data/bootstrap.tgz') tar.extract.assert_called_once_with('root_dir') @patch('kiwi.xml_state.XMLState.get_bootstrap_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_bootstrap_archive_from_derived_description( self, mock_exists, mock_tar, mock_poll, mock_collection_type): mock_exists.return_value = False self.system.install_bootstrap(self.manager) mock_tar.assert_called_once_with('derived/description/bootstrap.tgz') @patch('kiwi.xml_state.XMLState.get_system_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_system(self, mock_exists, mock_tar, mock_poll, mock_collection_type): mock_exists.return_value = True tar = mock.Mock() tar.extract = mock.Mock() mock_tar.return_value = tar mock_collection_type.return_value = 'onlyRequired' self.system.install_system(self.manager) self.manager.process_only_required.assert_called_once_with() self.manager.request_package.assert_any_call( 'plymouth-branding-openSUSE') self.manager.request_collection.assert_any_call('base') self.manager.request_product.assert_any_call('openSUSE') self.manager.process_install_requests.assert_called_once_with() mock_tar.assert_called_once_with('/absolute/path/to/image.tgz') tar.extract.assert_called_once_with('root_dir') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_pinch_system(self, mock_poll): self.system.pinch_system(self.manager) self.manager.request_package.assert_any_call('kernel-debug') self.manager.process_delete_requests.assert_called_once_with(False) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_packages(self, mock_poll): self.system.install_packages(self.manager, ['foo']) self.manager.request_package.assert_called_once_with('foo') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_delete_packages(self, mock_poll): self.system.delete_packages(self.manager, ['foo']) self.manager.request_package.assert_called_once_with('foo') @patch('kiwi.system.prepare.CommandProcess.poll') def test_update_system(self, mock_poll): self.system.update_system(self.manager) self.manager.update.assert_called_once_with() def test_destructor(self): self.system.__del__() self.system.root_bind.cleanup.assert_called_once_with() def test_destructor_raising(self): self.system.root_bind = mock.Mock() self.system.root_bind.cleanup.side_effect = Exception del self.system
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'] ) build_checks = self.checks_before_command_args build_checks.update( { 'check_target_directory_not_in_shared_cache': [abs_target_dir_path] } ) self.run_checks(build_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 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, 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) profile.create( Defaults.get_profile_file(image_root) ) setup = SystemSetup( self.xml_state, image_root ) 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 system.clean_package_manager_leftovers() # 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.new( 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']) )
def process(self): """ 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_efi_mode_for_disk_overlay_correctly_setup() 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_has_no_root_definition() 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() 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.quintuple_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.quintuple_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['--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() package_requests = False if self.command_args['--add-package']: package_requests = True if self.command_args['--delete-package']: package_requests = True 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 package_requests: 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() system.pinch_system( manager=manager, force=True ) # 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() # 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 TestSystemPrepare(object): @patch('kiwi.system.prepare.RootInit') @patch('kiwi.system.prepare.RootBind') def setup(self, mock_root_bind, mock_root_init): description = XMLDescription( description='../data/example_config.xml', derived_from='derived/description' ) self.xml = description.load() self.manager = mock.MagicMock( return_value=mock.MagicMock() ) self.manager.package_requests = ['foo'] self.manager.collection_requests = ['foo'] self.manager.product_requests = ['foo'] root_init = mock.MagicMock() mock_root_init.return_value = root_init root_bind = mock.MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind self.state = XMLState( self.xml ) self.system = SystemPrepare( xml_state=self.state, root_dir='root_dir', allow_existing=True ) mock_root_init.assert_called_once_with( 'root_dir', True ) root_init.create.assert_called_once_with() mock_root_bind.assert_called_once_with( root_init ) root_bind.setup_intermediate_config.assert_called_once_with() root_bind.mount_kernel_file_systems.assert_called_once_with() @raises(KiwiBootStrapPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_bootstrap_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.install_bootstrap(self.manager) @raises(KiwiBootStrapPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') def test_install_bootstrap_archives_raises(self, mock_tar, mock_poll): mock_tar.side_effect = Exception self.system.install_bootstrap(self.manager) @raises(KiwiSystemUpdateFailed) @patch('kiwi.system.prepare.CommandProcess.poll') def test_update_system_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.update_system(self.manager) @raises(KiwiSystemInstallPackagesFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.install_packages(self.manager, ['package']) @raises(KiwiInstallPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_system_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.install_system(self.manager) @raises(KiwiInstallPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') def test_install_system_archives_raises(self, mock_tar, mock_poll): mock_tar.side_effect = KiwiInstallPhaseFailed self.system.install_system(self.manager) @raises(KiwiInstallPhaseFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_pinch_system_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.pinch_system(self.manager) @raises(KiwiSystemDeletePackagesFailed) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_delete_packages_raises(self, mock_poll): mock_poll.side_effect = Exception self.system.delete_packages(self.manager, ['package']) @patch('kiwi.system.prepare.Repository') @patch('kiwi.system.prepare.Uri') @patch('kiwi.system.prepare.PackageManager') @patch('kiwi.xml_state.XMLState.get_package_manager') @patch('os.path.exists') def test_setup_repositories( self, mock_exists, mock_package_manager, mock_manager, mock_uri, mock_repo ): mock_exists.return_value = True mock_package_manager.return_value = 'package-manager-name' uri = mock.Mock() mock_uri.return_value = uri self.system.root_bind = mock.Mock() uri.is_remote = mock.Mock( return_value=False ) uri.translate = mock.Mock( return_value='uri' ) uri.alias = mock.Mock( return_value='uri-alias' ) repo = mock.Mock() mock_repo.return_value = repo self.system.setup_repositories() mock_repo.assert_called_once_with( self.system.root_bind, 'package-manager-name', ['exclude_docs'] ) # mock local repos will be translated and bind mounted assert uri.translate.call_args_list == [ call(), call() ] assert self.system.root_bind.mount_shared_directory.call_args_list == [ call('uri'), call('uri') ] assert uri.alias.call_args_list == [ call(), call() ] assert repo.add_repo.call_args_list == [ call('uri-alias', 'uri', 'yast2', 42, None, None), call('uri-alias', 'uri', 'rpm-md', None, None, None) ] @patch('kiwi.system.prepare.Repository') @patch('kiwi.system.prepare.Uri') @patch('kiwi.system.prepare.PackageManager') @patch('kiwi.xml_state.XMLState.get_package_manager') @patch('os.path.exists') @patch('kiwi.logger.log.warning') def test_setup_repositories_local_not_existing( self, mock_log_warn, mock_exists, mock_package_manager, mock_manager, mock_uri, mock_repo ): mock_exists.return_value = False mock_package_manager.return_value = 'package-manager-name' uri = mock.Mock() mock_uri.return_value = uri self.system.root_bind = mock.Mock() uri.is_remote = mock.Mock( return_value=False ) uri.translate = mock.Mock( return_value='uri' ) uri.alias = mock.Mock( return_value='uri-alias' ) repo = mock.Mock() mock_repo.return_value = repo self.system.setup_repositories() assert mock_log_warn.called @patch('kiwi.xml_state.XMLState.get_bootstrap_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_bootstrap( self, mock_exists, mock_tar, mock_poll, mock_collection_type ): mock_exists.return_value = True tar = mock.Mock() tar.extract = mock.Mock() mock_tar.return_value = tar mock_collection_type.return_value = 'onlyRequired' self.system.install_bootstrap(self.manager) self.manager.process_only_required.assert_called_once_with() self.manager.request_package.assert_any_call( 'filesystem' ) self.manager.request_package.assert_any_call( 'zypper' ) self.manager.request_collection.assert_called_once_with( 'bootstrap-collection' ) self.manager.request_product.assert_called_once_with( 'kiwi' ) self.manager.process_install_requests_bootstrap.assert_called_once_with( ) mock_tar.assert_called_once_with('../data/bootstrap.tgz') tar.extract.assert_called_once_with('root_dir') @patch('kiwi.xml_state.XMLState.get_bootstrap_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_bootstrap_archive_from_derived_description( self, mock_exists, mock_tar, mock_poll, mock_collection_type ): mock_exists.return_value = False self.system.install_bootstrap(self.manager) mock_tar.assert_called_once_with( 'derived/description/bootstrap.tgz' ) @patch('kiwi.xml_state.XMLState.get_system_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_system( self, mock_exists, mock_tar, mock_poll, mock_collection_type ): mock_exists.return_value = True tar = mock.Mock() tar.extract = mock.Mock() mock_tar.return_value = tar mock_collection_type.return_value = 'onlyRequired' self.system.install_system(self.manager) self.manager.process_only_required.assert_called_once_with() self.manager.request_package.assert_any_call( 'plymouth-branding-openSUSE' ) self.manager.request_collection.assert_any_call( 'base' ) self.manager.request_product.assert_any_call( 'openSUSE' ) self.manager.process_install_requests.assert_called_once_with() mock_tar.assert_called_once_with('/absolute/path/to/image.tgz') tar.extract.assert_called_once_with('root_dir') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_pinch_system(self, mock_poll): self.system.pinch_system(self.manager) self.manager.request_package.assert_any_call( 'kernel-debug' ) self.manager.process_delete_requests.assert_called_once_with(False) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_packages(self, mock_poll): self.system.install_packages(self.manager, ['foo']) self.manager.request_package.assert_called_once_with('foo') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_delete_packages(self, mock_poll): self.system.delete_packages(self.manager, ['foo']) self.manager.request_package.assert_called_once_with('foo') @patch('kiwi.system.prepare.CommandProcess.poll') def test_update_system(self, mock_poll): self.system.update_system(self.manager) self.manager.update.assert_called_once_with() def test_destructor(self): self.system.__del__() self.system.root_bind.cleanup.assert_called_once_with() def test_destructor_raising(self): self.system.root_bind = mock.Mock() self.system.root_bind.cleanup.side_effect = Exception del self.system
def process(self): """ 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'], self.global_args['--kiwi-file']) 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'] + self.xml_state.get_repositories_signing_keys(), self.global_args['--target-arch']) run_bootstrap = True if self.xml_state.get_package_manager() == 'apt' and \ self.command_args['--allow-existing-root']: # try to call apt-get inside of the existing root. # If the call succeeds we skip calling debootstrap again # and assume the root to be ok to proceed with apt-get # if it fails, treat the root as dirty and give the # bootstrap a try try: Command.run(['chroot', abs_root_path, 'apt-get', '--version']) run_bootstrap = False log.warning('debootstrap will only be called once, skipped') except Exception: run_bootstrap = True if run_bootstrap: system.install_bootstrap( manager, self.command_args['--add-bootstrap-package']) setup = SystemSetup(self.xml_state, abs_root_path) setup.import_description() # call post_bootstrap.sh script if present setup.call_post_bootstrap_script() 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) profile.create(Defaults.get_profile_file(abs_root_path)) 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() # call config.sh script if present 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 system.clean_package_manager_leftovers() # make sure system instance is cleaned up now del system
class TestSystemPrepare: @patch('kiwi.system.prepare.RootInit') @patch('kiwi.system.prepare.RootBind') @patch('kiwi.logger.log.get_logfile') def setup(self, mock_get_logfile, mock_root_bind, mock_root_init): mock_get_logfile.return_value = None description = XMLDescription(description='../data/example_config.xml', derived_from='derived/description') self.xml = description.load() self.manager = mock.MagicMock(return_value=mock.MagicMock()) self.manager.package_requests = ['foo'] self.manager.collection_requests = ['foo'] self.manager.product_requests = ['foo'] root_init = mock.MagicMock() mock_root_init.return_value = root_init root_bind = mock.MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind self.state = XMLState(self.xml) self.system = SystemPrepare(xml_state=self.state, root_dir='root_dir', allow_existing=True) mock_root_init.assert_called_once_with('root_dir', True) root_init.create.assert_called_once_with() mock_root_bind.assert_called_once_with(root_init) root_bind.setup_intermediate_config.assert_called_once_with() root_bind.mount_kernel_file_systems.assert_called_once_with() @patch('kiwi.system.prepare.RootImport') @patch('kiwi.system.prepare.RootInit') @patch('kiwi.system.prepare.RootBind') @patch('kiwi.logger.log.get_logfile') def test_init_with_derived_from_image(self, mock_get_logfile, mock_root_bind, mock_root_init, mock_root_import): mock_get_logfile.return_value = 'logfile' description = XMLDescription(description='../data/example_config.xml', derived_from='derived/description') xml = description.load() root_init = mock.MagicMock() mock_root_init.return_value = root_init root_import = mock.Mock() root_import.sync_data = mock.Mock() mock_root_import.return_value = root_import root_bind = mock.MagicMock() root_bind.root_dir = 'root_dir' mock_root_bind.return_value = root_bind state = XMLState(xml, profiles=['vmxFlavour'], build_type='docker') uri = mock.Mock() get_derived_from_image_uri = mock.Mock(return_value=uri) state.get_derived_from_image_uri = get_derived_from_image_uri system = SystemPrepare( xml_state=state, root_dir='root_dir', ) mock_root_init.assert_called_once_with('root_dir', False) root_init.create.assert_called_once_with() mock_root_import.assert_called_once_with('root_dir', uri, state.build_type.get_image()) root_import.sync_data.assert_called_once_with() mock_root_bind.assert_called_once_with(root_init) root_bind.setup_intermediate_config.assert_called_once_with() root_bind.mount_kernel_file_systems.assert_called_once_with() assert system.issue_message == '{headline}: {reason}' @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_bootstrap_packages_raises(self, mock_poll): mock_poll.side_effect = Exception('some_error') with raises(KiwiBootStrapPhaseFailed) as issue: self.system.install_bootstrap(self.manager) assert issue.value.message == self.system.issue_message.format( headline='Bootstrap package installation failed', reason='some_error') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') def test_install_bootstrap_archives_raises(self, mock_tar, mock_poll): mock_tar.side_effect = Exception with raises(KiwiBootStrapPhaseFailed): self.system.install_bootstrap(self.manager) @patch('kiwi.system.prepare.CommandProcess.poll') def test_update_system_raises(self, mock_poll): mock_poll.side_effect = Exception with raises(KiwiSystemUpdateFailed): self.system.update_system(self.manager) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_packages_raises(self, mock_poll): mock_poll.side_effect = Exception with raises(KiwiSystemInstallPackagesFailed): self.system.install_packages(self.manager, ['package']) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_system_packages_raises(self, mock_poll): mock_poll.side_effect = Exception with raises(KiwiInstallPhaseFailed): self.system.install_system(self.manager) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') def test_install_system_archives_raises(self, mock_tar, mock_poll): mock_tar.side_effect = KiwiInstallPhaseFailed with raises(KiwiInstallPhaseFailed): self.system.install_system(self.manager) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_delete_packages_raises(self, mock_poll): mock_poll.side_effect = Exception with raises(KiwiSystemDeletePackagesFailed): self.system.delete_packages(self.manager, ['package']) @patch('kiwi.system.prepare.Repository') @patch('kiwi.system.prepare.Uri') @patch('kiwi.system.prepare.PackageManager') @patch('kiwi.xml_state.XMLState.get_package_manager') @patch('os.path.exists') def test_setup_repositories(self, mock_exists, mock_package_manager, mock_manager, mock_uri, mock_repo): mock_exists.return_value = True mock_package_manager.return_value = 'package-manager-name' uri = mock.Mock() mock_uri.return_value = uri self.system.root_bind = mock.Mock() uri.is_remote = mock.Mock(return_value=False) uri.translate = mock.Mock(return_value='uri') uri.alias = mock.Mock(return_value='uri-alias') uri.credentials_file_name = mock.Mock(return_value='credentials-file') repo = mock.Mock() mock_repo.return_value = repo self.system.setup_repositories( clear_cache=True, signing_keys=['key-file-a.asc', 'key-file-b.asc']) mock_repo.assert_called_once_with( self.system.root_bind, 'package-manager-name', [ 'check_signatures', 'exclude_docs', '_install_langs%POSIX:C:C.UTF-8:en_US:de_DE' ]) # mock local repos will be translated and bind mounted assert uri.translate.call_args_list == [call(), call()] assert self.system.root_bind.mount_shared_directory.call_args_list == [ call('uri'), call('uri') ] assert uri.alias.call_args_list == [call(), call()] assert repo.add_repo.call_args_list == [ call('uri-alias', 'uri', None, 42, None, None, None, None, 'credentials-file', None, None), call('uri-alias', 'uri', 'rpm-md', None, None, None, None, None, 'credentials-file', None, None) ] assert repo.delete_repo_cache.call_args_list == [ call('uri-alias'), call('uri-alias') ] repo.setup_package_database_configuration.assert_called_once_with() repo.import_trusted_keys.assert_called_once_with( ['key-file-a.asc', 'key-file-b.asc']) @patch('kiwi.system.prepare.Repository') @patch('kiwi.system.prepare.Uri') @patch('kiwi.system.prepare.PackageManager') @patch('kiwi.xml_state.XMLState.get_package_manager') @patch('os.path.exists') @patch('kiwi.logger.log.warning') def test_setup_repositories_local_not_existing(self, mock_log_warn, mock_exists, mock_package_manager, mock_manager, mock_uri, mock_repo): mock_exists.return_value = False mock_package_manager.return_value = 'package-manager-name' uri = mock.Mock() mock_uri.return_value = uri self.system.root_bind = mock.Mock() uri.is_remote = mock.Mock(return_value=False) uri.translate = mock.Mock(return_value='uri') uri.alias = mock.Mock(return_value='uri-alias') repo = mock.Mock() mock_repo.return_value = repo self.system.setup_repositories() assert mock_log_warn.called @patch('kiwi.xml_state.XMLState.get_bootstrap_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_bootstrap(self, mock_exists, mock_tar, mock_poll, mock_collection_type): mock_exists.return_value = True tar = mock.Mock() tar.extract = mock.Mock() mock_tar.return_value = tar mock_collection_type.return_value = 'onlyRequired' self.system.install_bootstrap(self.manager) self.manager.process_only_required.assert_called_once_with() self.manager.request_package.assert_any_call('filesystem') self.manager.request_package.assert_any_call('zypper') self.manager.request_collection.assert_called_once_with( 'bootstrap-collection') self.manager.request_product.assert_called_once_with('kiwi') self.manager.process_install_requests_bootstrap.assert_called_once_with( ) mock_tar.assert_called_once_with('../data/bootstrap.tgz') tar.extract.assert_called_once_with('root_dir') self.manager.post_process_install_requests_bootstrap.assert_called_once_with( ) @patch('kiwi.logger.log.warning') @patch('kiwi.xml_state.XMLState.get_bootstrap_packages_sections') def test_install_bootstrap_skipped(self, mock_bootstrap_section, mock_log_warning): mock_bootstrap_section.return_value = [] self.system.install_bootstrap(self.manager) mock_bootstrap_section.assert_called_once_with() assert mock_log_warning.called @patch('kiwi.xml_state.XMLState.get_bootstrap_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_bootstrap_archive_from_derived_description( self, mock_exists, mock_tar, mock_poll, mock_collection_type): mock_exists.return_value = False self.system.install_bootstrap(self.manager) mock_tar.assert_called_once_with('derived/description/bootstrap.tgz') @patch('kiwi.xml_state.XMLState.get_system_collection_type') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') @patch('kiwi.system.prepare.ArchiveTar') @patch('os.path.exists') def test_install_system(self, mock_exists, mock_tar, mock_poll, mock_collection_type): mock_exists.return_value = True tar = mock.Mock() tar.extract = mock.Mock() mock_tar.return_value = tar mock_collection_type.return_value = 'onlyRequired' self.system.install_system(self.manager) self.manager.process_only_required.assert_called_once_with() self.manager.request_package.assert_any_call( 'plymouth-branding-openSUSE') self.manager.request_collection.assert_any_call('base') self.manager.request_product.assert_any_call('openSUSE') self.manager.request_package_exclusion.assert_any_call('foo') self.manager.process_install_requests.assert_called_once_with() mock_tar.assert_called_once_with('/absolute/path/to/image.tgz') tar.extract.assert_called_once_with('root_dir') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_install_packages(self, mock_poll): self.system.install_packages(self.manager, ['foo']) self.manager.request_package.assert_called_once_with('foo') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_delete_packages(self, mock_poll): self.system.delete_packages(self.manager, ['foo']) self.manager.request_package.assert_called_once_with('foo') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_pinch_system(self, mock_poll): self.system.pinch_system(self.manager, force=False) self.system.pinch_system(self.manager, force=True) self.manager.process_delete_requests.assert_has_calls( [call(False), call(True)]) @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_pinch_system_raises(self, mock_poll): mock_poll.side_effect = Exception with raises(KiwiPackagesDeletePhaseFailed): self.system.pinch_system(self.manager) self.manager.process_delete_requests.assert_called_once_with(False) @patch('kiwi.package_manager.PackageManagerZypper.process_delete_requests') @patch('kiwi.system.prepare.Repository') @patch('kiwi.system.prepare.CommandProcess.poll_show_progress') def test_pinch_system_without_manager(self, mock_poll, mock_repo, mock_requests): self.system.pinch_system() mock_repo.assert_called_once_with(mock.ANY, 'zypper') mock_requests.assert_called_once_with(False) @patch('kiwi.system.prepare.CommandProcess.poll') def test_update_system(self, mock_poll): self.system.update_system(self.manager) self.manager.update.assert_called_once_with() def test_destructor(self): self.system.__del__() self.system.root_bind.cleanup.assert_called_once_with() @patch('kiwi.logger.log.info') def test_destructor_raising(self, mock_log): self.system.root_bind = mock.Mock() self.system.root_bind.cleanup.side_effect = ValueError("nothing") del self.system assert mock_log.call_args_list[0] == call( 'Cleaning up SystemPrepare instance') assert mock_log.call_args_list[1] == call( 'Cleaning up SystemPrepare instance failed, got an exception of' ' type ValueError: nothing')
def process(self): """ 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_consistent_kernel_in_boot_and_system_image() self.runtime_checker.check_boot_image_reference_correctly_setup() self.runtime_checker.check_docker_tool_chain_installed() self.runtime_checker.check_volume_setup_has_no_root_definition() self.runtime_checker.check_image_include_repos_http_resolvable() self.runtime_checker.check_target_directory_not_in_shared_cache( abs_target_dir_path ) if self.command_args['--ignore-repos']: self.xml_state.delete_repository_sections() if self.command_args['--set-repo']: (repo_source, repo_type, repo_alias, repo_prio) = \ self.quadruple_token(self.command_args['--set-repo']) self.xml_state.set_repository( repo_source, repo_type, repo_alias, repo_prio ) if self.command_args['--add-repo']: for add_repo in self.command_args['--add-repo']: (repo_source, repo_type, repo_alias, repo_prio) = \ self.quadruple_token(add_repo) self.xml_state.add_repository( repo_source, repo_type, repo_alias, repo_prio ) Path.create(abs_target_dir_path) if self.command_args['--set-container-tag']: self.xml_state.set_container_config_tag( self.command_args['--set-container-tag'] ) 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() if Defaults.is_obs_worker(): # This build runs inside of a buildservice worker. Therefore # the repo defintions is adapted accordingly self.xml_state.translate_obs_to_suse_repositories() elif self.command_args['--obs-repo-internal']: # This build should use the internal SUSE buildservice # Be aware that the buildhost has to provide access self.xml_state.translate_obs_to_ibs_repositories() package_requests = False if self.command_args['--add-package']: package_requests = True if self.command_args['--delete-package']: package_requests = True 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 package_requests: 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_timezone() system.pinch_system( manager=manager, force=True ) # make sure manager instance is cleaned up now del manager # setup permanent image repositories after cleanup if self.xml_state.has_repositories_marked_as_imageinclude(): setup.import_repositories_marked_as_imageinclude() setup.call_config_script() # 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, {'signing_keys': self.command_args['--signing-key']} ) result = image_builder.create() result.print_results() result.dump( os.sep.join([abs_target_dir_path, 'kiwi.result']) )
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']) self.runtime_checker.check_efi_mode_for_disk_overlay_correctly_setup() self.runtime_checker.check_grub_efi_installed_for_efi_firmware() 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_has_no_root_definition() self.runtime_checker.check_xen_uniquely_setup_as_server_or_guest() self.runtime_checker.check_target_directory_not_in_shared_cache( abs_root_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['--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() package_requests = False if self.command_args['--add-package']: package_requests = True if self.command_args['--delete-package']: package_requests = True 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) system.install_system( manager ) if package_requests: 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() system.pinch_system( manager=manager, force=True ) # 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() # make sure system instance is cleaned up now del system
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']) self.runtime_checker.check_efi_mode_for_disk_overlay_correctly_setup() self.runtime_checker.check_grub_efi_installed_for_efi_firmware() 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_has_no_root_definition() self.runtime_checker.check_xen_uniquely_setup_as_server_or_guest() self.runtime_checker.check_target_directory_not_in_shared_cache( abs_root_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['--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 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) 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() # 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) # make sure system instance is cleaned up now del system
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']) )
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_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_has_no_root_definition() 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['--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() # 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) # 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']) )