예제 #1
0
파일: zypper.py 프로젝트: Conan-Kudo/kiwi
    def process_install_requests(self):
        """
        Process package install requests for image phase (chroot)

        :return: process results in command type

        :rtype: namedtuple
        """
        if self.exclude_requests:
            # For zypper excluding a package means, removing it from
            # the solver operation. This is done by adding a package
            # lock. This means that if the package is hard required
            # by another package, it will break the transaction.
            metadata_dir = ''.join([self.root_dir, '/etc/zypp'])
            if not os.path.exists(metadata_dir):
                Path.create(metadata_dir)
            for package in self.exclude_requests:
                Command.run(
                    ['chroot', self.root_dir, 'zypper'] +
                    self.chroot_zypper_args + ['al'] + [package],
                    self.chroot_command_env
                )
        return Command.call(
            ['chroot', self.root_dir, 'zypper'] + self.chroot_zypper_args + [
                'install', '--auto-agree-with-licenses'
            ] + self.custom_args + self._install_items(),
            self.chroot_command_env
        )
예제 #2
0
파일: oci.py 프로젝트: Conan-Kudo/kiwi
    def sync_data(self):
        """
        Synchronize data from the given base image to the target root
        directory.
        """
        self.extract_oci_image()
        Command.run([
            'umoci', 'unpack', '--image',
            '{0}:base_layer'.format(self.oci_layout_dir), self.oci_unpack_dir
        ])

        synchronizer = DataSync(
            os.sep.join([self.oci_unpack_dir, 'rootfs', '']),
            ''.join([self.root_dir, os.sep])
        )
        synchronizer.sync_data(options=['-a', '-H', '-X', '-A'])

        # A copy of the uncompressed image and its checksum are
        # kept inside the root_dir in order to ensure the later steps
        # i.e. system create are atomic and don't need any third
        # party archive.
        image_copy = Defaults.get_imported_root_image(self.root_dir)
        Path.create(os.path.dirname(image_copy))
        image_tar = ArchiveTar(image_copy)
        image_tar.create(self.oci_layout_dir)
        self._make_checksum(image_copy)
예제 #3
0
파일: btrfs.py 프로젝트: Conan-Kudo/kiwi
    def mount_volumes(self):
        """
        Mount btrfs subvolumes
        """

        self.toplevel_mount.mount(
            self.custom_filesystem_args['mount_options']
        )

        for volume_mount in self.subvol_mount_list:
            if self.volumes_mounted_initially:
                volume_mount.mountpoint = os.path.normpath(
                    volume_mount.mountpoint.replace(self.toplevel_volume, '', 1)
                )
            if not os.path.exists(volume_mount.mountpoint):
                Path.create(volume_mount.mountpoint)
            subvol_name = self._get_subvol_name_from_mountpoint(volume_mount)
            subvol_options = ','.join(
                [
                    'subvol=' + subvol_name
                ] + self.custom_filesystem_args['mount_options']
            )
            volume_mount.mount(
                options=[subvol_options]
            )

        self.volumes_mounted_initially = True
예제 #4
0
    def mount_shared_directory(self, host_dir=None):
        """
        Bind mount shared location

        The shared location is a directory which shares data from
        the image buildsystem host with the image root system. It
        is used for the repository setup and the package manager
        cache to allow chroot operations without being forced to
        duplicate this data

        :param str host_dir: directory to share between image root and build
            system root

        :raises KiwiMountSharedDirectoryError: if mount fails
        """
        if not host_dir:
            host_dir = self.shared_location
        try:
            Path.create(self.root_dir + host_dir)
            Path.create('/' + host_dir)
            shared_mount = MountManager(
                device=host_dir, mountpoint=self.root_dir + host_dir
            )
            shared_mount.bind_mount()
            self.mount_stack.append(shared_mount)
            self.dir_stack.append(host_dir)
        except Exception as e:
            self.cleanup()
            raise KiwiMountSharedDirectoryError(
                '%s: %s' % (type(e).__name__, format(e))
            )
예제 #5
0
파일: docker.py 프로젝트: Conan-Kudo/kiwi
    def pack_image_to_file(self, filename):
        """
        Packs the given oci image into the given filename.

        :param string filename: file name of the resulting packed image
        """
        oci_image = os.sep.join([
            self.oci_dir, ':'.join(['umoci_layout', self.container_tag])
        ])

        additional_tags = []
        for tag in self.additional_tags:
            additional_tags.extend([
                '--additional-tag', '{0}:{1}'.format(self.container_name, tag)
            ])

        # make sure the target tar file does not exist
        # skopeo doesn't support force overwrite
        Path.wipe(filename)
        Command.run(
            [
                'skopeo', 'copy', 'oci:{0}'.format(
                    oci_image
                ),
                'docker-archive:{0}:{1}:{2}'.format(
                    filename, self.container_name, self.container_tag
                )
            ] + additional_tags
        )
        container_compressor = self.runtime_config.get_container_compression()
        if container_compressor:
            compressor = Compress(filename)
            return compressor.xz(self.runtime_config.get_xz_options())
        else:
            return filename
예제 #6
0
파일: setup.py 프로젝트: AdamMajer/kiwi-ng
 def setup_locale(self):
     """
     Setup UTF8 system wide locale
     """
     if 'locale' in self.preferences:
         if 'POSIX' in self.preferences['locale'].split(','):
             locale = 'POSIX'
         else:
             locale = '{0}.UTF-8'.format(
                 self.preferences['locale'].split(',')[0]
             )
         log.info('Setting up locale: %s', self.preferences['locale'])
         if CommandCapabilities.has_option_in_help(
             'systemd-firstboot', '--locale',
             root=self.root_dir, raise_on_error=False
         ):
             Path.wipe(self.root_dir + '/etc/locale.conf')
             Command.run([
                 'chroot', self.root_dir, 'systemd-firstboot',
                 '--locale=' + locale
             ])
         elif os.path.exists(self.root_dir + '/etc/sysconfig/language'):
             Shell.run_common_function(
                 'baseUpdateSysConfig', [
                     self.root_dir + '/etc/sysconfig/language',
                     'RC_LANG', locale
                 ]
             )
         else:
             log.warning(
                 'locale setup skipped no capable '
                 'systemd-firstboot or etc/sysconfig/language not found'
             )
예제 #7
0
파일: setup.py 프로젝트: AdamMajer/kiwi-ng
 def setup_keyboard_map(self):
     """
     Setup console keyboard
     """
     if 'keytable' in self.preferences:
         log.info(
             'Setting up keytable: %s', self.preferences['keytable']
         )
         if CommandCapabilities.has_option_in_help(
             'systemd-firstboot', '--keymap',
             root=self.root_dir, raise_on_error=False
         ):
             Path.wipe(self.root_dir + '/etc/vconsole.conf')
             Command.run([
                 'chroot', self.root_dir, 'systemd-firstboot',
                 '--keymap=' + self.preferences['keytable']
             ])
         elif os.path.exists(self.root_dir + '/etc/sysconfig/keyboard'):
             Shell.run_common_function(
                 'baseUpdateSysConfig', [
                     self.root_dir + '/etc/sysconfig/keyboard', 'KEYTABLE',
                     '"' + self.preferences['keytable'] + '"'
                 ]
             )
         else:
             log.warning(
                 'keyboard setup skipped no capable '
                 'systemd-firstboot or etc/sysconfig/keyboard found'
             )
예제 #8
0
 def _create_iso_install_kernel_and_initrd(self):
     boot_path = self.media_dir + '/boot/' + self.arch + '/loader'
     Path.create(boot_path)
     kernel = Kernel(self.boot_image_task.boot_root_directory)
     if kernel.get_kernel():
         kernel.copy_kernel(boot_path, '/linux')
     else:
         raise KiwiInstallBootImageError(
             'No kernel in boot image tree %s found' %
             self.boot_image_task.boot_root_directory
         )
     if self.xml_state.is_xen_server():
         if kernel.get_xen_hypervisor():
             kernel.copy_xen_hypervisor(boot_path, '/xen.gz')
         else:
             raise KiwiInstallBootImageError(
                 'No hypervisor in boot image tree %s found' %
                 self.boot_image_task.boot_root_directory
             )
     if self.initrd_system == 'dracut':
         self._create_dracut_install_config()
         self._add_system_image_boot_options_to_boot_image()
     self.boot_image_task.create_initrd(self.mbrid, 'initrd_kiwi_install')
     Command.run(
         [
             'mv', self.boot_image_task.initrd_filename,
             boot_path + '/initrd'
         ]
     )
예제 #9
0
파일: zypper.py 프로젝트: AdamMajer/kiwi-ng
 def _create_zypper_runtime_environment(self):
     for zypper_dir in list(self.shared_zypper_dir.values()):
         Path.create(zypper_dir)
     return dict(
         os.environ,
         LANG='C',
         ZYPP_CONF=self.runtime_zypp_config_file.name
     )
예제 #10
0
파일: apt.py 프로젝트: AdamMajer/kiwi-ng
    def process_install_requests_bootstrap(self):
        """
        Process package install requests for bootstrap phase (no chroot)
        The debootstrap program is used to bootstrap a new system with
        a collection of predefined packages. The kiwi bootstrap section
        information is not used in this case
        """
        if not self.distribution:
            raise KiwiDebootstrapError(
                'No main distribution repository is configured'
            )
        bootstrap_script = '/usr/share/debootstrap/scripts/' + \
            self.distribution
        if not os.path.exists(bootstrap_script):
            raise KiwiDebootstrapError(
                'debootstrap script for %s distribution not found' %
                self.distribution
            )
        bootstrap_dir = self.root_dir + '.debootstrap'
        if 'apt-get' in self.package_requests:
            # debootstrap takes care to install apt-get
            self.package_requests.remove('apt-get')
        try:
            dev_mount = MountManager(
                device='/dev', mountpoint=self.root_dir + '/dev'
            )
            dev_mount.umount()
            if self.repository.unauthenticated == 'false':
                log.warning(
                    'KIWI does not support signature checks for apt-get '
                    'package manager during the bootstrap procedure, any '
                    'provided key will only be used inside the chroot '
                    'environment'
                )
            Command.run(
                [
                    'debootstrap', '--no-check-gpg', self.distribution,
                    bootstrap_dir, self.distribution_path
                ], self.command_env
            )
            data = DataSync(
                bootstrap_dir + '/', self.root_dir
            )
            data.sync_data(
                options=['-a', '-H', '-X', '-A']
            )
            for key in self.repository.signing_keys:
                Command.run([
                    'chroot', self.root_dir, 'apt-key', 'add', key
                ], self.command_env)
        except Exception as e:
            raise KiwiDebootstrapError(
                '%s: %s' % (type(e).__name__, format(e))
            )
        finally:
            Path.wipe(bootstrap_dir)

        return self.process_install_requests()
예제 #11
0
파일: live.py 프로젝트: Conan-Kudo/kiwi
 def __del__(self):
     if self.media_dir or self.live_container_dir:
         log.info(
             'Cleaning up {0} instance'.format(type(self).__name__)
         )
         if self.media_dir:
             Path.wipe(self.media_dir)
         if self.live_container_dir:
             Path.wipe(self.live_container_dir)
예제 #12
0
파일: yum.py 프로젝트: AdamMajer/kiwi-ng
    def delete_repo(self, name):
        """
        Delete yum repository

        :param string name: repository base file name
        """
        Path.wipe(
            self.shared_yum_dir['reposd-dir'] + '/' + name + '.repo'
        )
예제 #13
0
 def _cleanup_dir_stack(self):
     for location in reversed(self.dir_stack):
         try:
             Path.remove_hierarchy(self.root_dir + location)
         except Exception as e:
             log.warning(
                 'Failed to remove directory %s: %s', location, format(e)
             )
     del self.dir_stack[:]
예제 #14
0
 def test_remove_hierarchy(self, mock_log_warn, mock_command):
     Path.remove_hierarchy('/my_root/tmp/foo/bar')
     assert mock_command.call_args_list == [
         call(['rmdir', '--ignore-fail-on-non-empty', '/my_root/tmp/foo/bar']),
         call(['rmdir', '--ignore-fail-on-non-empty', '/my_root/tmp/foo'])
     ]
     mock_log_warn.assert_called_once_with(
         'remove_hierarchy: path /my_root/tmp is protected'
     )
예제 #15
0
파일: apt.py 프로젝트: AdamMajer/kiwi-ng
    def delete_repo(self, name):
        """
        Delete apt-get repository

        :param string name: repository base file name
        """
        Path.wipe(
            self.shared_apt_get_dir['sources-dir'] + '/' + name + '.list'
        )
예제 #16
0
파일: lvm.py 프로젝트: AdamMajer/kiwi-ng
 def mount_volumes(self):
     """
     Mount lvm volumes
     """
     for volume_mount in self.mount_list:
         Path.create(volume_mount.mountpoint)
         volume_mount.mount(
             options=[self.mount_options]
         )
     self.volumes_mounted_initially = True
예제 #17
0
파일: lvm.py 프로젝트: AdamMajer/kiwi-ng
 def __del__(self):
     if self.volume_group:
         log.info('Cleaning up %s instance', type(self).__name__)
         if self.umount_volumes():
             Path.wipe(self.mountpoint)
             try:
                 Command.run(['vgchange', '-an', self.volume_group])
             except Exception:
                 log.warning(
                     'volume group %s still busy', self.volume_group
                 )
예제 #18
0
파일: btrfs.py 프로젝트: Conan-Kudo/kiwi
    def create_volumes(self, filesystem_name):
        """
        Create configured btrfs subvolumes

        Any btrfs subvolume is of the same btrfs filesystem. There is no
        way to have different filesystems per btrfs subvolume. Thus
        the filesystem_name has no effect for btrfs

        :param string filesystem_name: unused
        """
        log.info(
            'Creating %s sub volumes', filesystem_name
        )
        self.create_volume_paths_in_root_dir()

        canonical_volume_list = self.get_canonical_volume_list()
        if canonical_volume_list.full_size_volume:
            # put an eventual fullsize volume to the volume list
            # because there is no extra handling required for it on btrfs
            canonical_volume_list.volumes.append(
                canonical_volume_list.full_size_volume
            )

        for volume in canonical_volume_list.volumes:
            if volume.name == 'LVRoot':
                # the btrfs root volume named '@' has been created as
                # part of the setup procedure
                pass
            else:
                log.info('--> sub volume %s', volume.realpath)
                toplevel = self.mountpoint + '/@/'
                volume_parent_path = os.path.normpath(
                    toplevel + os.path.dirname(volume.realpath)
                )
                if not os.path.exists(volume_parent_path):
                    Path.create(volume_parent_path)
                Command.run(
                    [
                        'btrfs', 'subvolume', 'create',
                        os.path.normpath(toplevel + volume.realpath)
                    ]
                )
                self.apply_attributes_on_volume(
                    toplevel, volume
                )
                if self.custom_args['root_is_snapshot']:
                    snapshot = self.mountpoint + '/@/.snapshots/1/snapshot/'
                    volume_mount = MountManager(
                        device=self.device,
                        mountpoint=os.path.normpath(snapshot + volume.realpath)
                    )
                    self.subvol_mount_list.append(
                        volume_mount
                    )
예제 #19
0
파일: base.py 프로젝트: AdamMajer/kiwi-ng
    def _cleanup(self):
        """
        Delete all temporary directories
        """
        for metadata_dir in self.repository_metadata_dirs:
            Path.wipe(metadata_dir)

        if self.repository_solvable_dir:
            Path.wipe(self.repository_solvable_dir)

        self._init_temporary_dir_names()
예제 #20
0
파일: base.py 프로젝트: AdamMajer/kiwi-ng
    def create_efi_path(self, in_sub_dir='boot/efi'):
        """
        Create standard EFI boot directory structure

        :param string in_sub_dir: toplevel directory

        :return: Full qualified EFI boot path
        :rtype: string
        """
        efi_boot_path = self.root_dir + '/' + in_sub_dir + '/EFI/BOOT'
        Path.create(efi_boot_path)
        return efi_boot_path
예제 #21
0
파일: yum.py 프로젝트: AdamMajer/kiwi-ng
    def cleanup_unused_repos(self):
        """
        Delete unused yum repositories

        Repository configurations which are not used for this build
        must be removed otherwise they are taken into account for
        the package installations
        """
        repos_dir = self.shared_yum_dir['reposd-dir']
        repo_files = list(os.walk(repos_dir))[0][2]
        for repo_file in repo_files:
            if repo_file not in self.repo_names:
                Path.wipe(repos_dir + '/' + repo_file)
예제 #22
0
파일: yum.py 프로젝트: AdamMajer/kiwi-ng
    def delete_repo_cache(self, name):
        """
        Delete yum repository cache

        The cache data for each repository is stored in a directory
        of the same name as the repository name. The method deletes
        this directory to cleanup the cache information

        :param string name: repository name
        """
        Path.wipe(
            os.sep.join([self.shared_yum_dir['cache-dir'], name])
        )
예제 #23
0
파일: apt.py 프로젝트: AdamMajer/kiwi-ng
    def delete_repo_cache(self, name):
        """
        Delete apt-get repository cache

        Apt stores the package cache in a collection of binary files
        and deb archives. As of now I couldn't came across a solution
        which allows for deleting only the cache data for a specific
        repository. Thus the repo cache cleanup affects all cache
        data

        :param string name: unused
        """
        for cache_file in ['archives', 'pkgcache.bin', 'srcpkgcache.bin']:
            Path.wipe(os.sep.join([self.manager_base, cache_file]))
예제 #24
0
파일: base.py 프로젝트: Conan-Kudo/kiwi
 def create_volume_paths_in_root_dir(self):
     """
     Implements creation of volume paths in the given root directory
     """
     for volume in self.volumes:
         if volume.realpath and not volume.realpath == os.sep:
             volume_image_path = os.path.normpath(
                 self.root_dir + os.sep + volume.realpath
             )
             if not os.path.exists(volume_image_path):
                 # not existing volume paths will be created in the image
                 # root directory. This happens hidden to the user but is
                 # imho ok because the path is explicitly configured as a
                 # volume
                 Path.create(volume_image_path)
예제 #25
0
파일: setup.py 프로젝트: AdamMajer/kiwi-ng
    def import_description(self):
        """
        Import XML descriptions, custom scripts, archives and
        script helper methods
        """
        log.info('Importing Image description to system tree')
        description = self.root_dir + '/image/config.xml'
        log.info('--> Importing state XML description as image/config.xml')
        Path.create(self.root_dir + '/image')
        with open(description, 'w') as config:
            config.write('<?xml version="1.0" encoding="utf-8"?>')
            self.xml_state.xml_data.export(outfile=config, level=0)

        self._import_custom_scripts()
        self._import_custom_archives()
예제 #26
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'])
        )
예제 #27
0
    def write(self):
        """
        Write isolinux.cfg and isolinux.msg file
        """
        log.info('Writing isolinux.cfg file')
        config_dir = self._get_iso_boot_path()
        config_file = config_dir + '/isolinux.cfg'
        if self.config:
            Path.create(config_dir)
            with open(config_file, 'w') as config:
                config.write(self.config)

        config_file_message = config_dir + '/isolinux.msg'
        if self.config_message:
            with open(config_file_message, 'w') as config:
                config.write(self.config_message)
예제 #28
0
파일: disk.py 프로젝트: Conan-Kudo/kiwi
 def _load_boot_image_instance(self):
     boot_image_dump_file = self.target_dir + '/boot_image.pickledump'
     if not os.path.exists(boot_image_dump_file):
         raise KiwiInstallMediaError(
             'No boot image instance dump %s found' % boot_image_dump_file
         )
     try:
         with open(boot_image_dump_file, 'rb') as boot_image_dump:
             boot_image = pickle.load(boot_image_dump)
         boot_image.enable_cleanup()
         Path.wipe(boot_image_dump_file)
     except Exception as e:
         raise KiwiInstallMediaError(
             'Failed to load boot image dump: %s' % type(e).__name__
         )
     return boot_image
예제 #29
0
 def _get_shim_install(self):
     chroot_env = {
         'PATH': os.sep.join([self.root_dir, 'usr', 'sbin'])
     }
     return Path.which(
         filename='shim-install', custom_env=chroot_env
     )
예제 #30
0
파일: base.py 프로젝트: Conan-Kudo/kiwi
    def get_canonical_volume_list(self):
        """
        Implements hierarchical sorting of volumes according to their
        paths and provides information about the volume configured as
        the one eating all the rest space

        :return: list of canonical_volume_type tuples

        :rtype: list
        """
        canonical_volume_type = namedtuple(
            'canonical_volume_type', [
                'volumes', 'full_size_volume'
            ]
        )
        volume_paths = {}
        full_size_volume = None
        for volume in self.volumes:
            if volume.fullsize:
                full_size_volume = volume
            elif volume.realpath:
                volume_paths[volume.realpath] = volume

        volume_list = []
        for realpath in Path.sort_by_hierarchy(sorted(volume_paths.keys())):
            volume_list.append(volume_paths[realpath])
        return canonical_volume_type(
            volumes=volume_list, full_size_volume=full_size_volume
        )
예제 #31
0
 def _get_shim_install(self):
     return Path.which(filename='shim-install', root_dir=self.boot_dir)
예제 #32
0
 def create_recovery_archive(self):
     """
     Create a compressed recovery archive from the root tree
     for use with kiwi's recvoery system. The method creates
     additional data into the image root filesystem which is
     deleted prior to the creation of a new recovery data set
     """
     # cleanup
     bash_comand = [
         'rm', '-f', self.root_dir + '/recovery.*'
     ]
     Command.run(['bash', '-c', ' '.join(bash_comand)])
     if not self.oemconfig['recovery']:
         return
     # recovery.tar
     log.info('Creating recovery tar archive')
     metadata = {
         'archive_name':
             self.root_dir + '/recovery.tar',
         'archive_filecount':
             self.root_dir + '/recovery.tar.files',
         'archive_size':
             self.root_dir + '/recovery.tar.size',
         'partition_size':
             self.root_dir + '/recovery.partition.size',
         'partition_filesystem':
             self.root_dir + '/recovery.tar.filesystem'
     }
     recovery_archive = NamedTemporaryFile(
         delete=False
     )
     archive = ArchiveTar(
         filename=recovery_archive.name,
         create_from_file_list=False
     )
     archive.create(
         source_dir=self.root_dir,
         exclude=['dev', 'proc', 'sys'],
         options=[
             '--numeric-owner',
             '--hard-dereference',
             '--preserve-permissions'
         ]
     )
     Command.run(
         ['mv', recovery_archive.name, metadata['archive_name']]
     )
     # recovery.tar.filesystem
     recovery_filesystem = self.xml_state.build_type.get_filesystem()
     with open(metadata['partition_filesystem'], 'w') as partfs:
         partfs.write('{0}'.format(recovery_filesystem))
     log.info(
         '--> Recovery partition filesystem: {0}'.format(recovery_filesystem)
     )
     # recovery.tar.files
     bash_comand = [
         'tar', '-tf', metadata['archive_name'], '|', 'wc', '-l'
     ]
     tar_files_call = Command.run(
         ['bash', '-c', ' '.join(bash_comand)]
     )
     tar_files_count = int(tar_files_call.output.rstrip('\n'))
     with open(metadata['archive_filecount'], 'w') as files:
         files.write('{0}{1}'.format(tar_files_count, os.linesep))
     log.info(
         '--> Recovery file count: {0} files'.format(tar_files_count)
     )
     # recovery.tar.size
     recovery_archive_size_bytes = os.path.getsize(metadata['archive_name'])
     with open(metadata['archive_size'], 'w') as size:
         size.write('{0}'.format(recovery_archive_size_bytes))
     log.info(
         '--> Recovery uncompressed size: {0} mbytes'.format(
             int(recovery_archive_size_bytes / 1048576)
         )
     )
     # recovery.tar.gz
     log.info('--> Compressing recovery archive')
     compress = Compress(self.root_dir + '/recovery.tar')
     compress.gzip()
     # recovery.partition.size
     recovery_archive_gz_size_mbytes = int(
         os.path.getsize(metadata['archive_name'] + '.gz') / 1048576
     )
     recovery_partition_mbytes = recovery_archive_gz_size_mbytes \
         + Defaults.get_recovery_spare_mbytes()
     with open(metadata['partition_size'], 'w') as gzsize:
         gzsize.write('{0}'.format(recovery_partition_mbytes))
     log.info(
         '--> Recovery partition size: {0} mbytes'.format(
             recovery_partition_mbytes
         )
     )
     # delete recovery archive if inplace recovery is requested
     # In this mode the recovery archive is created at install time
     # and not at image creation time. However the recovery metadata
     # is preserved in order to be able to check if enough space
     # is available on the disk to create the recovery archive.
     if self.oemconfig['recovery_inplace']:
         log.info(
             '--> Inplace recovery requested, deleting archive'
         )
         Path.wipe(metadata['archive_name'] + '.gz')
예제 #33
0
파일: base.py 프로젝트: nadvornik/kiwi
 def __del__(self):
     if self.temp_image_dir and os.path.exists(self.temp_image_dir):
         log.info('Cleaning up %s instance', type(self).__name__)
         Path.wipe(self.temp_image_dir)
예제 #34
0
 def __init__(self, data, style='standard'):
     self.data = data
     self.style = style
     self.color_json = Path.which('pjson')
예제 #35
0
파일: grub2.py 프로젝트: hwoarang/kiwi
 def _get_shim_install(self):
     chroot_env = {'PATH': os.sep.join([self.root_dir, 'usr', 'sbin'])}
     return Path.which(filename='shim-install', custom_env=chroot_env)
예제 #36
0
파일: grub2.py 프로젝트: hwoarang/kiwi
 def _get_grub2_mkimage_tool(self):
     for grub_mkimage_tool in ['grub2-mkimage', 'grub-mkimage']:
         if Path.which(grub_mkimage_tool):
             return grub_mkimage_tool
예제 #37
0
파일: grub2.py 프로젝트: lorenzen-b1/kiwi
    def _copy_theme_data_to_boot_directory(self, lookup_path, target):
        if not lookup_path:
            lookup_path = self.boot_dir
        boot_fonts_dir = os.path.normpath(
            os.sep.join(
                [
                    self.boot_dir,
                    self.get_boot_path(target),
                    self.boot_directory_name,
                    'fonts'
                ]
            )
        )
        Path.create(boot_fonts_dir)
        boot_unicode_font = boot_fonts_dir + '/unicode.pf2'
        if not os.path.exists(boot_unicode_font):
            try:
                unicode_font = Defaults.get_grub_path(
                    lookup_path, 'unicode.pf2'
                )
                Command.run(
                    ['cp', unicode_font, boot_unicode_font]
                )
            except Exception as issue:
                raise KiwiBootLoaderGrubFontError(
                    'Setting up unicode font failed with {0}'.format(issue)
                )

        boot_theme_dir = os.sep.join(
            [self.boot_dir, 'boot', self.boot_directory_name, 'themes']
        )
        Path.create(boot_theme_dir)

        if self.theme:
            theme_dir = Defaults.get_grub_path(
                lookup_path, 'themes/' + self.theme, raise_on_error=False
            )
            boot_theme_background_file = self._find_theme_background_file(
                lookup_path
            )
            if theme_dir and os.path.exists(theme_dir):
                if boot_theme_background_file:
                    # A background file was found. Preserve a copy of the
                    # file which was created at install time of the theme
                    # package by the activate-theme script
                    boot_theme_background_backup_file = os.sep.join(
                        [self.boot_dir, 'background.png']
                    )
                    Command.run(
                        [
                            'cp', boot_theme_background_file,
                            boot_theme_background_backup_file
                        ]
                    )
                # sync theme data from install path to boot path
                data = DataSync(
                    theme_dir, boot_theme_dir
                )
                data.sync_data(
                    options=['-a']
                )
                if boot_theme_background_file:
                    # Install preserved background file to the theme
                    Command.run(
                        [
                            'mv', boot_theme_background_backup_file,
                            os.sep.join([boot_theme_dir, self.theme])
                        ]
                    )
            elif boot_theme_background_file:
                # assume all theme data is in the directory of the
                # background file and just sync that directory to the
                # boot path
                data = DataSync(
                    os.path.dirname(boot_theme_background_file), boot_theme_dir
                )
                data.sync_data(
                    options=['-a']
                )

        self._check_boot_theme_exists()
예제 #38
0
 def _get_grub2_mkconfig_tool(self):
     for grub_mkconfig_tool in ['grub2-mkconfig', 'grub-mkconfig']:
         grub_mkconfig_file_path = Path.which(grub_mkconfig_tool,
                                              root_dir=self.root_dir)
         if grub_mkconfig_file_path:
             return grub_mkconfig_file_path
예제 #39
0
파일: umoci.py 프로젝트: D4N/kiwi
 def __del__(self):
     if self.oci_root_dir:
         Path.wipe(self.oci_root_dir)
     if self.oci_dir:
         Path.wipe(self.oci_dir)
예제 #40
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']
        )
        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'])
        )
예제 #41
0
 def __del__(self):
     if self.mountpoint_created_by_mount_manager and not self.is_mounted():
         Path.wipe(self.mountpoint)
예제 #42
0
 def __del__(self):
     for mount in reversed(self.mount_stack):
         if mount.is_mounted():
             if mount.umount():
                 Path.wipe(mount.mountpoint)
예제 #43
0
 def _create_zypper_runtime_environment(self):
     for zypper_dir in list(self.shared_zypper_dir.values()):
         Path.create(zypper_dir)
     return dict(os.environ,
                 LANG='C',
                 ZYPP_CONF=self.runtime_zypp_config_file.name)
예제 #44
0
 def delete_all_repos(self):
     """
     Delete all zypper repositories
     """
     Path.wipe(self.shared_zypper_dir['reposd-dir'])
     Path.create(self.shared_zypper_dir['reposd-dir'])
예제 #45
0
    def add_repo(self,
                 name,
                 uri,
                 repo_type='rpm-md',
                 prio=None,
                 dist=None,
                 components=None,
                 user=None,
                 secret=None,
                 credentials_file=None,
                 repo_gpgcheck=None,
                 pkg_gpgcheck=None):
        """
        Add zypper repository

        :param str name: repository name
        :param str uri: repository URI
        :param repo_type: repostory type name
        :param int prio: zypper repostory priority
        :param dist: unused
        :param components: unused
        :param user: credentials username
        :param secret: credentials password
        :param credentials_file: zypper credentials file
        :param bool repo_gpgcheck: enable repository signature validation
        :param bool pkg_gpgcheck: enable package signature validation
        """
        if credentials_file:
            repo_secret = os.sep.join(
                [self.shared_zypper_dir['credentials-dir'], credentials_file])
            if os.path.exists(repo_secret):
                Path.wipe(repo_secret)

            if user and secret:
                uri = ''.join([uri, '?credentials=', credentials_file])
                with open(repo_secret, 'w') as credentials:
                    credentials.write('username={0}{1}'.format(
                        user, os.linesep))
                    credentials.write('password={0}{1}'.format(
                        secret, os.linesep))

        repo_file = ''.join(
            [self.shared_zypper_dir['reposd-dir'], '/', name, '.repo'])
        self.repo_names.append(''.join([name, '.repo']))

        if os.path.exists(repo_file):
            Path.wipe(repo_file)

        self._backup_package_cache()
        zypper_addrepo_command = ['zypper'] + self.zypper_args + [
            '--root', self.root_dir, 'addrepo', '--refresh', '--keep-packages'
            if Uri(uri).is_remote() else '--no-keep-packages', '--no-check',
            uri, name
        ]
        try:
            Command.run(zypper_addrepo_command, self.command_env)
        except Exception:
            # for whatever reason zypper sometimes failes with
            # a 'failed to cache rpm database' error. I could not
            # find any reason why and a simple recall of the exact
            # same command in the exact same environment works.
            # Thus the stupid but simple workaround to this problem
            # is try one recall before really failing
            Command.run(zypper_addrepo_command, self.command_env)

        if prio or repo_gpgcheck is not None or pkg_gpgcheck is not None:
            repo_config = ConfigParser()
            repo_config.read(repo_file)
            if repo_gpgcheck is not None:
                repo_config.set(name, 'repo_gpgcheck',
                                '1' if repo_gpgcheck else '0')
            if pkg_gpgcheck is not None:
                repo_config.set(name, 'pkg_gpgcheck',
                                '1' if pkg_gpgcheck else '0')
            if prio:
                repo_config.set(name, 'priority', format(prio))
            with open(repo_file, 'w') as repo:
                repo_config.write(repo)
        self._restore_package_cache()
예제 #46
0
    def create(self):
        """
        Build a bootable hybrid live ISO image

        Image types which triggers this builder are:

        * image="iso"
        """
        # media dir to store CD contents
        self.media_dir = mkdtemp(prefix='live-media.', dir=self.target_dir)
        rootsize = SystemSize(self.media_dir)

        # custom iso metadata
        log.info('Using following live ISO metadata:')
        log.info('--> Application id: {0}'.format(self.mbrid.get_id()))
        log.info('--> Publisher: {0}'.format(Defaults.get_publisher()))
        log.info('--> Volume id: {0}'.format(self.volume_id))
        custom_iso_args = {
            'create_options': [
                '-A',
                self.mbrid.get_id(), '-p',
                Defaults.get_preparer(), '-publisher',
                Defaults.get_publisher(), '-V', self.volume_id
            ]
        }

        # pack system into live boot structure as expected by dracut
        log.info('Packing system into dracut live ISO type: {0}'.format(
            self.live_type))
        root_filesystem = Defaults.get_default_live_iso_root_filesystem()
        filesystem_custom_parameters = {
            'mount_options': self.xml_state.get_fs_mount_option_list()
        }
        filesystem_setup = FileSystemSetup(self.xml_state, self.root_dir)
        root_image = NamedTemporaryFile()
        loop_provider = LoopDevice(
            root_image.name, filesystem_setup.get_size_mbytes(root_filesystem),
            self.xml_state.build_type.get_target_blocksize())
        loop_provider.create()
        live_filesystem = FileSystem(name=root_filesystem,
                                     device_provider=loop_provider,
                                     root_dir=self.root_dir + os.sep,
                                     custom_args=filesystem_custom_parameters)
        live_filesystem.create_on_device()
        log.info('--> Syncing data to {0} root image'.format(root_filesystem))
        live_filesystem.sync_data(
            Defaults.get_exclude_list_for_root_data_sync())
        log.info('--> Creating squashfs container for root image')
        self.live_container_dir = mkdtemp(prefix='live-container.',
                                          dir=self.target_dir)
        Path.create(self.live_container_dir + '/LiveOS')
        shutil.copy(root_image.name,
                    self.live_container_dir + '/LiveOS/rootfs.img')
        live_container_image = FileSystem(name='squashfs',
                                          device_provider=None,
                                          root_dir=self.live_container_dir)
        container_image = NamedTemporaryFile()
        live_container_image.create_on_file(container_image.name)
        Path.create(self.media_dir + '/LiveOS')
        shutil.copy(container_image.name,
                    self.media_dir + '/LiveOS/squashfs.img')

        # setup bootloader config to boot the ISO via isolinux
        log.info('Setting up isolinux bootloader configuration')
        bootloader_config_isolinux = BootLoaderConfig('isolinux',
                                                      self.xml_state,
                                                      self.media_dir)
        bootloader_config_isolinux.setup_live_boot_images(
            mbrid=None, lookup_path=self.boot_image.boot_root_directory)
        bootloader_config_isolinux.setup_live_image_config(mbrid=None)
        bootloader_config_isolinux.write()

        # setup bootloader config to boot the ISO via EFI
        if self.firmware.efi_mode():
            log.info('Setting up EFI grub bootloader configuration')
            bootloader_config_grub = BootLoaderConfig(
                'grub2', self.xml_state, self.media_dir, {
                    'grub_directory_name':
                    Defaults.get_grub_boot_directory_name(self.root_dir)
                })
            bootloader_config_grub.setup_live_boot_images(
                mbrid=self.mbrid, lookup_path=self.root_dir)
            bootloader_config_grub.setup_live_image_config(mbrid=self.mbrid)
            bootloader_config_grub.write()

        # call custom editbootconfig script if present
        self.system_setup.call_edit_boot_config_script(
            filesystem='iso:{0}'.format(self.media_dir),
            boot_part_id=1,
            working_directory=self.root_dir)

        # create dracut initrd for live image
        log.info('Creating live ISO boot image')
        self._create_dracut_live_iso_config()
        self.boot_image.create_initrd(self.mbrid)

        # setup kernel file(s) and initrd in ISO boot layout
        log.info('Setting up kernel file(s) and boot image in ISO boot layout')
        self._setup_live_iso_kernel_and_initrd()

        # calculate size and decide if we need UDF
        if rootsize.accumulate_mbyte_file_sizes() > 4096:
            log.info('ISO exceeds 4G size, using UDF filesystem')
            custom_iso_args['create_options'].append('-iso-level')
            custom_iso_args['create_options'].append('3')
            custom_iso_args['create_options'].append('-udf')

        # create iso filesystem from media_dir
        log.info('Creating live ISO image')
        iso_image = FileSystemIsoFs(device_provider=None,
                                    root_dir=self.media_dir,
                                    custom_args=custom_iso_args)
        iso_header_offset = iso_image.create_on_file(self.isoname)

        # make it hybrid
        if self.hybrid:
            Iso.create_hybrid(iso_header_offset, self.mbrid, self.isoname,
                              self.firmware.efi_mode())

        # include metadata for checkmedia tool
        if self.xml_state.build_type.get_mediacheck() is True:
            Iso.set_media_tag(self.isoname)

        self.result.add(key='live_image',
                        filename=self.isoname,
                        use_for_bundle=True,
                        compress=False,
                        shasum=True)
        self.result.add(key='image_packages',
                        filename=self.system_setup.export_package_list(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        self.result.add(key='image_verified',
                        filename=self.system_setup.export_package_verification(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        return self.result
예제 #47
0
파일: live.py 프로젝트: sitedata/kiwi-1
    def create(self):
        """
        Build a bootable hybrid live ISO image

        Image types which triggers this builder are:

        * image="iso"

        :raises KiwiLiveBootImageError: if no kernel or hipervisor is found
            in boot image tree
        :return: result

        :rtype: instance of :class:`Result`
        """
        # media dir to store CD contents
        self.media_dir = mkdtemp(prefix='live-media.', dir=self.target_dir)

        # unpack cdroot user files to media dir
        self.system_setup.import_cdroot_files(self.media_dir)

        rootsize = SystemSize(self.media_dir)

        # custom iso metadata
        log.info('Using following live ISO metadata:')
        log.info('--> Application id: {0}'.format(self.mbrid.get_id()))
        log.info('--> Publisher: {0}'.format(Defaults.get_publisher()))
        log.info('--> Volume id: {0}'.format(self.volume_id))
        custom_iso_args = {
            'meta_data': {
                'publisher': self.publisher,
                'preparer': Defaults.get_preparer(),
                'volume_id': self.volume_id,
                'mbr_id': self.mbrid.get_id(),
                'efi_mode': self.firmware.efi_mode()
            }
        }

        log.info('Setting up live image bootloader configuration')
        if self.firmware.efi_mode():
            # setup bootloader config to boot the ISO via EFI
            # This also embedds an MBR and the respective BIOS modules
            # for compat boot. The complete bootloader setup will be
            # based on grub
            bootloader_config = BootLoaderConfig(
                'grub2',
                self.xml_state,
                root_dir=self.root_dir,
                boot_dir=self.media_dir,
                custom_args={
                    'grub_directory_name':
                    Defaults.get_grub_boot_directory_name(self.root_dir)
                })
            bootloader_config.setup_live_boot_images(mbrid=self.mbrid,
                                                     lookup_path=self.root_dir)
        else:
            # setup bootloader config to boot the ISO via isolinux.
            # This allows for booting on x86 platforms in BIOS mode
            # only.
            bootloader_config = BootLoaderConfig('isolinux',
                                                 self.xml_state,
                                                 root_dir=self.root_dir,
                                                 boot_dir=self.media_dir)
        IsoToolsBase.setup_media_loader_directory(
            self.boot_image.boot_root_directory, self.media_dir,
            bootloader_config.get_boot_theme())
        bootloader_config.write_meta_data()
        bootloader_config.setup_live_image_config(mbrid=self.mbrid)
        bootloader_config.write()

        # call custom editbootconfig script if present
        self.system_setup.call_edit_boot_config_script(
            filesystem='iso:{0}'.format(self.media_dir),
            boot_part_id=1,
            working_directory=self.root_dir)

        # prepare dracut initrd call
        self.boot_image.prepare()

        # create dracut initrd for live image
        log.info('Creating live ISO boot image')
        live_dracut_modules = Defaults.get_live_dracut_modules_from_flag(
            self.live_type)
        live_dracut_modules.append('pollcdrom')
        for dracut_module in live_dracut_modules:
            self.boot_image.include_module(dracut_module)
        self.boot_image.omit_module('multipath')
        self.boot_image.write_system_config_file(
            config={
                'modules': live_dracut_modules,
                'omit_modules': ['multipath']
            },
            config_file=self.root_dir + '/etc/dracut.conf.d/02-livecd.conf')
        self.boot_image.create_initrd(self.mbrid)

        # setup kernel file(s) and initrd in ISO boot layout
        log.info('Setting up kernel file(s) and boot image in ISO boot layout')
        self._setup_live_iso_kernel_and_initrd()

        # calculate size and decide if we need UDF
        if rootsize.accumulate_mbyte_file_sizes() > 4096:
            log.info('ISO exceeds 4G size, using UDF filesystem')
            custom_iso_args['meta_data']['udf'] = True

        # pack system into live boot structure as expected by dracut
        log.info('Packing system into dracut live ISO type: {0}'.format(
            self.live_type))
        root_filesystem = Defaults.get_default_live_iso_root_filesystem()
        filesystem_custom_parameters = {
            'mount_options': self.xml_state.get_fs_mount_option_list(),
            'create_options': self.xml_state.get_fs_create_option_list()
        }
        filesystem_setup = FileSystemSetup(self.xml_state, self.root_dir)
        root_image = NamedTemporaryFile()
        loop_provider = LoopDevice(
            root_image.name, filesystem_setup.get_size_mbytes(root_filesystem),
            self.xml_state.build_type.get_target_blocksize())
        loop_provider.create()
        live_filesystem = FileSystem.new(
            name=root_filesystem,
            device_provider=loop_provider,
            root_dir=self.root_dir + os.sep,
            custom_args=filesystem_custom_parameters)
        live_filesystem.create_on_device()
        log.info('--> Syncing data to {0} root image'.format(root_filesystem))
        live_filesystem.sync_data(
            Defaults.get_exclude_list_for_root_data_sync())
        live_filesystem.umount()

        log.info('--> Creating squashfs container for root image')
        self.live_container_dir = mkdtemp(prefix='live-container.',
                                          dir=self.target_dir)
        Path.create(self.live_container_dir + '/LiveOS')
        shutil.copy(root_image.name,
                    self.live_container_dir + '/LiveOS/rootfs.img')
        live_container_image = FileSystem.new(
            name='squashfs',
            device_provider=None,
            root_dir=self.live_container_dir,
            custom_args={
                'compression':
                self.xml_state.build_type.get_squashfscompression()
            })
        container_image = NamedTemporaryFile()
        live_container_image.create_on_file(container_image.name)
        Path.create(self.media_dir + '/LiveOS')
        shutil.copy(container_image.name,
                    self.media_dir + '/LiveOS/squashfs.img')

        # create iso filesystem from media_dir
        log.info('Creating live ISO image')
        iso_image = FileSystemIsoFs(device_provider=None,
                                    root_dir=self.media_dir,
                                    custom_args=custom_iso_args)
        iso_image.create_on_file(self.isoname)

        # include metadata for checkmedia tool
        if self.xml_state.build_type.get_mediacheck() is True:
            Iso.set_media_tag(self.isoname)

        self.result.verify_image_size(
            self.runtime_config.get_max_size_constraint(), self.isoname)
        self.result.add(key='live_image',
                        filename=self.isoname,
                        use_for_bundle=True,
                        compress=False,
                        shasum=True)
        self.result.add(key='image_packages',
                        filename=self.system_setup.export_package_list(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        self.result.add(key='image_verified',
                        filename=self.system_setup.export_package_verification(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        return self.result