Exemplo n.º 1
0
class ResultListTask(CliTask):
    """
    Implements result listing

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        List result information from a previous system command
        """
        self.manual = Help()
        if self._help():
            return

        result_directory = os.path.abspath(
            self.command_args['--target-dir']
        )
        log.info(
            'Listing results from %s', result_directory
        )
        result = Result.load(
            result_directory + '/kiwi.result'
        )
        result.print_results()

    def _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::result::list')
        else:
            return False
        return self.manual
Exemplo n.º 2
0
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
Exemplo n.º 3
0
class TestHelp(object):
    def setup(self):
        self.help = Help()

    @raises(KiwiHelpNoCommandGiven)
    def test_show(self):
        self.help.show(None)

    @patch('subprocess.call')
    def test_show_command(self, mock_process):
        self.help.show('foo')
        mock_process.assert_called_once_with('man 2 foo', shell=True)
Exemplo n.º 4
0
    def process(self):
        """
        Create a system image from the specified root directory
        the root directory is the result of a system prepare
        command
        """
        self.manual = Help()
        if self._help():
            return

        Privileges.check_for_root_permissions()

        abs_target_dir_path = os.path.abspath(
            self.command_args['--target-dir']
        )
        abs_root_path = os.path.abspath(self.command_args['--root'])

        self.load_xml_description(
            abs_root_path
        )
        self.runtime_checker.check_target_directory_not_in_shared_cache(
            abs_target_dir_path
        )

        log.info('Creating system image')
        if not os.path.exists(abs_target_dir_path):
            Path.create(abs_target_dir_path)

        setup = SystemSetup(
            xml_state=self.xml_state,
            root_dir=abs_root_path
        )
        setup.call_image_script()

        image_builder = ImageBuilder(
            self.xml_state,
            abs_target_dir_path,
            abs_root_path,
            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'])
        )
Exemplo n.º 5
0
    def process(self):
        """
        List result information from a previous system command
        """
        self.manual = Help()
        if self._help():
            return

        result_directory = os.path.abspath(
            self.command_args['--target-dir']
        )
        log.info(
            'Listing results from %s', result_directory
        )
        result = Result.load(
            result_directory + '/kiwi.result'
        )
        result.print_results()
Exemplo n.º 6
0
    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']
                )
Exemplo n.º 7
0
class SystemPrepareTask(CliTask):
    """
    Implements preparation and installation of a new root system

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    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']
        )

        abs_root_path = os.path.abspath(self.command_args['--root'])

        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_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()

        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 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 _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::system::prepare')
        else:
            return False
        return self.manual
Exemplo n.º 8
0
    def process(self):
        """
        reformats raw disk image and its format to a new disk
        geometry using the qemu tool chain
        """
        self.manual = Help()
        if self.command_args.get('help') is True:
            return self.manual.show('kiwi::image::resize')

        abs_target_dir_path = os.path.abspath(
            self.command_args['--target-dir']
        )

        if self.command_args['--root']:
            image_root = os.path.abspath(
                os.path.normpath(self.command_args['--root'])
            )
        else:
            image_root = os.sep.join(
                [abs_target_dir_path, 'build', 'image-root']
            )

        self.load_xml_description(
            image_root
        )

        disk_format = self.xml_state.build_type.get_format()

        image_format = DiskFormat(
            disk_format or 'raw', self.xml_state, image_root,
            abs_target_dir_path
        )
        if not image_format.has_raw_disk():
            raise KiwiImageResizeError(
                'no raw disk image {0} found in build results'.format(
                    image_format.diskname
                )
            )

        new_disk_size = StringToSize.to_bytes(self.command_args['--size'])

        # resize raw disk
        log.info(
            'Resizing raw disk to {0} bytes'.format(new_disk_size)
        )
        resize_result = image_format.resize_raw_disk(new_disk_size)

        # resize raw disk partition table
        firmware = FirmWare(self.xml_state)
        loop_provider = LoopDevice(image_format.diskname)
        loop_provider.create(overwrite=False)
        partitioner = Partitioner(
            firmware.get_partition_table_type(), loop_provider
        )
        partitioner.resize_table()
        del loop_provider

        # resize disk format from resized raw disk
        if disk_format and resize_result is True:
            log.info(
                'Creating {0} disk format from resized raw disk'.format(
                    disk_format
                )
            )
            image_format.create_image_format()
        elif resize_result is False:
            log.info(
                'Raw disk is already at {0} bytes'.format(new_disk_size)
            )
Exemplo n.º 9
0
class SystemPrepareTask(CliTask):
    """
    Implements preparation and installation of a new root system

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    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_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_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['--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 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 _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::system::prepare')
        else:
            return False
        return self.manual
Exemplo n.º 10
0
    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
Exemplo n.º 11
0
class ImageResizeTask(CliTask):
    """
    Implements resizing of disk images and their disk format

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        reformats raw disk image and its format to a new disk
        geometry using the qemu tool chain
        """
        self.manual = Help()
        if self.command_args.get('help') is True:
            return self.manual.show('kiwi::image::resize')

        abs_target_dir_path = os.path.abspath(
            self.command_args['--target-dir'])

        if self.command_args['--root']:
            image_root = os.path.abspath(
                os.path.normpath(self.command_args['--root']))
        else:
            image_root = os.sep.join(
                [abs_target_dir_path, 'build', 'image-root'])

        self.load_xml_description(image_root, self.global_args['--kiwi-file'])

        disk_format = self.xml_state.build_type.get_format()

        image_format = DiskFormat.new(disk_format or 'raw', self.xml_state,
                                      image_root, abs_target_dir_path)
        if not image_format.has_raw_disk():
            raise KiwiImageResizeError(
                'no raw disk image {0} found in build results'.format(
                    image_format.diskname))

        new_disk_size = StringToSize.to_bytes(self.command_args['--size'])

        # resize raw disk
        log.info('Resizing raw disk to {0} bytes'.format(new_disk_size))
        resize_result = image_format.resize_raw_disk(new_disk_size)

        # resize raw disk partition table
        firmware = FirmWare(self.xml_state)
        loop_provider = LoopDevice(image_format.diskname)
        loop_provider.create(overwrite=False)
        partitioner = Partitioner.new(firmware.get_partition_table_type(),
                                      loop_provider)
        partitioner.resize_table()
        del loop_provider

        # resize disk format from resized raw disk
        if disk_format and resize_result is True:
            log.info('Creating {0} disk format from resized raw disk'.format(
                disk_format))
            image_format.create_image_format()
        elif resize_result is False:
            log.info('Raw disk is already at {0} bytes'.format(new_disk_size))
Exemplo n.º 12
0
    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_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()

        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_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']))
Exemplo n.º 13
0
class ResultBundleTask(CliTask):
    """
    Implements result bundler

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        Create result bundle from the image build results in the
        specified target directory. Each result image will contain
        the specified bundle identifier as part of its filename.
        Uncompressed image files will also become xz compressed
        and a sha sum will be created from every result image
        """
        self.manual = Help()
        if self._help():
            return

        if self.command_args['--package-as-rpm']:
            Privileges.check_for_root_permissions()

        # load serialized result object from target directory
        result_directory = os.path.abspath(self.command_args['--target-dir'])
        bundle_directory = os.path.abspath(self.command_args['--bundle-dir'])
        if result_directory == bundle_directory:
            raise KiwiBundleError(
                'Bundle directory must be different from target directory')

        log.info('Bundle build results from %s', result_directory)
        result = Result.load(result_directory + '/kiwi.result')
        image_version = result.xml_state.get_image_version()
        image_name = result.xml_state.xml_data.get_name()
        image_description = result.xml_state.get_description_section()
        ordered_results = OrderedDict(sorted(result.get_results().items()))

        # hard link bundle files, compress and build checksum
        if self.command_args['--package-as-rpm']:
            Path.wipe(bundle_directory)
        if not os.path.exists(bundle_directory):
            Path.create(bundle_directory)

        bundle_file_format_name = ''
        if 'bundle_format' in ordered_results:
            bundle_format = ordered_results['bundle_format']
            tags = bundle_format['tags']
            bundle_file_format_name = bundle_format['pattern']
            # Insert image name
            bundle_file_format_name = bundle_file_format_name.replace(
                '%N', tags.N)
            # Insert Concatenated profile name (_)
            bundle_file_format_name = bundle_file_format_name.replace(
                '%P', tags.P)
            # Insert Architecture name
            bundle_file_format_name = bundle_file_format_name.replace(
                '%A', tags.A)
            # Insert Image build type name
            bundle_file_format_name = bundle_file_format_name.replace(
                '%T', tags.T)
            # Insert Image Major version number
            bundle_file_format_name = bundle_file_format_name.replace(
                '%M', format(tags.M))
            # Insert Image Minor version number
            bundle_file_format_name = bundle_file_format_name.replace(
                '%m', format(tags.m))
            # Insert Image Patch version number
            bundle_file_format_name = bundle_file_format_name.replace(
                '%p', format(tags.p))
            # Insert Bundle ID
            bundle_file_format_name = bundle_file_format_name.replace(
                '%I', self.command_args['--id'])
            del (ordered_results['bundle_format'])

        for result_file in list(ordered_results.values()):
            if result_file.use_for_bundle:
                extension = result_file.filename.split('.').pop()
                if bundle_file_format_name:
                    bundle_file_basename = '.'.join(
                        [bundle_file_format_name, extension])
                else:
                    bundle_file_basename = os.path.basename(
                        result_file.filename)
                    # The bundle id is only taken into account for image results
                    # which contains the image version appended in its file name
                    part_name = list(
                        bundle_file_basename.partition(image_name))
                    bundle_file_basename = ''.join([
                        part_name[0], part_name[1], part_name[2].replace(
                            image_version,
                            image_version + '-' + self.command_args['--id'])
                    ])
                log.info('Creating %s', bundle_file_basename)
                bundle_file = ''.join(
                    [bundle_directory, '/', bundle_file_basename])
                Command.run(['cp', result_file.filename, bundle_file])
                if result_file.compress:
                    log.info('--> XZ compressing')
                    compress = Compress(bundle_file)
                    compress.xz(self.runtime_config.get_xz_options())
                    bundle_file = compress.compressed_filename

                if self.command_args['--zsync-source'] and result_file.shasum:
                    # Files with a checksum are considered to be image files
                    # and are therefore eligible to be provided via the
                    # requested Partial/differential file download based on
                    # zsync
                    zsyncmake = Path.which('zsyncmake', access_mode=os.X_OK)
                    if zsyncmake:
                        log.info('--> Creating zsync control file')
                        Command.run([
                            zsyncmake, '-e', '-u',
                            os.sep.join([
                                self.command_args['--zsync-source'],
                                os.path.basename(bundle_file)
                            ]), '-o', bundle_file + '.zsync', bundle_file
                        ])
                    else:
                        log.warning(
                            '--> zsyncmake missing, zsync setup skipped')

                if result_file.shasum:
                    log.info('--> Creating SHA 256 sum')
                    checksum = Checksum(bundle_file)
                    with open(bundle_file + '.sha256', 'w') as shasum:
                        shasum.write('{0}  {1}{2}'.format(
                            checksum.sha256(), os.path.basename(bundle_file),
                            os.linesep))
        if self.command_args['--package-as-rpm']:
            ResultBundleTask._build_rpm_package(
                bundle_directory, bundle_file_format_name or image_name,
                image_version, image_description.specification,
                list(glob.iglob(f'{bundle_directory}/*')))

    @staticmethod
    def _build_rpm_package(bundle_directory: str, image_name: str,
                           image_version: str, description_text,
                           filenames: List[str]) -> None:
        source_links = []
        for source_file in filenames:
            source_links.append(' '.join([
                'ln', '%{_sourcedir}/' + os.path.basename(source_file),
                '%{buildroot}' + f'/var/tmp/{image_name}'
            ]))
        spec_file_name = os.path.join(bundle_directory, f'{image_name}.spec')
        spec_data = dedent('''
            %global _sourcedir %(pwd)
            %global _rpmdir .

            Url:            https://osinside.github.io/kiwi
            Name:           {name}
            Summary:        {name}
            Version:        {version}
            Release:        0
            Group:          %{{sysgroup}}
            License:        GPL-3.0-or-later
            BuildRoot:      %{{_tmppath}}/%{{name}}-%{{version}}-build
            BuildArch:      noarch

            %description
            {description}

            %prep

            %build

            %install
            install -d -m 755 %{{buildroot}}/var/tmp/{name}

            {source_links}

            %clean
            rm -rf %{{buildroot}}

            %files
            %defattr(-, root, root)
            /var/tmp/{name}

            %changelog
        ''').format(name=image_name,
                    version=image_version,
                    description=description_text,
                    source_links=os.linesep.join(source_links))
        with open(spec_file_name, 'w') as spec:
            spec.write(spec_data)
        os.chdir(bundle_directory)
        log.info('Creating rpm package...')
        Command.run([
            'rpmbuild', '--nodeps', '--nocheck', '--rmspec', '-bb',
            spec_file_name
        ])
        for source_file in filenames:
            os.unlink(source_file)
        Command.run(['bash', '-c', 'mv noarch/*.rpm . && rmdir noarch'])

    def _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::result::bundle')
        else:
            return False
        return self.manual
Exemplo n.º 14
0
    def process(self):
        """
        Walks through the given info options and provide the requested data
        """
        self.manual = Help()
        if self.command_args.get('help') is True:
            return self.manual.show('kiwi::image::info')

        self.load_xml_description(self.command_args['--description'],
                                  self.global_args['--kiwi-file'])

        if self.command_args['--ignore-repos']:
            self.xml_state.delete_repository_sections()

        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)

        self.runtime_checker.check_repositories_configured()

        result = {'image': self.xml_state.xml_data.get_name()}

        if self.command_args['--resolve-package-list']:
            solver = self._setup_solver()
            boostrap_package_list = self.xml_state.get_bootstrap_packages()
            package_list = boostrap_package_list + \
                self.xml_state.get_system_packages()
            bootstrap_collection_type = \
                self.xml_state.get_bootstrap_collection_type()
            system_collection_type = \
                self.xml_state.get_system_collection_type()
            bootstrap_packages = solver.solve(
                boostrap_package_list, False,
                True if bootstrap_collection_type == 'onlyRequired' else False)
            solved_packages = solver.solve(
                self.xml_state.get_system_packages(), False,
                True if system_collection_type == 'onlyRequired' else False)
            solved_packages.update(bootstrap_packages)
            package_info = {}
            for package, metadata in sorted(list(solved_packages.items())):
                if package in package_list:
                    status = 'listed_in_kiwi_description'
                else:
                    status = 'added_by_dependency_solver'
                package_info[package] = {
                    'source': metadata.uri,
                    'installsize_bytes': int(metadata.installsize_bytes),
                    'arch': metadata.arch,
                    'version': metadata.version,
                    'status': status
                }
            result['resolved-packages'] = package_info

        if self.global_args['--color-output']:
            DataOutput(result, style='color').display()
        else:
            DataOutput(result).display()

        if self.command_args['--print-xml']:
            DataOutput.display_file(
                self.description.markup.get_xml_description(),
                'Description(XML):')
        elif self.command_args['--print-yaml']:
            DataOutput.display_file(
                self.description.markup.get_yaml_description(),
                'Description(YAML):')
Exemplo n.º 15
0
class ResultBundleTask(CliTask):
    """
    Implements result bundler

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        Create result bundle from the image build results in the
        specified target directory. Each result image will contain
        the specified bundle identifier as part of its filename.
        Uncompressed image files will also become xz compressed
        and a sha sum will be created from every result image
        """
        self.manual = Help()
        if self._help():
            return

        # load serialized result object from target directory
        result_directory = os.path.abspath(self.command_args['--target-dir'])
        bundle_directory = os.path.abspath(self.command_args['--bundle-dir'])
        if result_directory == bundle_directory:
            raise KiwiBundleError(
                'Bundle directory must be different from target directory')

        log.info('Bundle build results from %s', result_directory)
        result = Result.load(result_directory + '/kiwi.result')
        image_version = result.xml_state.get_image_version()
        image_name = result.xml_state.xml_data.get_name()
        ordered_results = OrderedDict(sorted(result.get_results().items()))

        # hard link bundle files, compress and build checksum
        if not os.path.exists(bundle_directory):
            Path.create(bundle_directory)
        for result_file in list(ordered_results.values()):
            if result_file.use_for_bundle:
                bundle_file_basename = os.path.basename(result_file.filename)
                # The bundle id is only taken into account for image results
                # which contains the image version appended in its file name
                part_name = list(bundle_file_basename.partition(image_name))
                bundle_file_basename = ''.join([
                    part_name[0], part_name[1], part_name[2].replace(
                        image_version,
                        image_version + '-' + self.command_args['--id'])
                ])
                log.info('Creating %s', bundle_file_basename)
                bundle_file = ''.join(
                    [bundle_directory, '/', bundle_file_basename])
                Command.run(['cp', result_file.filename, bundle_file])
                if self.runtime_config.is_bundle_compression_requested() and \
                   result_file.compress:
                    log.info('--> XZ compressing')
                    compress = Compress(bundle_file)
                    compress.xz(self.runtime_config.get_xz_options())
                    bundle_file = compress.compressed_filename

                if self.command_args['--zsync-source'] and result_file.shasum:
                    # Files with a checksum are considered to be image files
                    # and are therefore eligible to be provided via the
                    # requested Partial/differential file download based on
                    # zsync
                    zsyncmake = Path.which('zsyncmake', access_mode=os.X_OK)
                    if zsyncmake:
                        log.info('--> Creating zsync control file')
                        Command.run([
                            zsyncmake, '-e', '-u',
                            os.sep.join([
                                self.command_args['--zsync-source'],
                                os.path.basename(bundle_file)
                            ]), '-o', bundle_file + '.zsync', bundle_file
                        ])
                    else:
                        log.warning(
                            '--> zsyncmake missing, zsync setup skipped')

                if result_file.shasum:
                    log.info('--> Creating SHA 256 sum')
                    checksum = Checksum(bundle_file)
                    with open(bundle_file + '.sha256', 'w') as shasum:
                        shasum.write(checksum.sha256())

    def _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::result::bundle')
        else:
            return False
        return self.manual
Exemplo n.º 16
0
class SystemPrepareTask(CliTask):
    """
    Implements preparation and installation of a new root system

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    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)
        system.install_system(
            manager
        )

        if self.command_args['--add-package']:
            system.install_packages(
                manager, self.command_args['--add-package']
            )
        if self.command_args['--delete-package']:
            system.delete_packages(
                manager, self.command_args['--delete-package']
            )

        profile = Profile(self.xml_state)

        defaults = Defaults()
        defaults.to_profile(profile)

        setup = SystemSetup(
            self.xml_state, abs_root_path
        )
        setup.import_shell_environment(profile)

        setup.import_description()
        setup.import_overlay_files()
        setup.import_image_identifier()
        setup.setup_groups()
        setup.setup_users()
        setup.setup_keyboard_map()
        setup.setup_locale()
        setup.setup_plymouth_splash()
        setup.setup_timezone()
        setup.setup_permissions()

        # make sure manager instance is cleaned up now
        del manager

        # setup permanent image repositories after cleanup
        setup.import_repositories_marked_as_imageinclude()
        setup.call_config_script()

        # handle uninstall package requests, gracefully uninstall
        # with dependency cleanup
        system.pinch_system(force=False)

        # handle delete package requests, forced uninstall without
        # any dependency resolution
        system.pinch_system(force=True)

        # delete any custom rpm macros created
        Rpm(
            abs_root_path, Defaults.get_custom_rpm_image_macro_name()
        ).wipe_config()

        # make sure system instance is cleaned up now
        del system

    def _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::system::prepare')
        else:
            return False
        return self.manual
Exemplo n.º 17
0
    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'])

        abs_root_path = os.path.abspath(self.command_args['--root'])

        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_root_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)

        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 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_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
Exemplo n.º 18
0
    def process(self):
        """
        Walks through the given info options and provide the requested data
        """
        self.manual = Help()
        if self.command_args.get('help') is True:
            return self.manual.show('kiwi::image::info')

        self.load_xml_description(
            self.command_args['--description']
        )

        if self.command_args['--ignore-repos']:
            self.xml_state.delete_repository_sections()

        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
                )

        self.runtime_checker.check_repositories_configured()

        result = {
            'image': self.xml_state.xml_data.get_name()
        }

        if self.command_args['--resolve-package-list']:
            solver = self._setup_solver()
            boostrap_package_list = self.xml_state.get_bootstrap_packages()
            package_list = boostrap_package_list + \
                self.xml_state.get_system_packages()
            bootstrap_packages = solver.solve(
                boostrap_package_list, False,
                True if self.xml_state.get_bootstrap_collection_type() is
                'onlyRequired' else False
            )
            solved_packages = solver.solve(
                self.xml_state.get_system_packages(), False,
                True if self.xml_state.get_system_collection_type() is
                'onlyRequired' else False
            )
            solved_packages.update(bootstrap_packages)
            package_info = {}
            for package, metadata in sorted(list(solved_packages.items())):
                if package in package_list:
                    status = 'listed_in_kiwi_description'
                else:
                    status = 'added_by_dependency_solver'
                package_info[package] = {
                    'source': metadata.uri,
                    'installsize_bytes': int(metadata.installsize_bytes),
                    'arch': metadata.arch,
                    'version': metadata.version,
                    'status': status
                }
            result['resolved-packages'] = package_info

        if self.global_args['--color-output']:
            DataOutput(result, style='color').display()
        else:
            DataOutput(result).display()
Exemplo n.º 19
0
class SystemBuildTask(CliTask):
    """
    Implements building of system images

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    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'])
        )

    def _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::system::build')
        else:
            return False
        return self.manual
Exemplo n.º 20
0
 def setup(self):
     self.help = Help()
Exemplo n.º 21
0
    def process(self):
        """
        Create result bundle from the image build results in the
        specified target directory. Each result image will contain
        the specified bundle identifier as part of its filename.
        Uncompressed image files will also become xz compressed
        and a sha sum will be created from every result image
        """
        self.manual = Help()
        if self._help():
            return

        if self.command_args['--package-as-rpm']:
            Privileges.check_for_root_permissions()

        # load serialized result object from target directory
        result_directory = os.path.abspath(self.command_args['--target-dir'])
        bundle_directory = os.path.abspath(self.command_args['--bundle-dir'])
        if result_directory == bundle_directory:
            raise KiwiBundleError(
                'Bundle directory must be different from target directory')

        log.info('Bundle build results from %s', result_directory)
        result = Result.load(result_directory + '/kiwi.result')
        image_version = result.xml_state.get_image_version()
        image_name = result.xml_state.xml_data.get_name()
        image_description = result.xml_state.get_description_section()
        ordered_results = OrderedDict(sorted(result.get_results().items()))

        # hard link bundle files, compress and build checksum
        if self.command_args['--package-as-rpm']:
            Path.wipe(bundle_directory)
        if not os.path.exists(bundle_directory):
            Path.create(bundle_directory)

        bundle_file_format_name = ''
        if 'bundle_format' in ordered_results:
            bundle_format = ordered_results['bundle_format']
            tags = bundle_format['tags']
            bundle_file_format_name = bundle_format['pattern']
            # Insert image name
            bundle_file_format_name = bundle_file_format_name.replace(
                '%N', tags.N)
            # Insert Concatenated profile name (_)
            bundle_file_format_name = bundle_file_format_name.replace(
                '%P', tags.P)
            # Insert Architecture name
            bundle_file_format_name = bundle_file_format_name.replace(
                '%A', tags.A)
            # Insert Image build type name
            bundle_file_format_name = bundle_file_format_name.replace(
                '%T', tags.T)
            # Insert Image Major version number
            bundle_file_format_name = bundle_file_format_name.replace(
                '%M', format(tags.M))
            # Insert Image Minor version number
            bundle_file_format_name = bundle_file_format_name.replace(
                '%m', format(tags.m))
            # Insert Image Patch version number
            bundle_file_format_name = bundle_file_format_name.replace(
                '%p', format(tags.p))
            # Insert Bundle ID
            bundle_file_format_name = bundle_file_format_name.replace(
                '%I', self.command_args['--id'])
            del (ordered_results['bundle_format'])

        for result_file in list(ordered_results.values()):
            if result_file.use_for_bundle:
                extension = result_file.filename.split('.').pop()
                if bundle_file_format_name:
                    bundle_file_basename = '.'.join(
                        [bundle_file_format_name, extension])
                else:
                    bundle_file_basename = os.path.basename(
                        result_file.filename)
                    # The bundle id is only taken into account for image results
                    # which contains the image version appended in its file name
                    part_name = list(
                        bundle_file_basename.partition(image_name))
                    bundle_file_basename = ''.join([
                        part_name[0], part_name[1], part_name[2].replace(
                            image_version,
                            image_version + '-' + self.command_args['--id'])
                    ])
                log.info('Creating %s', bundle_file_basename)
                bundle_file = ''.join(
                    [bundle_directory, '/', bundle_file_basename])
                Command.run(['cp', result_file.filename, bundle_file])
                if result_file.compress:
                    log.info('--> XZ compressing')
                    compress = Compress(bundle_file)
                    compress.xz(self.runtime_config.get_xz_options())
                    bundle_file = compress.compressed_filename

                if self.command_args['--zsync-source'] and result_file.shasum:
                    # Files with a checksum are considered to be image files
                    # and are therefore eligible to be provided via the
                    # requested Partial/differential file download based on
                    # zsync
                    zsyncmake = Path.which('zsyncmake', access_mode=os.X_OK)
                    if zsyncmake:
                        log.info('--> Creating zsync control file')
                        Command.run([
                            zsyncmake, '-e', '-u',
                            os.sep.join([
                                self.command_args['--zsync-source'],
                                os.path.basename(bundle_file)
                            ]), '-o', bundle_file + '.zsync', bundle_file
                        ])
                    else:
                        log.warning(
                            '--> zsyncmake missing, zsync setup skipped')

                if result_file.shasum:
                    log.info('--> Creating SHA 256 sum')
                    checksum = Checksum(bundle_file)
                    with open(bundle_file + '.sha256', 'w') as shasum:
                        shasum.write('{0}  {1}{2}'.format(
                            checksum.sha256(), os.path.basename(bundle_file),
                            os.linesep))
        if self.command_args['--package-as-rpm']:
            ResultBundleTask._build_rpm_package(
                bundle_directory, bundle_file_format_name or image_name,
                image_version, image_description.specification,
                list(glob.iglob(f'{bundle_directory}/*')))
Exemplo n.º 22
0
class ImageInfoTask(CliTask):
    """
    Implements retrieval of in depth information for an image description

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        Walks through the given info options and provide the requested data
        """
        self.manual = Help()
        if self.command_args.get('help') is True:
            return self.manual.show('kiwi::image::info')

        self.load_xml_description(self.command_args['--description'],
                                  self.global_args['--kiwi-file'])

        if self.command_args['--ignore-repos']:
            self.xml_state.delete_repository_sections()

        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)

        self.runtime_checker.check_repositories_configured()

        result = {'image': self.xml_state.xml_data.get_name()}

        if self.command_args['--resolve-package-list']:
            solver = self._setup_solver()
            boostrap_package_list = self.xml_state.get_bootstrap_packages()
            package_list = boostrap_package_list + \
                self.xml_state.get_system_packages()
            bootstrap_collection_type = \
                self.xml_state.get_bootstrap_collection_type()
            system_collection_type = \
                self.xml_state.get_system_collection_type()
            bootstrap_packages = solver.solve(
                boostrap_package_list, False,
                True if bootstrap_collection_type == 'onlyRequired' else False)
            solved_packages = solver.solve(
                self.xml_state.get_system_packages(), False,
                True if system_collection_type == 'onlyRequired' else False)
            solved_packages.update(bootstrap_packages)
            package_info = {}
            for package, metadata in sorted(list(solved_packages.items())):
                if package in package_list:
                    status = 'listed_in_kiwi_description'
                else:
                    status = 'added_by_dependency_solver'
                package_info[package] = {
                    'source': metadata.uri,
                    'installsize_bytes': int(metadata.installsize_bytes),
                    'arch': metadata.arch,
                    'version': metadata.version,
                    'status': status
                }
            result['resolved-packages'] = package_info

        if self.global_args['--color-output']:
            DataOutput(result, style='color').display()
        else:
            DataOutput(result).display()

        if self.command_args['--print-xml']:
            DataOutput.display_file(
                self.description.markup.get_xml_description(),
                'Description(XML):')
        elif self.command_args['--print-yaml']:
            DataOutput.display_file(
                self.description.markup.get_yaml_description(),
                'Description(YAML):')

    def _setup_solver(self):
        solver = Sat()
        for xml_repo in self.xml_state.get_repository_sections_used_for_build(
        ):
            repo_source = xml_repo.get_source().get_path()
            repo_sourcetype = xml_repo.get_sourcetype() or ''
            repo_user = xml_repo.get_username()
            repo_secret = xml_repo.get_password()
            repo_type = xml_repo.get_type()
            repo_dist = xml_repo.get_distribution()
            repo_components = xml_repo.get_components()
            if not repo_type:
                repo_type = SolverRepositoryBase(
                    Uri(uri=repo_source, source_type=repo_sourcetype),
                    repo_user, repo_secret).get_repo_type()
            if repo_type == 'apt-deb':
                # Debian based repos can be setup for a specific
                # distribution including a list of individual components.
                # For each component of the selected distribution extra
                # repository metadata exists. In such a case we iterate
                # over the configured dist components and add them as
                # repository each.
                dist_type = solver.set_dist_type('deb')
                if repo_components and repo_dist:
                    for component in repo_components.split():
                        repo_source_for_component = os.sep.join([
                            repo_source.rstrip(os.sep), 'dists', repo_dist,
                            component, f'binary-{dist_type.get("arch")}'
                        ])
                        solver.add_repository(
                            SolverRepository.new(
                                Uri(repo_source_for_component, repo_type,
                                    repo_sourcetype), repo_user, repo_secret))
                    continue
            solver.add_repository(
                SolverRepository.new(
                    Uri(repo_source, repo_type, repo_sourcetype), repo_user,
                    repo_secret))
        return solver
Exemplo n.º 23
0
class ImageInfoTask(CliTask):
    """
    Implements retrieval of in depth information for an image description

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        Walks through the given info options and provide the requested data
        """
        self.manual = Help()
        if self.command_args.get('help') is True:
            return self.manual.show('kiwi::image::info')

        self.load_xml_description(self.command_args['--description'])

        if self.command_args['--ignore-repos']:
            self.xml_state.delete_repository_sections()

        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)

        self.runtime_checker.check_repositories_configured()

        result = {'image': self.xml_state.xml_data.get_name()}

        if self.command_args['--resolve-package-list']:
            solver = self._setup_solver()
            boostrap_package_list = self.xml_state.get_bootstrap_packages()
            package_list = boostrap_package_list + \
                self.xml_state.get_system_packages()
            bootstrap_packages = solver.solve(
                boostrap_package_list, False,
                True if self.xml_state.get_bootstrap_collection_type() is
                'onlyRequired' else False)
            solved_packages = solver.solve(
                self.xml_state.get_system_packages(), False, True if
                self.xml_state.get_system_collection_type() is 'onlyRequired'
                else False)
            solved_packages.update(bootstrap_packages)
            package_info = {}
            for package, metadata in sorted(list(solved_packages.items())):
                if package in package_list:
                    status = 'listed_in_kiwi_description'
                else:
                    status = 'added_by_dependency_solver'
                package_info[package] = {
                    'source': metadata.uri,
                    'installsize_bytes': int(metadata.installsize_bytes),
                    'arch': metadata.arch,
                    'version': metadata.version,
                    'status': status
                }
            result['resolved-packages'] = package_info

        if self.global_args['--color-output']:
            DataOutput(result, style='color').display()
        else:
            DataOutput(result).display()

    def _setup_solver(self):
        solver = Sat()
        for xml_repo in self.xml_state.get_repository_sections_used_for_build(
        ):
            repo_source = xml_repo.get_source().get_path()
            repo_user = xml_repo.get_username()
            repo_secret = xml_repo.get_password()
            repo_type = xml_repo.get_type()
            solver.add_repository(
                SolverRepository(Uri(repo_source, repo_type), repo_user,
                                 repo_secret))
        return solver
Exemplo n.º 24
0
class SystemPrepareTask(CliTask):
    """
    Implements preparation and installation of a new root system

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    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 _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::system::prepare')
        else:
            return False
        return self.manual
Exemplo n.º 25
0
class ImageResizeTask(CliTask):
    """
    Implements resizing of disk images and their disk format

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        reformats raw disk image and its format to a new disk
        geometry using the qemu tool chain
        """
        self.manual = Help()
        if self.command_args.get('help') is True:
            return self.manual.show('kiwi::image::resize')

        abs_target_dir_path = os.path.abspath(
            self.command_args['--target-dir'])

        if self.command_args['--root']:
            image_root = os.path.abspath(
                os.path.normpath(self.command_args['--root']))
        else:
            image_root = os.sep.join(
                [abs_target_dir_path, 'build', 'image-root'])

        self.load_xml_description(image_root)

        disk_format = self.xml_state.build_type.get_format()

        image_format = DiskFormat(disk_format or 'raw', self.xml_state,
                                  image_root, abs_target_dir_path)
        if not image_format.has_raw_disk():
            raise KiwiImageResizeError(
                'no raw disk image {0} found in build results'.format(
                    image_format.diskname))

        new_disk_size = self._to_bytes(self.command_args['--size'])

        log.info('Resizing raw disk to {0} bytes'.format(new_disk_size))
        resize_result = image_format.resize_raw_disk(new_disk_size)
        if disk_format and resize_result is True:
            log.info('Creating {0} disk format from resized raw disk'.format(
                disk_format))
            image_format.create_image_format()
        elif resize_result is False:
            log.info('Raw disk is already at {0} bytes'.format(new_disk_size))

    def _to_bytes(self, size_value):
        size_format = '^(\d+)([gGmM]{0,1})$'
        size = re.search(size_format, size_value)
        if not size:
            raise KiwiImageResizeError(
                'unsupported size format {0}, must match {1}'.format(
                    size_value, size_format))
        size_base = int(size.group(1))
        size_unit = {'g': 3, 'm': 2}.get(size.group(2).lower())
        return size_unit and size_base * math.pow(0x400,
                                                  size_unit) or size_base
Exemplo n.º 26
0
    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'])

        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'],
                                            self.global_args['--target-arch'])
        system.install_bootstrap(manager,
                                 self.command_args['--add-bootstrap-package'])

        setup = SystemSetup(self.xml_state, image_root)
        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(image_root))

        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

        setup.call_image_script()

        # make sure setup instance is cleaned up now
        del setup

        log.info('Creating system image')
        self.run_checks(
            {'check_dracut_module_versions_compatible_to_kiwi': [image_root]})
        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']))
Exemplo n.º 27
0
class SystemBuildTask(CliTask):
    """
    Implements building of system images

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    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 _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::system::build')
        else:
            return False
        return self.manual
Exemplo n.º 28
0
    def process(self):
        """
        Create result bundle from the image build results in the
        specified target directory. Each result image will contain
        the specified bundle identifier as part of its filename.
        Uncompressed image files will also become xz compressed
        and a sha sum will be created from every result image
        """
        self.manual = Help()
        if self._help():
            return

        # load serialized result object from target directory
        result_directory = os.path.abspath(self.command_args['--target-dir'])
        bundle_directory = os.path.abspath(self.command_args['--bundle-dir'])
        if result_directory == bundle_directory:
            raise KiwiBundleError(
                'Bundle directory must be different from target directory'
            )

        log.info(
            'Bundle build results from %s', result_directory
        )
        result = Result.load(
            result_directory + '/kiwi.result'
        )
        image_version = result.xml_state.get_image_version()
        ordered_results = OrderedDict(sorted(result.get_results().items()))

        # hard link bundle files, compress and build checksum
        if not os.path.exists(bundle_directory):
            Path.create(bundle_directory)
        for result_file in list(ordered_results.values()):
            if result_file.use_for_bundle:
                bundle_file_basename = os.path.basename(result_file.filename)
                # The bundle id is only taken into account for image results
                # which contains the image version in its nane
                bundle_file_basename = bundle_file_basename.replace(
                    image_version,
                    image_version + '-' + self.command_args['--id']
                )
                log.info('Creating %s', bundle_file_basename)
                bundle_file = ''.join(
                    [bundle_directory, '/', bundle_file_basename]
                )
                checksum_file = ''.join(
                    [bundle_directory, '/', bundle_file_basename, '.sha256']
                )
                Command.run(
                    [
                        'cp', result_file.filename, bundle_file
                    ]
                )
                if result_file.compress:
                    log.info('--> XZ compressing')
                    compress = Compress(bundle_file)
                    compress.xz(self.runtime_config.get_xz_options())
                    bundle_file = compress.compressed_filename
                    checksum_file = compress.compressed_filename + '.sha256'
                    if self.command_args['--zsync-source']:
                        zsyncmake = Path.which('zsyncmake', access_mode=os.X_OK)
                        if zsyncmake:
                            log.info('--> Creating zsync control file')
                            Command.run(
                                [
                                    zsyncmake, '-e',
                                    '-u', os.sep.join(
                                        [
                                            self.command_args['--zsync-source'],
                                            os.path.basename(bundle_file)
                                        ]
                                    ),
                                    '-o', bundle_file + '.zsync',
                                    bundle_file
                                ]
                            )
                        else:
                            log.warning(
                                '--> zsyncmake missing, zsync setup skipped'
                            )
                if result_file.shasum:
                    log.info('--> Creating SHA 256 sum')
                    checksum = Checksum(bundle_file)
                    with open(checksum_file, 'w') as shasum:
                        shasum.write(checksum.sha256())
Exemplo n.º 29
0
class SystemCreateTask(CliTask):
    """
    Implements creation of system images

    Attributes

    * :attr:`manual`
        Instance of Help
    """
    def process(self):
        """
        Create a system image from the specified root directory
        the root directory is the result of a system prepare
        command
        """
        self.manual = Help()
        if self._help():
            return

        Privileges.check_for_root_permissions()

        abs_target_dir_path = os.path.abspath(
            self.command_args['--target-dir']
        )
        abs_root_path = os.path.abspath(self.command_args['--root'])

        self.load_xml_description(
            abs_root_path
        )

        self.run_checks(
            {'check_target_directory_not_in_shared_cache': [abs_root_path]}
        )

        log.info('Creating system image')
        if not os.path.exists(abs_target_dir_path):
            Path.create(abs_target_dir_path)

        setup = SystemSetup(
            xml_state=self.xml_state,
            root_dir=abs_root_path
        )
        setup.call_image_script()

        image_builder = ImageBuilder(
            self.xml_state,
            abs_target_dir_path,
            abs_root_path,
            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 _help(self):
        if self.command_args['help']:
            self.manual.show('kiwi::system::create')
        else:
            return False
        return self.manual
Exemplo n.º 30
0
    def process(self):
        """
        Create result bundle from the image build results in the
        specified target directory. Each result image will contain
        the specified bundle identifier as part of its filename.
        Uncompressed image files will also become xz compressed
        and a sha sum will be created from every result image
        """
        self.manual = Help()
        if self._help():
            return

        # load serialized result object from target directory
        result_directory = os.path.abspath(self.command_args['--target-dir'])
        bundle_directory = os.path.abspath(self.command_args['--bundle-dir'])
        if result_directory == bundle_directory:
            raise KiwiBundleError(
                'Bundle directory must be different from target directory')

        log.info('Bundle build results from %s', result_directory)
        result = Result.load(result_directory + '/kiwi.result')
        image_version = result.xml_state.get_image_version()
        ordered_results = OrderedDict(sorted(result.get_results().items()))

        # hard link bundle files, compress and build checksum
        if not os.path.exists(bundle_directory):
            Path.create(bundle_directory)
        for result_file in list(ordered_results.values()):
            if result_file.use_for_bundle:
                bundle_file_basename = os.path.basename(result_file.filename)
                # The bundle id is only taken into account for image results
                # which contains the image version in its nane
                bundle_file_basename = bundle_file_basename.replace(
                    image_version,
                    image_version + '-' + self.command_args['--id'])
                log.info('Creating %s', bundle_file_basename)
                bundle_file = ''.join(
                    [bundle_directory, '/', bundle_file_basename])
                checksum_file = ''.join(
                    [bundle_directory, '/', bundle_file_basename, '.sha256'])
                Command.run(['cp', result_file.filename, bundle_file])
                if result_file.compress:
                    log.info('--> XZ compressing')
                    compress = Compress(bundle_file)
                    compress.xz(self.runtime_config.get_xz_options())
                    bundle_file = compress.compressed_filename
                    checksum_file = compress.compressed_filename + '.sha256'
                    if self.command_args['--zsync-source']:
                        zsyncmake = Path.which('zsyncmake',
                                               access_mode=os.X_OK)
                        if zsyncmake:
                            log.info('--> Creating zsync control file')
                            Command.run([
                                zsyncmake, '-e', '-u',
                                os.sep.join([
                                    self.command_args['--zsync-source'],
                                    os.path.basename(bundle_file)
                                ]), '-o', bundle_file + '.zsync', bundle_file
                            ])
                        else:
                            log.warning(
                                '--> zsyncmake missing, zsync setup skipped')
                if result_file.shasum:
                    log.info('--> Creating SHA 256 sum')
                    checksum = Checksum(bundle_file)
                    with open(checksum_file, 'w') as shasum:
                        shasum.write(checksum.sha256())
Exemplo n.º 31
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'])
        )