Пример #1
0
 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()
     ])
Пример #2
0
 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()
Пример #3
0
 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)
Пример #4
0
    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
Пример #5
0
 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
Пример #6
0
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)
Пример #7
0
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')
        ]
Пример #8
0
    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'])
        )
Пример #9
0
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()