Example #1
0
    def create(self, name, mbsize, type_name, flags=None):
        """
        Create DASD partition

        :param string name: partition name
        :param int mbsize: partition size
        :param string type_name: unused
        :param list flags: unused
        """
        self.partition_id += 1
        fdasd_input = NamedTemporaryFile()
        with open(fdasd_input.name, 'w') as partition:
            log.debug('%s: fdasd: n p cur_position +%sM w q', name,
                      format(mbsize))
            if mbsize == 'all_free':
                partition.write('n\np\n\n\nw\nq\n')
            else:
                partition.write('n\np\n\n+%dM\nw\nq\n' % mbsize)
        bash_command = ' '.join(
            ['cat', fdasd_input.name, '|', 'fdasd', '-f', self.disk_device])
        try:
            Command.run(['bash', '-c', bash_command])
        except Exception:
            # unfortunately fdasd reports that it can't read in the partition
            # table which I consider a bug in fdasd. However the table was
            # correctly created and therefore we continue. Problem is that we
            # are not able to detect real errors with the fdasd operation at
            # that point.
            log.debug('potential fdasd errors were ignored')
Example #2
0
    def create(self, name, mbsize, type_name, flags=None):
        """
        Create DASD partition

        :param string name: partition name
        :param int mbsize: partition size
        :param string type_name: unused
        :param list flags: unused
        """
        self.partition_id += 1
        fdasd_input = NamedTemporaryFile()
        with open(fdasd_input.name, 'w') as partition:
            log.debug(
                '%s: fdasd: n p cur_position +%sM w q',
                name, format(mbsize)
            )
            if mbsize == 'all_free':
                partition.write('n\np\n\n\nw\nq\n')
            else:
                partition.write('n\np\n\n+%dM\nw\nq\n' % mbsize)
        bash_command = ' '.join(
            ['cat', fdasd_input.name, '|', 'fdasd', '-f', self.disk_device]
        )
        try:
            Command.run(
                ['bash', '-c', bash_command]
            )
        except Exception:
            # unfortunately fdasd reports that it can't read in the partition
            # table which I consider a bug in fdasd. However the table was
            # correctly created and therefore we continue. Problem is that we
            # are not able to detect real errors with the fdasd operation at
            # that point.
            log.debug('potential fdasd errors were ignored')
Example #3
0
    def fix_boot_catalog(cls, isofile):
        """
        Fixup inconsistencies in boot catalog

        Make sure all catalog entries are in correct order and provide
        complete metadata information e.g catalog name

        :param str isofile: path to the ISO file
        """
        iso_metadata = Iso._read_iso_metadata(isofile)
        Iso._validate_iso_metadata(iso_metadata)
        boot_catalog = iso_metadata.boot_catalog
        first_catalog_entry = Iso._sub_string(
            data=boot_catalog, length=32, start=32
        )
        first_catalog_entry = Iso._embed_string_in_segment(
            data=first_catalog_entry,
            string=struct.pack('B19s', 1, bytes(b'Legacy (isolinux)')),
            length=20,
            start=12
        )
        boot_catalog = Iso._embed_string_in_segment(
            data=boot_catalog,
            string=first_catalog_entry,
            length=32,
            start=32
        )
        second_catalog_entry = Iso._sub_string(
            data=boot_catalog, length=32, start=64
        )
        second_catalog_entry = Iso._embed_string_in_segment(
            data=second_catalog_entry,
            string=struct.pack('B19s', 1, bytes(b'UEFI (grub)')),
            length=20,
            start=12
        )
        second_catalog_entry_sector = second_catalog_entry[0]
        if second_catalog_entry_sector == 0x88:
            boot_catalog = Iso._embed_string_in_segment(
                data=boot_catalog,
                string=second_catalog_entry,
                length=32,
                start=96
            )
            second_catalog_entry = struct.pack(
                'BBH28s', 0x91, 0xef, 1, bytes(b'')
            )
            boot_catalog = Iso._embed_string_in_segment(
                data=boot_catalog,
                string=second_catalog_entry,
                length=32,
                start=64
            )
            with open(isofile, 'rb+') as iso:
                Iso._write_iso_sector(
                    iso_metadata.boot_catalog_sector, boot_catalog, iso
                )
            log.debug('Fixed iso catalog contents')
Example #4
0
    def fix_boot_catalog(self, isofile):
        """
        Fixup inconsistencies in boot catalog

        Make sure all catalog entries are in correct order and provide
        complete metadata information e.g catalog name

        :param str isofile: path to the ISO file
        """
        iso_metadata = Iso._read_iso_metadata(isofile)
        Iso._validate_iso_metadata(iso_metadata)
        boot_catalog = iso_metadata.boot_catalog
        first_catalog_entry = Iso._sub_string(
            data=boot_catalog, length=32, start=32
        )
        first_catalog_entry = Iso._embed_string_in_segment(
            data=first_catalog_entry,
            string=struct.pack('B19s', 1, bytes(b'Legacy (isolinux)')),
            length=20,
            start=12
        )
        boot_catalog = Iso._embed_string_in_segment(
            data=boot_catalog,
            string=first_catalog_entry,
            length=32,
            start=32
        )
        second_catalog_entry = Iso._sub_string(
            data=boot_catalog, length=32, start=64
        )
        second_catalog_entry = Iso._embed_string_in_segment(
            data=second_catalog_entry,
            string=struct.pack('B19s', 1, bytes(b'UEFI (grub)')),
            length=20,
            start=12
        )
        second_catalog_entry_sector = second_catalog_entry[0]
        if second_catalog_entry_sector == 0x88:
            boot_catalog = Iso._embed_string_in_segment(
                data=boot_catalog,
                string=second_catalog_entry,
                length=32,
                start=96
            )
            second_catalog_entry = struct.pack(
                'BBH28s', 0x91, 0xef, 1, bytes(b'')
            )
            boot_catalog = Iso._embed_string_in_segment(
                data=boot_catalog,
                string=second_catalog_entry,
                length=32,
                start=64
            )
            with open(isofile, 'rb+') as iso:
                Iso._write_iso_sector(
                    iso_metadata.boot_catalog_sector, boot_catalog, iso
                )
            log.debug('Fixed iso catalog contents')
Example #5
0
    def relocate_boot_catalog(self, isofile):
        """
        Move ISO boot catalog to the standardized place

        Check location of the boot catalog and move it to the place where
        all BIOS and firwmare implementations expects it

        :param str isofile: path to the ISO file
        """
        iso_metadata = Iso._read_iso_metadata(isofile)
        Iso._validate_iso_metadata(iso_metadata)
        with open(isofile, 'rb+') as iso:
            new_boot_catalog_sector = iso_metadata.path_table_sector - 1
            new_volume_descriptor = Iso._read_iso_sector(
                new_boot_catalog_sector - 1, iso
            )
            new_volume_id = Iso._sub_string(
                data=new_volume_descriptor, length=7
            )
            if bytes(b'CD001') not in new_volume_id:
                new_boot_catalog_sector = None
                ref_sector = iso_metadata.boot_catalog_sector
                for sector in range(0x12, 0x40):
                    new_volume_descriptor = Iso._read_iso_sector(sector, iso)
                    new_volume_id = Iso._sub_string(
                        data=new_volume_descriptor, length=7
                    )
                    if (bytes(b'TEA01') in new_volume_id or
                            sector + 1 == ref_sector):
                        new_boot_catalog_sector = sector + 1
                        break

            if (
                new_boot_catalog_sector and
                iso_metadata.boot_catalog_sector != new_boot_catalog_sector
            ):
                new_boot_catalog = Iso._read_iso_sector(
                    new_boot_catalog_sector, iso
                )
                empty_catalog = bytes(b'\x00') * 0x800
                if new_boot_catalog == empty_catalog:
                    eltorito_descriptor = Iso._embed_string_in_segment(
                        data=iso_metadata.eltorito_descriptor,
                        string=struct.pack('<I', new_boot_catalog_sector),
                        length=4,
                        start=0x47
                    )
                    Iso._write_iso_sector(
                        new_boot_catalog_sector, iso_metadata.boot_catalog, iso
                    )
                    Iso._write_iso_sector(
                        0x11, eltorito_descriptor, iso
                    )
                    log.debug(
                        'Relocated boot catalog from sector 0x%x to 0x%x',
                        iso_metadata.boot_catalog_sector,
                        new_boot_catalog_sector
                    )
Example #6
0
    def relocate_boot_catalog(cls, isofile):
        """
        Move ISO boot catalog to the standardized place

        Check location of the boot catalog and move it to the place where
        all BIOS and firwmare implementations expects it

        :param str isofile: path to the ISO file
        """
        iso_metadata = Iso._read_iso_metadata(isofile)
        Iso._validate_iso_metadata(iso_metadata)
        with open(isofile, 'rb+') as iso:
            new_boot_catalog_sector = iso_metadata.path_table_sector - 1
            new_volume_descriptor = Iso._read_iso_sector(
                new_boot_catalog_sector - 1, iso
            )
            new_volume_id = Iso._sub_string(
                data=new_volume_descriptor, length=7
            )
            if bytes(b'CD001') not in new_volume_id:
                new_boot_catalog_sector = None
                ref_sector = iso_metadata.boot_catalog_sector
                for sector in range(0x12, 0x40):
                    new_volume_descriptor = Iso._read_iso_sector(sector, iso)
                    new_volume_id = Iso._sub_string(
                        data=new_volume_descriptor, length=7
                    )
                    if bytes(b'TEA01') in new_volume_id or \
                       sector + 1 == ref_sector:

                        new_boot_catalog_sector = sector + 1
                        break

            if new_boot_catalog_sector and \
               iso_metadata.boot_catalog_sector != new_boot_catalog_sector:

                new_boot_catalog = Iso._read_iso_sector(
                    new_boot_catalog_sector, iso
                )
                empty_catalog = bytes(b'\x00') * 0x800
                if new_boot_catalog == empty_catalog:
                    eltorito_descriptor = Iso._embed_string_in_segment(
                        data=iso_metadata.eltorito_descriptor,
                        string=struct.pack('<I', new_boot_catalog_sector),
                        length=4,
                        start=0x47
                    )
                    Iso._write_iso_sector(
                        new_boot_catalog_sector, iso_metadata.boot_catalog, iso
                    )
                    Iso._write_iso_sector(
                        0x11, eltorito_descriptor, iso
                    )
                    log.debug(
                        'Relocated boot catalog from sector 0x%x to 0x%x',
                        iso_metadata.boot_catalog_sector,
                        new_boot_catalog_sector
                    )
Example #7
0
    def setup_media_loader_directory(lookup_path, media_path, boot_theme):
        loader_data = lookup_path + '/image/loader/'
        media_boot_path = os.sep.join(
            [media_path, Defaults.get_iso_boot_path(), 'loader'])
        Path.wipe(loader_data)
        Path.create(loader_data)
        grub_image_file_names = [
            Defaults.get_isolinux_bios_grub_loader(), 'boot_hybrid.img'
        ]
        loader_files = []
        for grub_image_file_name in grub_image_file_names:
            grub_file = Defaults.get_grub_path(
                lookup_path,
                'i386-pc/{0}'.format(grub_image_file_name),
                raise_on_error=False)
            if grub_file and os.path.exists(grub_file):
                loader_files.append(grub_file)

        for syslinux_file_name in Defaults.get_syslinux_modules():
            for syslinux_dir in Defaults.get_syslinux_search_paths():
                syslinux_file = os.path.normpath(
                    os.sep.join(
                        [lookup_path, syslinux_dir, syslinux_file_name]))
                if os.path.exists(syslinux_file):
                    loader_files.append(syslinux_file)

        log.debug('Copying loader files to {0}'.format(loader_data))
        for loader_file in loader_files:
            log.debug('--> Copying {0}'.format(loader_file))
            shutil.copy(loader_file, loader_data)

        bash_command = ' '.join(
            ['cp', lookup_path + '/boot/memtest*', loader_data + '/memtest'])
        Command.run(command=['bash', '-c', bash_command], raise_on_error=False)

        if boot_theme:
            theme_path = ''.join(
                [lookup_path, '/etc/bootsplash/themes/', boot_theme])
            if os.path.exists(theme_path + '/cdrom/gfxboot.cfg'):
                bash_command = ' '.join(
                    ['cp', theme_path + '/cdrom/*', loader_data])
                Command.run(['bash', '-c', bash_command])
                # don't move down one menu entry the first time a F-key is used
                Command.run([
                    'gfxboot', '--config-file', loader_data + '/gfxboot.cfg',
                    '--change-config', 'install::autodown=0'
                ])

            if os.path.exists(theme_path + '/bootloader/message'):
                Command.run(
                    ['cp', theme_path + '/bootloader/message', loader_data])

        Path.create(media_boot_path)
        data = DataSync(loader_data, media_boot_path)
        data.sync_data(options=['-z', '-a'])
Example #8
0
    def install(self):
        """
        Install bootloader on self.device
        """
        log.info('Installing zipl on disk %s', self.device)

        self.boot_mount.mount()

        bash_command = ' '.join([
            'cd', self.boot_mount.mountpoint, '&&', 'zipl', '-V', '-c',
            self.boot_mount.mountpoint + '/config', '-m', 'menu'
        ])
        zipl_call = Command.run(['bash', '-c', bash_command])
        log.debug('zipl install succeeds with: %s', zipl_call.output)
Example #9
0
    def create_initrd(self, mbrid=None, basename=None, install_initrd=False):
        """
        Call dracut as chroot operation to create the initrd and move
        the result into the image build target directory

        :param object mbrid: unused
        :param string basename: base initrd file name
        :param bool install_initrd: installation media initrd
        """
        if self.is_prepared():
            log.info('Creating generic dracut initrd archive')
            kernel_info = Kernel(self.boot_root_directory)
            kernel_details = kernel_info.get_kernel(raise_on_not_found=True)
            if basename:
                dracut_initrd_basename = basename
            else:
                dracut_initrd_basename = self.initrd_base_name
            if install_initrd:
                included_files = self.included_files_install
                modules_args = [
                    '--add', ' {0} '.format(' '.join(self.install_modules))
                ] if self.install_modules else []
                omit_modules_args = [
                    '--omit', ' {0} '.format(' '.join(
                        self.omit_install_modules))
                ] if self.omit_install_modules else []
            else:
                included_files = self.included_files
                modules_args = [
                    '--add', ' {0} '.format(' '.join(self.modules))
                ] if self.modules else []
                omit_modules_args = [
                    '--omit', ' {0} '.format(' '.join(self.omit_modules))
                ] if self.omit_modules else []
            dracut_initrd_basename += '.xz'
            options = self.dracut_options + modules_args +\
                omit_modules_args + included_files
            dracut_call = Command.run([
                'chroot', self.boot_root_directory, 'dracut', '--force',
                '--no-hostonly', '--no-hostonly-cmdline', '--xz'
            ] + options + [dracut_initrd_basename, kernel_details.version],
                                      stderr_to_stdout=True)
            log.debug(dracut_call.output)
            Command.run([
                'mv',
                os.sep.join([self.boot_root_directory,
                             dracut_initrd_basename]), self.target_dir
            ])
            self.initrd_filename = os.sep.join(
                [self.target_dir, dracut_initrd_basename])
Example #10
0
    def import_shell_environment(self, profile):
        """
        Create profile environment to let scripts consume
        information from the XML description.

        :param object profile: Instance of Profile
        """
        profile_file = self.root_dir + '/.profile'
        log.info('Creating .profile environment')
        profile_environment = profile.create()
        with open(profile_file, 'w') as profile:
            for line in profile_environment:
                profile.write(line + '\n')
                log.debug('--> %s', line)
Example #11
0
    def import_shell_environment(self, profile):
        """
        Create profile environment to let scripts consume
        information from the XML description.

        :param object profile: Instance of Profile
        """
        profile_file = self.root_dir + '/.profile'
        log.info('Creating .profile environment')
        profile_environment = profile.create()
        with open(profile_file, 'w') as profile:
            for line in profile_environment:
                profile.write(line + '\n')
                log.debug('--> %s', line)
Example #12
0
    def _install_bootloader(self, device_map):
        root_device = device_map['root']
        boot_device = root_device
        if 'boot' in device_map:
            boot_device = device_map['boot']

        if 'readonly' in device_map:
            root_device = device_map['readonly']

        custom_install_arguments = {
            'boot_device': boot_device.get_device(),
            'root_device': root_device.get_device(),
            'firmware': self.firmware,
            'target_removable': self.target_removable
        }

        if 'efi' in device_map:
            efi_device = device_map['efi']
            custom_install_arguments.update(
                {'efi_device': efi_device.get_device()}
            )

        if 'prep' in device_map:
            prep_device = device_map['prep']
            custom_install_arguments.update(
                {'prep_device': prep_device.get_device()}
            )

        if self.volume_manager_name:
            self.system.umount_volumes()
            custom_install_arguments.update(
                {'system_volumes': self.system.get_volumes()}
            )

        if self.bootloader is not 'custom':
            log.debug(
                "custom arguments for bootloader installation %s",
                custom_install_arguments
            )
            bootloader = BootLoaderInstall(
                self.bootloader, self.root_dir, self.disk.storage_provider,
                custom_install_arguments
            )
            if bootloader.install_required():
                bootloader.install()

        self.system_setup.call_edit_boot_install_script(
            self.diskname, boot_device.get_device()
        )
Example #13
0
    def _install_bootloader(self, device_map):
        root_device = device_map['root']
        boot_device = root_device
        if 'boot' in device_map:
            boot_device = device_map['boot']

        if 'readonly' in device_map:
            root_device = device_map['readonly']

        custom_install_arguments = {
            'boot_device': boot_device.get_device(),
            'root_device': root_device.get_device(),
            'firmware': self.firmware,
            'target_removable': self.target_removable
        }

        if 'efi' in device_map:
            efi_device = device_map['efi']
            custom_install_arguments.update(
                {'efi_device': efi_device.get_device()})

        if 'prep' in device_map:
            prep_device = device_map['prep']
            custom_install_arguments.update(
                {'prep_device': prep_device.get_device()})

        if self.volume_manager_name:
            self.system.umount_volumes()
            custom_install_arguments.update(
                {'system_volumes': self.system.get_volumes()})

        # create bootloader config prior bootloader installation
        self.bootloader_config.setup_disk_image_config(
            boot_options=custom_install_arguments)

        # cleanup bootloader config resources taken prior to next steps
        del self.bootloader_config

        if self.bootloader != 'custom':
            log.debug("custom arguments for bootloader installation %s",
                      custom_install_arguments)
            bootloader = BootLoaderInstall(self.bootloader, self.root_dir,
                                           self.disk.storage_provider,
                                           custom_install_arguments)
            if bootloader.install_required():
                bootloader.install()

        self.system_setup.call_edit_boot_install_script(
            self.diskname, boot_device.get_device())
Example #14
0
    def create(self, name, mbsize, type_name, flags=None):
        """
        Create msdos partition

        :param string name: partition name
        :param int mbsize: partition size
        :param string type_name: partition type
        :param list flags: additional flags
        """
        self.partition_id += 1
        fdisk_input = NamedTemporaryFile()
        if self.partition_id > 1:
            # Undefined start sector value skips this for fdisk and
            # use its default value
            self.start_sector = None
        with open(fdisk_input.name, 'w') as partition:
            log.debug(
                '%s: fdisk: n p %d cur_position +%sM w q',
                name, self.partition_id, format(mbsize)
            )
            partition.write(
                'n\np\n{0}\n{1}\n{2}\nw\nq\n'.format(
                    self.partition_id,
                    '' if not self.start_sector else self.start_sector,
                    '' if mbsize == 'all_free' else '+{0}M'.format(mbsize)
                )
            )
        bash_command = ' '.join(
            ['cat', fdisk_input.name, '|', 'fdisk', self.disk_device]
        )
        try:
            Command.run(
                ['bash', '-c', bash_command]
            )
        except Exception:
            # unfortunately fdisk reports that it can't read in the partition
            # table which I consider a bug in fdisk. However the table was
            # correctly created and therefore we continue. Problem is that we
            # are not able to detect real errors with the fdisk operation at
            # that point.
            log.debug('potential fdisk errors were ignored')

        self.set_flag(self.partition_id, type_name)
        if flags:
            for flag_name in flags:
                self.set_flag(self.partition_id, flag_name)
Example #15
0
    def get_format(self):
        """
        Detect compression format

        :return: compression format name or None if it couldn't be inferred

        :rtype: Optional[str]
        """
        for zipper in self.supported_zipper:
            cmd = [zipper, '-l', self.source_filename]
            try:
                Command.run(cmd)
                return zipper
            except Exception as exc:
                log.debug(
                    'Error running "{cmd:s}", got a {exc_t:s}: {exc:s}'.format(
                        cmd=' '.join(cmd),
                        exc_t=type(exc).__name__,
                        exc=str(exc)))
Example #16
0
    def install(self):
        """
        Install bootloader on self.device
        """
        log.info('Installing zipl on disk %s', self.device)

        self.boot_mount.mount()

        bash_command = ' '.join(
            [
                'cd', self.boot_mount.mountpoint, '&&',
                'zipl', '-V', '-c', self.boot_mount.mountpoint + '/config',
                '-m', 'menu'
            ]
        )
        zipl_call = Command.run(
            ['bash', '-c', bash_command]
        )
        log.debug('zipl install succeeds with: %s', zipl_call.output)
Example #17
0
 def set_hybrid_mbr(self):
     """
     Turn partition table into hybrid GPT/MBR table
     """
     partition_ids = []
     partition_number_to_embed = self.partition_id
     if partition_number_to_embed > 3:
         # the max number of partitions to embed is 3
         # for details see man sgdisk
         log.debug(
             'maximum number of GPT hybrid MBR partitions is 3, got %d',
             partition_number_to_embed)
         partition_number_to_embed = 3
         log.debug('reduced GPT hybrid MBR partition count to %d',
                   partition_number_to_embed)
     for number in range(1, partition_number_to_embed + 1):
         partition_ids.append(format(number))
     Command.run(
         ['sgdisk', '-h', ':'.join(partition_ids), self.disk_device])
Example #18
0
 def wipe(self):
     """
     Zap (destroy) any GPT and MBR data structures if present
     For DASD disks create a new VTOC table
     """
     if 'dasd' in self.table_type:
         log.debug('Initialize DASD disk with new VTOC table')
         fdasd_input = NamedTemporaryFile()
         with open(fdasd_input.name, 'w') as vtoc:
             vtoc.write('y\n\nw\nq\n')
         bash_command = ' '.join(
             [
                 'cat', fdasd_input.name, '|',
                 'fdasd', '-f', self.storage_provider.get_device()
             ]
         )
         try:
             Command.run(
                 ['bash', '-c', bash_command]
             )
         except Exception:
             # unfortunately fdasd reports that it can't read in the
             # partition table which I consider a bug in fdasd. However
             # the table was correctly created and therefore we continue.
             # Problem is that we are not able to detect real errors
             # with the fdasd operation at that point.
             log.debug('potential fdasd errors were ignored')
     else:
         log.debug('Initialize %s disk', self.table_type)
         Command.run(
             [
                 'sgdisk', '--zap-all', self.storage_provider.get_device()
             ]
         )
Example #19
0
 def wipe(self):
     """
     Zap (destroy) any GPT and MBR data structures if present
     For DASD disks create a new VTOC table
     """
     if 'dasd' in self.table_type:
         log.debug('Initialize DASD disk with new VTOC table')
         fdasd_input = NamedTemporaryFile()
         with open(fdasd_input.name, 'w') as vtoc:
             vtoc.write('y\n\nw\nq\n')
         bash_command = ' '.join([
             'cat', fdasd_input.name, '|', 'fdasd', '-f',
             self.storage_provider.get_device()
         ])
         try:
             Command.run(['bash', '-c', bash_command])
         except Exception:
             # unfortunately fdasd reports that it can't read in the
             # partition table which I consider a bug in fdasd. However
             # the table was correctly created and therefore we continue.
             # Problem is that we are not able to detect real errors
             # with the fdasd operation at that point.
             log.debug('potential fdasd errors were ignored')
     else:
         log.debug('Initialize %s disk', self.table_type)
         Command.run(
             ['sgdisk', '--zap-all',
              self.storage_provider.get_device()])
Example #20
0
    def _create_volume_no_zero(lvcreate_args):
        """
        Create an LV using specified arguments to lvcreate

        The LV will be created with the '-Zn' option prepended
        to the arguments, which disables the zeroing of the new
        device's header; this action will fail when running in
        an environment where udev is not enabled, such as in a
        chroot'd Open Build Service build. Since the backing
        device for a kiwi LVM device is a zero filled qemu-img
        created file, there should be no negative side effects
        to skipping the zeroing of this header block.

        Then we run 'vgscan --mknodes' to ensure that any /dev
        nodes have been created for the new LV.

        :param list lvcreate_args: list of lvcreate arguments.
        """
        log.debug('--> running "lvcreate -Zn %s"', " ".join(lvcreate_args))
        Command.run(['lvcreate', '-Zn'] + lvcreate_args)
        log.debug('--> running "vgscan --mknodes" to create missing nodes')
        Command.run(['vgscan', '--mknodes'])
Example #21
0
    def create(self, name, mbsize, type_name, flags=None):
        """
        Create msdos partition

        :param string name: partition name
        :param int mbsize: partition size
        :param string type_name: partition type
        :param list flags: additional flags
        """
        self.partition_id += 1
        fdisk_input = NamedTemporaryFile()
        if self.partition_id > 1:
            # Undefined start sector value skips this for fdisk and
            # use its default value
            self.start_sector = None
        with open(fdisk_input.name, 'w') as partition:
            log.debug('%s: fdisk: n p %d cur_position +%sM w q', name,
                      self.partition_id, format(mbsize))
            partition.write('n\np\n{0}\n{1}\n{2}\nw\nq\n'.format(
                self.partition_id,
                '' if not self.start_sector else self.start_sector,
                '' if mbsize == 'all_free' else '+{0}M'.format(mbsize)))
        bash_command = ' '.join(
            ['cat', fdisk_input.name, '|', 'fdisk', self.disk_device])
        try:
            Command.run(['bash', '-c', bash_command])
        except Exception:
            # unfortunately fdisk reports that it can't read in the partition
            # table which I consider a bug in fdisk. However the table was
            # correctly created and therefore we continue. Problem is that we
            # are not able to detect real errors with the fdisk operation at
            # that point.
            log.debug('potential fdisk errors were ignored')

        self.set_flag(self.partition_id, type_name)
        if flags:
            for flag_name in flags:
                self.set_flag(self.partition_id, flag_name)
Example #22
0
 def set_hybrid_mbr(self):
     """
     Turn partition table into hybrid GPT/MBR table
     """
     partition_ids = []
     partition_number_to_embed = self.partition_id
     if partition_number_to_embed > 3:
         # the max number of partitions to embed is 3
         # for details see man sgdisk
         log.debug(
             'maximum number of GPT hybrid MBR partitions is 3, got %d',
             partition_number_to_embed
         )
         partition_number_to_embed = 3
         log.debug(
             'reduced GPT hybrid MBR partition count to %d',
             partition_number_to_embed
         )
     for number in range(1, partition_number_to_embed + 1):
         partition_ids.append(format(number))
     Command.run(
         ['sgdisk', '-h', ':'.join(partition_ids), self.disk_device]
     )
Example #23
0
    def create_header_end_block(self, isofile):
        """
        Find offset address of file containing the header_id and
        replace it by a list of 2k blocks in range 0 - offset + 1
        This is the required preparation to support hybrid ISO
        images, meaning to let isohybrid work correctly

        :param string isofile: path to the ISO file

        :raises KiwiIsoLoaderError: if the header_id file is not found
        :return: 512 byte blocks offset address

        :rtype: int
        """
        file_count = 0
        offset = 0
        found_id = False
        iso_tool = IsoToolsCdrTools(self.source_dir)
        with open(isofile, 'rb') as iso:
            for start in iso_tool.list_iso(isofile):
                if file_count >= 8:  # check only the first 8 files
                    break
                file_count += 1
                read_buffer = ''
                for index in range(0, -9, -1):  # go back up to 8 blocks
                    offset = start + index
                    iso.seek(offset << 11, 0)
                    read_buffer = iso.read(len(self.header_id))
                    if read_buffer == self.header_id.encode():
                        iso.seek(0, 0)
                        file_count = 8
                        found_id = True
                        break

            if found_id:
                log.debug('Found ISO header_end id at offset:')
                log.debug('--> 2k blocks: %d', offset)
                log.debug('--> 512 byte blocks(isohybrid): %d', offset * 4)
                log.debug('--> bytes(loop mount): %d', offset * 2048)
                with open(self.header_end_file, 'wb') as marker:
                    for index in range(offset + 1):
                        marker.write(iso.read(2048))
            else:
                raise KiwiIsoLoaderError(
                    'Header ID not found in iso file %s' % isofile
                )
            return offset * 4
Example #24
0
    def create_header_end_block(self, isofile):
        """
        Find offset address of file containing the header_id and
        replace it by a list of 2k blocks in range 0 - offset + 1
        This is the required preparation to support hybrid ISO
        images, meaning to let isohybrid work correctly

        :param string isofile: path to the ISO file

        :raises KiwiIsoLoaderError: if the header_id file is not found
        :return: 512 byte blocks offset address

        :rtype: int
        """
        file_count = 0
        offset = 0
        found_id = False
        iso_tool = IsoToolsCdrTools(self.source_dir)
        with open(isofile, 'rb') as iso:
            for start in iso_tool.list_iso(isofile):
                if file_count >= 8:  # check only the first 8 files
                    break
                file_count += 1
                read_buffer = ''
                for index in range(0, -9, -1):  # go back up to 8 blocks
                    offset = start + index
                    iso.seek(offset << 11, 0)
                    read_buffer = iso.read(len(self.header_id))
                    if read_buffer == self.header_id.encode():
                        iso.seek(0, 0)
                        file_count = 8
                        found_id = True
                        break

            if found_id:
                log.debug('Found ISO header_end id at offset:')
                log.debug('--> 2k blocks: %d', offset)
                log.debug('--> 512 byte blocks(isohybrid): %d', offset * 4)
                log.debug('--> bytes(loop mount): %d', offset * 2048)
                with open(self.header_end_file, 'wb') as marker:
                    for index in range(offset + 1):
                        marker.write(iso.read(2048))
            else:
                raise KiwiIsoLoaderError(
                    'Header ID not found in iso file %s' % isofile
                )
            return offset * 4