Esempio n. 1
0
    def create(self):
        """
        Create new system root directory

        The method creates a temporary directory and initializes it
        for the purpose of building a system image from it. This
        includes the following setup:

        * create static core device nodes
        * create core system paths

        On success the contents of the temporary location are
        synced to the specified root_dir and the temporary location
        will be deleted. That way we never work on an incomplete
        initial setup
        """
        root = mkdtemp(prefix='kiwi_root.')
        Path.create(self.root_dir)
        try:
            self._create_base_directories(root)
            self._create_device_nodes(root)
            self._create_base_links(root)
            self._setup_config_templates(root)
            data = DataSync(root + '/', self.root_dir)
            data.sync_data(options=['-a', '--ignore-existing'])
        except Exception as e:
            self.delete()
            raise KiwiRootInitCreationError('%s: %s' %
                                            (type(e).__name__, format(e)))
        finally:
            rmtree(root, ignore_errors=True)
Esempio n. 2
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))
            )
Esempio n. 3
0
    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)
Esempio n. 4
0
    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', 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)
Esempio n. 5
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']})
        result = image_builder.create()
        result.print_results()
        result.dump(os.sep.join([abs_target_dir_path, 'kiwi.result']))
Esempio n. 6
0
    def setup(self, name=None):
        """
        Setup btrfs volume management

        In case of btrfs a toplevel(@) subvolume is created and marked
        as default volume. If snapshots are activated via the custom_args
        the setup method also created the @/.snapshots/1/snapshot
        subvolumes. There is no concept of a volume manager name, thus
        the name argument is not used for btrfs

        :param string name: unused
        """
        self.setup_mountpoint()

        filesystem = FileSystem(name='btrfs',
                                device_provider=MappedDevice(
                                    device=self.device, device_provider=self),
                                custom_args=self.custom_filesystem_args)
        filesystem.create_on_device(label=self.custom_args['root_label'])
        self.toplevel_mount = MountManager(device=self.device,
                                           mountpoint=self.mountpoint)
        self.toplevel_mount.mount(self.custom_filesystem_args['mount_options'])
        root_volume = self.mountpoint + '/@'
        Command.run(['btrfs', 'subvolume', 'create', root_volume])
        if self.custom_args['root_is_snapshot']:
            snapshot_volume = self.mountpoint + '/@/.snapshots'
            Command.run(['btrfs', 'subvolume', 'create', snapshot_volume])
            Path.create(snapshot_volume + '/1')
            snapshot = self.mountpoint + '/@/.snapshots/1/snapshot'
            Command.run(
                ['btrfs', 'subvolume', 'snapshot', root_volume, snapshot])
            self._set_default_volume('@/.snapshots/1/snapshot')
        else:
            self._set_default_volume('@')
Esempio n. 7
0
File: live.py Progetto: isbm/kiwi
    def _setup_live_iso_kernel_and_initrd(self):
        """
        Copy kernel and initrd from the root tree into the iso boot structure
        """
        boot_path = ''.join([self.media_dir, '/boot/', self.arch, '/loader'])
        Path.create(boot_path)

        # Move kernel files to iso filesystem structure
        kernel = Kernel(self.boot_image.boot_root_directory)
        if kernel.get_kernel():
            kernel.copy_kernel(boot_path, '/linux')
        else:
            raise KiwiLiveBootImageError(
                'No kernel in boot image tree {0} found'.format(
                    self.boot_image.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 KiwiLiveBootImageError(
                    'No hypervisor in boot image tree {0} found'.format(
                        self.boot_image.boot_root_directory))

        # Move initrd to iso filesystem structure
        if os.path.exists(self.boot_image.initrd_filename):
            shutil.move(self.boot_image.initrd_filename, boot_path + '/initrd')
        else:
            raise KiwiLiveBootImageError(
                'No boot image {0} in boot image tree {1} found'.format(
                    self.boot_image.initrd_filename,
                    self.boot_image.boot_root_directory))
Esempio n. 8
0
    def create_initrd(self,
                      mbrid: Optional[SystemIdentifier] = None,
                      basename: Optional[str] = None,
                      install_initrd: bool = False) -> None:
        """
        Create initrd from prepared boot system tree and compress the result

        :param SystemIdentifier mbrid: instance of ImageIdentifier
        :param str basename: base initrd file name
        :param bool install_initrd: installation media initrd

        """
        if self.is_prepared():
            log.info('Creating initrd cpio archive')
            # we can't simply exclude boot when building the archive
            # because the file boot/mbrid must be preserved. Because of
            # that we create a copy of the boot directory and remove
            # everything in boot/ except for boot/mbrid. The original
            # boot directory should not be changed because we rely
            # on other data in boot/ e.g the kernel to be available
            # for the entire image building process
            if basename:
                kiwi_initrd_basename = basename
            else:
                kiwi_initrd_basename = self.initrd_base_name
            temp_boot_root = Temporary(prefix='kiwi_boot_root_copy.').new_dir()
            temp_boot_root_directory = temp_boot_root.name
            os.chmod(temp_boot_root_directory, 0o755)
            data = DataSync(self.boot_root_directory + '/',
                            temp_boot_root_directory)
            data.sync_data(options=['-a'])
            boot_directory = temp_boot_root_directory + '/boot'
            Path.wipe(boot_directory)
            if mbrid:
                log.info('--> Importing mbrid: %s', mbrid.get_id())
                Path.create(boot_directory)
                image_identifier = boot_directory + '/mbrid'
                mbrid.write(image_identifier)

            cpio = ArchiveCpio(
                os.sep.join([self.target_dir, kiwi_initrd_basename]))
            # the following is a list of directories which were needed
            # during the process of creating an image but not when the
            # image is actually booting with this initrd
            exclude_from_archive = [
                '/' + Defaults.get_shared_cache_location(), '/image',
                '/usr/lib/grub*'
            ]
            # the following is a list of directories to exclude which
            # are not needed inside of the initrd
            exclude_from_archive += [
                '/usr/share/doc', '/usr/share/man', '/home', '/media', '/srv'
            ]
            cpio.create(source_dir=temp_boot_root_directory,
                        exclude=exclude_from_archive)
            log.info('--> xz compressing archive')
            compress = Compress(
                os.sep.join([self.target_dir, kiwi_initrd_basename]))
            compress.xz(['--check=crc32', '--lzma2=dict=1MiB', '--threads=0'])
            self.initrd_filename = compress.compressed_filename
Esempio n. 9
0
 def link_database_to_host_path(self):
     """
     Create a link from host database location to image database
     location. The link is only created if both locations differ
     and if the host database location does not exist.
     """
     rpm_host_dbpath = self.rpmdb_host.expand_query('%_dbpath')
     rpm_image_dbpath = self.rpmdb_image.expand_query('%_dbpath')
     if rpm_host_dbpath != rpm_image_dbpath:
         root_rpm_host_dbpath = os.path.normpath(
             os.sep.join([self.root_dir, rpm_host_dbpath])
         )
         if not os.path.exists(root_rpm_host_dbpath):
             Path.create(os.path.dirname(root_rpm_host_dbpath))
             host_to_root = ''.join(
                 '../' for i in os.path.dirname(
                     rpm_host_dbpath
                 ).lstrip(os.sep).split(os.sep)
             )
             Command.run(
                 [
                     'ln', '-s', os.path.normpath(
                         os.sep.join([host_to_root, rpm_image_dbpath])
                     ), root_rpm_host_dbpath
                 ]
             )
Esempio n. 10
0
    def post_init(self, custom_args=None):
        """
        Post initialization method

        Store custom pacman arguments and create runtime configuration
        and environment

        :param list custom_args: pacman arguments
        """
        self.custom_args = custom_args
        self.check_signatures = False
        self.repo_names = []
        if not custom_args:
            self.custom_args = []

        self.runtime_pacman_config_file = NamedTemporaryFile(dir=self.root_dir)

        if 'check_signatures' in self.custom_args:
            self.custom_args.remove('check_signatures')
            self.check_signatures = True

        manager_base = self.shared_location + '/pacman'

        self.shared_pacman_dir = {
            'cache-dir': manager_base + '/cache',
            'repos-dir': manager_base + '/repos'
        }
        Path.create(self.shared_pacman_dir['repos-dir'])

        self.pacman_args = [
            '--config', self.runtime_pacman_config_file.name, '--noconfirm'
        ]

        self._write_runtime_config()
Esempio n. 11
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.machine and self.machine.get_domain() == 'dom0':
         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
             )
     self.boot_image_task.create_initrd(self.mbrid)
     Command.run(
         [
             'mv', self.boot_image_task.initrd_filename,
             boot_path + '/initrd'
         ]
     )
Esempio n. 12
0
    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
        )
Esempio n. 13
0
    def sync_data(self):
        """
        Synchronize data from the given base image to the target root
        directory.
        """
        if not self.unknown_uri:
            compressor = Compress(self.image_file)
            if compressor.get_format():
                compressor.uncompress(True)
                self.uncompressed_image = compressor.uncompressed_filename
            else:
                self.uncompressed_image = self.image_file
            image_uri = '{0}:{1}'.format(
                self.archive_transport, self.uncompressed_image
            )
        else:
            log.warning('Bypassing base image URI to OCI tools')
            image_uri = self.unknown_uri

        oci = OCI.new()
        oci.import_container_image(image_uri)
        oci.unpack()
        oci.import_rootfs(self.root_dir)

        # 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))
        oci.export_container_image(
            image_copy, 'oci-archive', Defaults.get_container_base_image_tag()
        )
        self._make_checksum(image_copy)
Esempio n. 14
0
    def setup_install_boot_images(self, mbrid, lookup_path=None):
        """
        Create/Provide grub2 boot images and metadata

        In order to boot from the ISO grub2 modules, images and theme
        data needs to be created and provided at the correct place on
        the iso filesystem

        :param string mbrid: mbrid file name on boot device
        :param string lookup_path: custom module lookup path
        """
        log.info('Creating grub2 bootloader images')
        self.efi_boot_path = self.create_efi_path(in_sub_dir='')

        log.info('--> Creating identifier file %s', mbrid.get_id())
        Path.create(self._get_grub2_boot_path())
        mbrid.write(self.boot_dir + '/boot/' + mbrid.get_id())
        mbrid.write(self.boot_dir + '/boot/mbrid')

        self._copy_theme_data_to_boot_directory(lookup_path, 'iso')

        if self._supports_bios_modules():
            self._copy_bios_modules_to_boot_directory(lookup_path)
            self._setup_bios_image(mbrid=mbrid, lookup_path=lookup_path)

        if self.firmware.efi_mode():
            self._setup_EFI_path(lookup_path)

        if self.firmware.efi_mode() == 'efi':
            self._setup_efi_image(mbrid=mbrid, lookup_path=lookup_path)
            self._copy_efi_modules_to_boot_directory(lookup_path)
        elif self.firmware.efi_mode() == 'uefi':
            self._copy_efi_modules_to_boot_directory(lookup_path)
            self._setup_secure_boot_efi_image(lookup_path)
Esempio n. 15
0
    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
Esempio n. 16
0
    def write(self):
        """
        Write zipl config file
        """
        log.info('Writing zipl config file')
        config_dir = self._get_zipl_boot_path()
        config_file = config_dir + '/config'
        if self.config:
            Path.create(config_dir)
            with open(config_file, 'w') as config:
                config.write(self.config)

            log.info('Moving initrd/kernel to zipl boot directory')
            Command.run(
                [
                    'mv',
                    os.sep.join(
                        [
                            self.boot_dir, 'boot',
                            os.readlink(self.boot_dir + '/boot/initrd')
                        ]
                    ),
                    os.sep.join(
                        [
                            self.boot_dir, 'boot',
                            os.readlink(self.boot_dir + '/boot/image')
                        ]
                    ),
                    self._get_zipl_boot_path()
                ]
            )
Esempio n. 17
0
    def commit(self) -> None:
        """
        Update instance directory with contents of registered files

        Use an atomic operation that prepares a tmp directory with
        all registered files and move it to the directory given at
        instance creation time. Please note the operation is not
        fully atomic as it uses two move commands in a series
        """
        Path.create(self.dirname_tmp)
        bash_command = [
            'cp', '-a', f'{self.dirname}/*', self.dirname_tmp
        ]
        Command.run(
            ['bash', '-c', ' '.join(bash_command)], raise_on_error=False
        )
        for origin, tmpname in list(self.collection.items()):
            Command.run(
                ['mv', tmpname, os.sep.join([self.dirname_tmp, origin])]
            )
        Command.run(
            ['mv', self.dirname, self.dirname_wipe]
        )
        Command.run(
            ['mv', self.dirname_tmp, self.dirname]
        )
        Command.run(
            ['rm', '-rf', self.dirname_wipe]
        )
Esempio n. 18
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))
            )
Esempio n. 19
0
    def create(self, filename, base_image):
        """
        Create compressed oci system container tar archive

        :param string filename: archive file name
        :param string base_image: archive used as a base image
        """
        exclude_list = Defaults.get_exclude_list_for_root_data_sync()
        exclude_list.append('boot')
        exclude_list.append('dev')
        exclude_list.append('sys')
        exclude_list.append('proc')

        if base_image:
            Path.create(self.oci.container_dir)
            image_tar = ArchiveTar(base_image)
            image_tar.extract(self.oci.container_dir)

        self.oci.init_layout(bool(base_image))

        self.oci.unpack()
        self.oci.sync_rootfs(''.join([self.root_dir, os.sep]), exclude_list)
        self.oci.repack(self.oci_config)

        if 'additional_tags' in self.oci_config:
            for tag in self.oci_config['additional_tags']:
                self.oci.add_tag(tag)

        self.oci.set_config(self.oci_config, bool(base_image))

        self.oci.garbage_collect()

        return self.pack_image_to_file(filename)
Esempio n. 20
0
    def create(self) -> None:
        """
        Create new system root directory

        The method creates a temporary directory and initializes it
        for the purpose of building a system image from it. This
        includes the following setup:

        * create core system paths
        * create static core device nodes

        On success the contents of the temporary location are
        synced to the specified root_dir and the temporary location
        will be deleted. That way we never work on an incomplete
        initial setup

        :raises KiwiRootInitCreationError: if the init creation fails
            at some point
        """
        root = Temporary(prefix='kiwi_root.').new_dir()
        Path.create(self.root_dir)
        try:
            self._create_base_directories(root.name)
            self._create_base_links(root.name)
            data = DataSync(root.name + '/', self.root_dir)
            data.sync_data(options=['-a', '--ignore-existing'])
            if Defaults.is_buildservice_worker():
                copy(os.sep + Defaults.get_buildservice_env_name(),
                     self.root_dir)
        except Exception as e:
            self.delete()
            raise KiwiRootInitCreationError('%s: %s' %
                                            (type(e).__name__, format(e)))
Esempio n. 21
0
 def _create_iso_install_kernel_and_initrd(self) -> None:
     boot_path = self.media_dir.name + '/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.boot_image_task.include_module('kiwi-dump')
         self.boot_image_task.include_module('kiwi-dump-reboot')
         if self.root_filesystem_is_multipath is False:
             self.boot_image_task.omit_module('multipath')
         for mod in self.xml_state.get_installmedia_initrd_modules('add'):
             self.boot_image_task.include_module(mod)
         for mod in self.xml_state.get_installmedia_initrd_modules('omit'):
             self.boot_image_task.omit_module(mod)
         self.boot_image_task.set_static_modules(
             self.xml_state.get_installmedia_initrd_modules('set'))
         self._add_system_image_boot_options_to_boot_image()
     self.boot_image_task.create_initrd(self.mbrid,
                                        'initrd_kiwi_install',
                                        install_initrd=True)
     Command.run([
         'mv', self.boot_image_task.initrd_filename, boot_path + '/initrd'
     ])
Esempio n. 22
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'
         ]
     )
Esempio n. 23
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',
                                        install_initrd=True)
     Command.run([
         'mv', self.boot_image_task.initrd_filename, boot_path + '/initrd'
     ])
Esempio n. 24
0
    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
Esempio n. 25
0
    def _copy_theme_data_to_boot_directory(self, lookup_path, target):
        if not lookup_path:
            lookup_path = self.boot_dir
        font_name = 'unicode.pf2'
        efi_font_dir = Defaults.get_grub_efi_font_directory(lookup_path)
        boot_fonts_dir = os.path.normpath(
            os.sep.join([
                self.boot_dir,
                self.get_boot_path(target), self.boot_directory_name, 'fonts'
            ]))
        try:
            unicode_font = Defaults.get_grub_path(lookup_path, font_name)
            if not os.path.exists(os.sep.join([boot_fonts_dir, font_name])):
                Path.create(boot_fonts_dir)
                Command.run(['cp', unicode_font, boot_fonts_dir])
            if efi_font_dir:
                Command.run(['cp', unicode_font, efi_font_dir])
        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()
Esempio n. 26
0
File: iso.py Progetto: hwoarang/kiwi
    def setup_isolinux_boot_path(self):
        """
        Write the base boot path into the isolinux loader binary

        :raises KiwiIsoLoaderError: if loader/isolinux.bin is not found
        """
        loader_base_directory = self.boot_path + '/loader'
        loader_file = '/'.join(
            [self.source_dir, self.boot_path, 'loader/isolinux.bin'])
        if not os.path.exists(loader_file):
            raise KiwiIsoLoaderError(
                'No isolinux loader %s found'.format(loader_file))
        try:
            Command.run([
                'isolinux-config', '--base', loader_base_directory, loader_file
            ])
        except Exception:
            # Setup of the base directory failed. This happens if
            # isolinux-config was not able to identify the isolinux
            # signature. As a workaround a compat directory /isolinux
            # is created which hardlinks all loader files
            compat_base_directory = self.source_dir + '/isolinux'
            loader_files = '/'.join(
                [self.source_dir, self.boot_path, 'loader/*'])
            Path.create(compat_base_directory)
            bash_command = ' '.join(
                ['ln', loader_files, compat_base_directory])
            Command.run(['bash', '-c', bash_command])
Esempio n. 27
0
 def _copy_loader_data_to_boot_directory(self, lookup_path):
     if not lookup_path:
         lookup_path = self.root_dir
     loader_data = lookup_path + '/image/loader/'
     Path.create(self._get_iso_boot_path())
     data = DataSync(loader_data, self._get_iso_boot_path())
     data.sync_data(options=['-z', '-a'])
Esempio n. 28
0
    def write(self):
        """
        Write grub.cfg and etc/default/grub file
        """
        config_dir = self._get_grub2_boot_path()
        config_file = config_dir + '/grub.cfg'
        if self.config:
            log.info('Writing grub.cfg file')
            Path.create(config_dir)
            with open(config_file, 'w') as config:
                config.write(self.config)

            if self.firmware.efi_mode():
                if self.iso_boot or self.shim_fallback_setup:
                    efi_vendor_boot_path = Defaults.get_shim_vendor_directory(
                        self.root_dir)
                    if efi_vendor_boot_path:
                        grub_config_file_for_efi_boot = os.sep.join(
                            [efi_vendor_boot_path, 'grub.cfg'])
                    else:
                        grub_config_file_for_efi_boot = os.path.normpath(
                            os.sep.join([self.efi_boot_path, 'grub.cfg']))
                    log.info(
                        'Writing {0} file to be found by EFI firmware'.format(
                            grub_config_file_for_efi_boot))
                    with open(grub_config_file_for_efi_boot, 'w') as config:
                        config.write(self.config)

                if self.iso_boot:
                    self._create_embedded_fat_efi_image()

            self._setup_default_grub()
            self.setup_sysconfig_bootloader()
Esempio n. 29
0
    def process_install_requests(self) -> command_call_type:
        """
        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', '--download', 'in-advance',
                '--auto-agree-with-licenses'
            ] + self.custom_args + ['--'] + self._install_items(),
            self.chroot_command_env)
Esempio n. 30
0
    def setup_package_database_configuration(self) -> None:
        """
        Setup rpm macros for bootstrapping and image building

        1. Create the rpm image macro which persists during the build
        2. Create the rpm bootstrap macro to make sure for bootstrapping
           the rpm database location matches the host rpm database setup.
           This macro only persists during the bootstrap phase. If the
           image was already bootstrapped a compat link is created instead.
        3. Create zypper compat link
        """
        rpmdb = RpmDataBase(
            self.root_dir, Defaults.get_custom_rpm_image_macro_name()
        )
        if self.locale:
            rpmdb.set_macro_from_string(self.locale[0])
        rpmdb.write_config()

        rpmdb = RpmDataBase(self.root_dir)
        if rpmdb.has_rpm():
            rpmdb.link_database_to_host_path()
        else:
            rpmdb.set_database_to_host_path()
        # Zypper compat code:
        #
        # Manually adding the compat link /var/lib/rpm that points to the
        # rpmdb location as it is configured in the host rpm setup. The
        # host rpm setup is taken into account because import_trusted_keys
        # is called during the bootstrap phase where rpm (respectively zypper)
        # is called from the host
        #
        # Usually it is expected that the package manager reads the
        # signing keys from the rpm database setup provisioned by rpm
        # itself (macro level) but zypper doesn't take the rpm macro
        # setup into account and relies on a hard coded path which we
        # can only provide as a symlink.
        #
        # That symlink is usually created by the rpm package when it gets
        # installed. However at that early phase when we import the
        # signing keys no rpm is installed yet nor any symlink exists.
        # Thus we have to create it here and hope to get rid of it in the
        # future.
        #
        # For further details on the motivation in zypper please
        # refer to bsc#1112357
        rpmdb.init_database()
        image_rpm_compat_link = '/var/lib/rpm'
        host_rpm_dbpath = rpmdb.rpmdb_host.expand_query('%_dbpath')
        if host_rpm_dbpath != image_rpm_compat_link:
            Path.create(
                self.root_dir + os.path.dirname(image_rpm_compat_link)
            )
            Command.run(
                [
                    'ln', '-s', '--no-target-directory',
                    ''.join(['../..', host_rpm_dbpath]),
                    self.root_dir + image_rpm_compat_link
                ], raise_on_error=False
            )
Esempio n. 31
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
     )
Esempio n. 32
0
 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
Esempio n. 33
0
 def test_create(self, mock_command, mock_exists):
     mock_exists.return_value = False
     Path.create('foo')
     mock_command.assert_called_once_with(['mkdir', '-p', 'foo'])
     mock_exists.return_value = True
     mock_command.reset_mock()
     Path.create('foo')
     assert not mock_command.called
Esempio n. 34
0
 def _create_zypper_runtime_environment(self) -> Dict:
     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
     )
Esempio n. 35
0
 def __init__(self, device: str, mountpoint: str = ''):
     self.device = device
     if not mountpoint:
         self.mountpoint_tempdir = Temporary(
             prefix='kiwi_mount_manager.').new_dir()
         self.mountpoint = self.mountpoint_tempdir.name
     else:
         Path.create(mountpoint)
         self.mountpoint = mountpoint
Esempio n. 36
0
 def _create_embedded_fat_efi_image(self):
     Path.create(self.boot_dir + '/boot/' + self.arch)
     efi_fat_image = ''.join([self.boot_dir + '/boot/', self.arch, '/efi'])
     Command.run(['qemu-img', 'create', efi_fat_image, '15M'])
     Command.run(['mkdosfs', '-n', 'BOOT', efi_fat_image])
     Command.run([
         'mcopy', '-Do', '-s', '-i', efi_fat_image, self.boot_dir + '/EFI',
         '::'
     ])
Esempio n. 37
0
 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
Esempio n. 38
0
    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
                    )
Esempio n. 39
0
    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
Esempio n. 40
0
 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)
Esempio n. 41
0
    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()
Esempio n. 42
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'])
        )
Esempio n. 43
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)
Esempio n. 44
0
    def export_modprobe_setup(self, target_root_dir):
        """
        Export etc/modprobe.d to given root_dir

        :param string target_root_dir: path name
        """
        modprobe_config = self.root_dir + '/etc/modprobe.d'
        if os.path.exists(modprobe_config):
            log.info('Export modprobe configuration')
            Path.create(target_root_dir + '/etc')
            data = DataSync(
                modprobe_config, target_root_dir + '/etc/'
            )
            data.sync_data(
                options=['-z', '-a']
            )
Esempio n. 45
0
    def setup(self, name=None):
        """
        Setup btrfs volume management

        In case of btrfs a toplevel(@) subvolume is created and marked
        as default volume. If snapshots are activated via the custom_args
        the setup method also created the @/.snapshots/1/snapshot
        subvolumes. There is no concept of a volume manager name, thus
        the name argument is not used for btrfs

        :param string name: unused
        """
        self.setup_mountpoint()

        filesystem = FileSystem(
            name='btrfs',
            device_provider=MappedDevice(
                device=self.device, device_provider=self
            ),
            custom_args=self.custom_filesystem_args
        )
        filesystem.create_on_device(
            label=self.custom_args['root_label']
        )
        self.toplevel_mount = MountManager(
            device=self.device, mountpoint=self.mountpoint
        )
        self.toplevel_mount.mount(
            self.custom_filesystem_args['mount_options']
        )
        root_volume = self.mountpoint + '/@'
        Command.run(
            ['btrfs', 'subvolume', 'create', root_volume]
        )
        if self.custom_args['root_is_snapshot']:
            snapshot_volume = self.mountpoint + '/@/.snapshots'
            Command.run(
                ['btrfs', 'subvolume', 'create', snapshot_volume]
            )
            Path.create(snapshot_volume + '/1')
            snapshot = self.mountpoint + '/@/.snapshots/1/snapshot'
            Command.run(
                ['btrfs', 'subvolume', 'snapshot', root_volume, snapshot]
            )
            self._set_default_volume('@/.snapshots/1/snapshot')
        else:
            self._set_default_volume('@')
Esempio n. 46
0
 def _create_embedded_fat_efi_image(self):
     Path.create(self.root_dir + '/boot/' + self.arch)
     efi_fat_image = ''.join(
         [self.root_dir + '/boot/', self.arch, '/efi']
     )
     Command.run(
         ['qemu-img', 'create', efi_fat_image, '15M']
     )
     Command.run(
         ['mkdosfs', '-n', 'BOOT', efi_fat_image]
     )
     Command.run(
         [
             'mcopy', '-Do', '-s', '-i', efi_fat_image,
             self.root_dir + '/EFI', '::'
         ]
     )
Esempio n. 47
0
    def setup_install_boot_images(self, mbrid, lookup_path=None):
        """
        Create/Provide grub2 boot images and metadata

        In order to boot from the ISO grub2 modules, images and theme
        data needs to be created and provided at the correct place on
        the iso filesystem

        :param string mbrid: mbrid file name on boot device
        :param string lookup_path: custom module lookup path
        """
        log.info('Creating grub2 bootloader images')
        self.efi_boot_path = self.create_efi_path(in_sub_dir='')

        log.info('--> Creating identifier file %s', mbrid.get_id())
        Path.create(
            self._get_grub2_boot_path()
        )
        mbrid.write(
            self.root_dir + '/boot/' + mbrid.get_id()
        )
        mbrid.write(
            self.root_dir + '/boot/mbrid'
        )

        self._copy_theme_data_to_boot_directory(lookup_path)

        if self._supports_bios_modules():
            self._copy_bios_modules_to_boot_directory(lookup_path)

        if self.firmware.efi_mode():
            self._setup_EFI_path(lookup_path)

        if self.firmware.efi_mode() == 'efi':
            log.info('--> Creating unsigned efi image')
            self._create_efi_image(mbrid=mbrid, lookup_path=lookup_path)
            self._copy_efi_modules_to_boot_directory(lookup_path)
        elif self.firmware.efi_mode() == 'uefi':
            log.info('--> Setting up shim secure boot efi image')
            self._copy_efi_modules_to_boot_directory(lookup_path)
            self._setup_secure_boot_efi_image(lookup_path)
Esempio n. 48
0
    def _setup_live_iso_kernel_and_initrd(self):
        """
        Copy kernel and initrd from the root tree into the iso boot structure
        """
        boot_path = ''.join(
            [self.media_dir, '/boot/', self.arch, '/loader']
        )
        Path.create(boot_path)

        # Move kernel files to iso filesystem structure
        kernel = Kernel(self.boot_image.boot_root_directory)
        if kernel.get_kernel():
            kernel.copy_kernel(boot_path, '/linux')
        else:
            raise KiwiLiveBootImageError(
                'No kernel in boot image tree {0} found'.format(
                    self.boot_image.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 KiwiLiveBootImageError(
                    'No hypervisor in boot image tree {0} found'.format(
                        self.boot_image.boot_root_directory
                    )
                )

        # Move initrd to iso filesystem structure
        if os.path.exists(self.boot_image.initrd_filename):
            shutil.move(
                self.boot_image.initrd_filename, boot_path + '/initrd'
            )
        else:
            raise KiwiLiveBootImageError(
                'No boot image {0} in boot image tree {1} found'.format(
                    self.boot_image.initrd_filename,
                    self.boot_image.boot_root_directory
                )
            )
Esempio n. 49
0
    def write(self):
        """
        Write zipl config file
        """
        log.info('Writing zipl config file')
        config_dir = self._get_zipl_boot_path()
        config_file = config_dir + '/config'
        if self.config:
            Path.create(config_dir)
            with open(config_file, 'w') as config:
                config.write(self.config)

            log.info('Moving initrd/kernel to zipl boot directory')
            Command.run(
                [
                    'mv',
                    self.root_dir + '/boot/initrd.vmx',
                    self.root_dir + '/boot/linux.vmx',
                    self._get_zipl_boot_path()
                ]
            )
Esempio n. 50
0
    def create(self):
        """
        Create new system root directory

        The method creates a temporary directory and initializes it
        for the purpose of building a system image from it. This
        includes the following setup:

        * create static core device nodes
        * create core system paths

        On success the contents of the temporary location are
        synced to the specified root_dir and the temporary location
        will be deleted. That way we never work on an incomplete
        initial setup

        :raises KiwiRootInitCreationError: if the init creation fails
            at some point
        """
        root = mkdtemp(prefix='kiwi_root.')
        Path.create(self.root_dir)
        try:
            self._create_base_directories(root)
            self._create_base_links(root)
            self._setup_config_templates(root)
            data = DataSync(root + '/', self.root_dir)
            data.sync_data(
                options=['-a', '--ignore-existing']
            )
            if Defaults.is_buildservice_worker():
                copy(
                    os.sep + Defaults.get_buildservice_env_name(),
                    self.root_dir)
        except Exception as e:
            self.delete()
            raise KiwiRootInitCreationError(
                '%s: %s' % (type(e).__name__, format(e))
            )
        finally:
            rmtree(root, ignore_errors=True)
Esempio n. 51
0
    def write(self):
        """
        Write grub.cfg and etc/default/grub file
        """
        config_dir = self._get_grub2_boot_path()
        config_file = config_dir + '/grub.cfg'
        if self.config:
            log.info('Writing grub.cfg file')
            Path.create(config_dir)
            with open(config_file, 'w') as config:
                config.write(self.config)

            if self.firmware.efi_mode():
                if self.iso_boot or self.shim_fallback_setup:
                    efi_vendor_boot_path = Defaults.get_shim_vendor_directory(
                        self.root_dir
                    )
                    if efi_vendor_boot_path:
                        grub_config_file_for_efi_boot = os.sep.join(
                            [efi_vendor_boot_path, 'grub.cfg']
                        )
                    else:
                        grub_config_file_for_efi_boot = os.path.normpath(
                            os.sep.join([self.efi_boot_path, 'grub.cfg'])
                        )
                    log.info(
                        'Writing {0} file to be found by EFI firmware'.format(
                            grub_config_file_for_efi_boot
                        )
                    )
                    with open(grub_config_file_for_efi_boot, 'w') as config:
                        config.write(self.config)

                if self.iso_boot:
                    self._create_embedded_fat_efi_image()

            self._setup_default_grub()
            self.setup_sysconfig_bootloader()
Esempio n. 52
0
    def create_repository_solvable(
        self, target_dir=Defaults.get_solvable_location()
    ):
        """
        Create SAT solvable for this repository from previously
        created intermediate solvables by merge and store the
        result solvable in the specified target_dir

        :param string target_dir: path name

        :return: file path to solvable
        :rtype: string
        """
        Path.create(target_dir)
        solvable = os.sep.join(
            [target_dir, self.uri.alias()]
        )
        if not self.is_uptodate(target_dir):
            self._setup_repository_metadata()
            solvable = self._merge_solvables(target_dir)
            self._cleanup()

        return solvable
Esempio n. 53
0
    def setup_isolinux_boot_path(self):
        """
        Write the base boot path into the isolinux loader binary

        :raises KiwiIsoLoaderError: if loader/isolinux.bin is not found
        """
        loader_base_directory = self.boot_path + '/loader'
        loader_file = '/'.join(
            [self.source_dir, self.boot_path, 'loader/isolinux.bin']
        )
        if not os.path.exists(loader_file):
            raise KiwiIsoLoaderError(
                'No isolinux loader %s found'.format(loader_file)
            )
        try:
            Command.run(
                [
                    'isolinux-config', '--base', loader_base_directory,
                    loader_file
                ]
            )
        except Exception:
            # Setup of the base directory failed. This happens if
            # isolinux-config was not able to identify the isolinux
            # signature. As a workaround a compat directory /isolinux
            # is created which hardlinks all loader files
            compat_base_directory = self.source_dir + '/isolinux'
            loader_files = '/'.join(
                [self.source_dir, self.boot_path, 'loader/*']
            )
            Path.create(compat_base_directory)
            bash_command = ' '.join(
                ['ln', loader_files, compat_base_directory]
            )
            Command.run(
                ['bash', '-c', bash_command]
            )
Esempio n. 54
0
 def _create_apt_get_runtime_environment(self):
     for apt_get_dir in list(self.shared_apt_get_dir.values()):
         Path.create(apt_get_dir)
     return dict(
         os.environ, LANG='C', DEBIAN_FRONTEND='noninteractive'
     )
Esempio n. 55
0
 def delete_all_repos(self):
     """
     Delete all apt-get repositories
     """
     Path.wipe(self.shared_apt_get_dir['sources-dir'])
     Path.create(self.shared_apt_get_dir['sources-dir'])
Esempio n. 56
0
 def delete_all_repos(self):
     """
     Delete all yum repositories
     """
     Path.wipe(self.shared_yum_dir['reposd-dir'])
     Path.create(self.shared_yum_dir['reposd-dir'])
Esempio n. 57
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())
Esempio n. 58
0
    def _copy_theme_data_to_boot_directory(self, lookup_path):
        if not lookup_path:
            lookup_path = self.root_dir
        boot_unicode_font = self.root_dir + '/boot/unicode.pf2'
        if not os.path.exists(boot_unicode_font):
            unicode_font = self._find_grub_data(lookup_path + '/usr/share') + \
                '/unicode.pf2'
            try:
                Command.run(
                    ['cp', unicode_font, boot_unicode_font]
                )
            except Exception:
                raise KiwiBootLoaderGrubFontError(
                    'Unicode font %s not found' % unicode_font
                )

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

        if self.theme:
            theme_dir = self._find_grub_data(lookup_path + '/usr/share') + \
                '/themes/' + self.theme
            boot_theme_background_file = self._find_theme_background_file(
                lookup_path
            )
            if 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.root_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=['-z', '-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=['-z', '-a']
                )

        self._check_boot_theme_exists()
Esempio n. 59
0
 def _create_yum_runtime_environment(self):
     for yum_dir in list(self.shared_yum_dir.values()):
         Path.create(yum_dir)
     return dict(
         os.environ, LANG='C'
     )
Esempio n. 60
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'])