Esempio n. 1
0
    def __init__(self, xml_state, target_dir, boot_image_task):
        self.target_dir = target_dir
        self.machine = xml_state.get_build_type_machine_section()
        self.boot_image_task = boot_image_task
        self.xml_state = xml_state
        self.diskname = "".join(
            [
                target_dir,
                "/",
                xml_state.xml_data.get_name(),
                "." + platform.machine(),
                "-" + xml_state.get_image_version(),
                ".raw",
            ]
        )
        self.isoname = "".join(
            [
                target_dir,
                "/",
                xml_state.xml_data.get_name(),
                "." + platform.machine(),
                "-" + xml_state.get_image_version(),
                ".install.iso",
            ]
        )
        self.pxename = "".join(
            [
                target_dir,
                "/",
                xml_state.xml_data.get_name(),
                "." + platform.machine(),
                "-" + xml_state.get_image_version(),
                ".install.tar.xz",
            ]
        )
        self.squashed_diskname = "".join([xml_state.xml_data.get_name(), ".raw"])
        self.md5name = "".join([xml_state.xml_data.get_name(), ".md5"])

        self.mbrid = ImageIdentifier()
        self.mbrid.calculate_id()

        self.media_dir = None
        self.pxe_dir = None
        self.squashed_contents = None
        self.custom_iso_args = None
Esempio n. 2
0
    def __init__(self, xml_state, target_dir, root_dir):
        self.media_dir = None
        self.arch = platform.machine()
        self.root_dir = root_dir
        self.target_dir = target_dir
        self.xml_state = xml_state
        self.live_type = xml_state.build_type.get_flags()
        self.types = Defaults.get_live_iso_types()
        self.hybrid = xml_state.build_type.get_hybrid()
        self.volume_id = xml_state.build_type.get_volid()
        self.machine = xml_state.get_build_type_machine_section()
        self.mbrid = ImageIdentifier()
        self.mbrid.calculate_id()

        if not self.live_type:
            self.live_type = Defaults.get_default_live_iso_type()

        self.boot_image_task = BootImageTask(
            'kiwi', xml_state, target_dir
        )
        self.firmware = FirmWare(
            xml_state
        )
        self.system_setup = SystemSetup(
            xml_state=xml_state, description_dir=None, root_dir=self.root_dir
        )
        self.isoname = ''.join(
            [
                target_dir, '/',
                xml_state.xml_data.get_name(),
                '.' + platform.machine(),
                '-' + xml_state.get_image_version(),
                '.iso'
            ]
        )
        self.live_image_file = ''.join(
            [
                target_dir, '/',
                xml_state.xml_data.get_name(),
                '-read-only.', self.arch, '-',
                xml_state.get_image_version()
            ]
        )
        self.result = Result()
Esempio n. 3
0
class InstallImageBuilder(object):
    """
        Installation image builder
    """

    def __init__(self, xml_state, target_dir, boot_image_task):
        self.target_dir = target_dir
        self.machine = xml_state.get_build_type_machine_section()
        self.boot_image_task = boot_image_task
        self.xml_state = xml_state
        self.diskname = "".join(
            [
                target_dir,
                "/",
                xml_state.xml_data.get_name(),
                "." + platform.machine(),
                "-" + xml_state.get_image_version(),
                ".raw",
            ]
        )
        self.isoname = "".join(
            [
                target_dir,
                "/",
                xml_state.xml_data.get_name(),
                "." + platform.machine(),
                "-" + xml_state.get_image_version(),
                ".install.iso",
            ]
        )
        self.pxename = "".join(
            [
                target_dir,
                "/",
                xml_state.xml_data.get_name(),
                "." + platform.machine(),
                "-" + xml_state.get_image_version(),
                ".install.tar.xz",
            ]
        )
        self.squashed_diskname = "".join([xml_state.xml_data.get_name(), ".raw"])
        self.md5name = "".join([xml_state.xml_data.get_name(), ".md5"])

        self.mbrid = ImageIdentifier()
        self.mbrid.calculate_id()

        self.media_dir = None
        self.pxe_dir = None
        self.squashed_contents = None
        self.custom_iso_args = None

    def create_install_iso(self):
        """
            Create an install ISO from the disk_image as hybrid ISO
            bootable via legacy BIOS, EFI and as disk from Stick
        """
        self.media_dir = mkdtemp(prefix="install-media.", dir=self.target_dir)
        # custom iso metadata
        self.custom_iso_args = ["-V", '"KIWI Installation System"', "-A", self.mbrid.get_id()]

        # the system image transfer is checked against a checksum
        log.info("Creating disk image checksum")
        self.squashed_contents = mkdtemp(prefix="install-squashfs.", dir=self.target_dir)
        checksum = Checksum(self.diskname)
        checksum.md5(self.squashed_contents + "/" + self.md5name)

        # the kiwi initrd code triggers the install by trigger files
        self.__create_iso_install_trigger_files()

        # the system image is stored as squashfs embedded file
        log.info("Creating squashfs embedded disk image")
        Command.run(["cp", "-l", self.diskname, self.squashed_contents + "/" + self.squashed_diskname])
        squashed_image_file = "".join([self.target_dir, "/", self.squashed_diskname, ".squashfs"])
        squashed_image = FileSystemSquashFs(device_provider=None, root_dir=self.squashed_contents)
        squashed_image.create_on_file(squashed_image_file)
        Command.run(["mv", squashed_image_file, self.media_dir])

        # setup bootloader config to boot the ISO via isolinux
        log.info("Setting up install image bootloader configuration")
        bootloader_config_isolinux = BootLoaderConfig("isolinux", self.xml_state, self.media_dir)
        bootloader_config_isolinux.setup_install_boot_images(
            mbrid=None, lookup_path=self.boot_image_task.boot_root_directory
        )
        bootloader_config_isolinux.setup_install_image_config(mbrid=None)
        bootloader_config_isolinux.write()

        # setup bootloader config to boot the ISO via EFI
        bootloader_config_grub = BootLoaderConfig("grub2", self.xml_state, self.media_dir)
        bootloader_config_grub.setup_install_boot_images(
            mbrid=self.mbrid, lookup_path=self.boot_image_task.boot_root_directory
        )
        bootloader_config_grub.setup_install_image_config(mbrid=self.mbrid)
        bootloader_config_grub.write()

        # create initrd for install image
        log.info("Creating install image boot image")
        self.__create_iso_install_kernel_and_initrd()

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

        # make it hybrid
        Iso.create_hybrid(iso_header_offset, self.mbrid, self.isoname)

    def create_install_pxe_archive(self):
        """
            Create an oem install tar archive suitable for installing a
            disk image via the network using the PXE boot protocol.
            The archive contains the raw disk image and its checksum
            as well as an install initrd and kernel plus the required
            kernel commandline information which needs to be added
            as append line in the pxelinux config file on the boot
            server
        """
        self.pxe_dir = mkdtemp(prefix="pxe-install-media.", dir=self.target_dir)
        # the system image is transfered as xz compressed variant
        log.info("xz compressing disk image")
        pxe_image_filename = "".join([self.pxe_dir, "/", self.xml_state.xml_data.get_name(), ".xz"])
        compress = Compress(source_filename=self.diskname, keep_source_on_compress=True)
        compress.xz()
        Command.run(["mv", compress.compressed_filename, pxe_image_filename])

        # the system image transfer is checked against a checksum
        log.info("Creating disk image checksum")
        pxe_md5_filename = "".join([self.pxe_dir, "/", self.xml_state.xml_data.get_name(), ".md5"])
        checksum = Checksum(pxe_image_filename)
        checksum.md5(pxe_md5_filename)

        # create pxe config append information
        # this information helps to configure the boot server correctly
        append_filename = "".join([self.pxe_dir, "/", self.xml_state.xml_data.get_name(), ".append"])
        cmdline = "pxe=1"
        custom_cmdline = self.xml_state.build_type.get_kernelcmdline()
        if custom_cmdline:
            cmdline += " " + custom_cmdline
        with open(append_filename, "w") as append:
            append.write("%s\n" % cmdline)

        # create initrd for pxe install
        log.info("Creating pxe install boot image")
        self.__create_pxe_install_kernel_and_initrd()

        # create pxe install tarball
        log.info("Creating pxe install archive")
        archive = ArchiveTar(self.pxename.replace(".xz", ""))
        archive.create_xz_compressed(self.pxe_dir)

    def __create_pxe_install_kernel_and_initrd(self):
        kernel = Kernel(self.boot_image_task.boot_root_directory)
        if kernel.get_kernel():
            kernel.copy_kernel(self.pxe_dir, "/pxeboot.kernel")
        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(self.pxe_dir, "/pxeboot.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, self.pxe_dir + "/pxeboot.initrd.xz"])

    def __create_iso_install_kernel_and_initrd(self):
        boot_path = self.media_dir + "/boot/x86_64/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"])

    def __create_iso_install_trigger_files(self):
        initrd_trigger = self.boot_image_task.boot_root_directory + "/config.vmxsystem"
        iso_trigger = self.media_dir + "/config.isoclient"
        with open(initrd_trigger, "w") as vmx_system:
            vmx_system.write('IMAGE="%s"\n' % self.squashed_diskname)
        with open(iso_trigger, "w") as iso_system:
            iso_system.write('IMAGE="%s"\n' % self.squashed_diskname)

    def __del__(self):
        log.info("Cleaning up %s instance", type(self).__name__)
        if self.media_dir:
            Path.wipe(self.media_dir)
        if self.pxe_dir:
            Path.wipe(self.pxe_dir)
        if self.squashed_contents:
            Path.wipe(self.squashed_contents)
Esempio n. 4
0
class LiveImageBuilder(object):
    """
        Live image builder
    """
    def __init__(self, xml_state, target_dir, root_dir):
        self.media_dir = None
        self.arch = platform.machine()
        self.root_dir = root_dir
        self.target_dir = target_dir
        self.xml_state = xml_state
        self.live_type = xml_state.build_type.get_flags()
        self.types = Defaults.get_live_iso_types()
        self.hybrid = xml_state.build_type.get_hybrid()
        self.volume_id = xml_state.build_type.get_volid()
        self.machine = xml_state.get_build_type_machine_section()
        self.mbrid = ImageIdentifier()
        self.mbrid.calculate_id()

        if not self.live_type:
            self.live_type = Defaults.get_default_live_iso_type()

        self.boot_image_task = BootImageTask(
            'kiwi', xml_state, target_dir
        )
        self.firmware = FirmWare(
            xml_state
        )
        self.system_setup = SystemSetup(
            xml_state=xml_state, description_dir=None, root_dir=self.root_dir
        )
        self.isoname = ''.join(
            [
                target_dir, '/',
                xml_state.xml_data.get_name(),
                '.' + platform.machine(),
                '-' + xml_state.get_image_version(),
                '.iso'
            ]
        )
        self.live_image_file = ''.join(
            [
                target_dir, '/',
                xml_state.xml_data.get_name(),
                '-read-only.', self.arch, '-',
                xml_state.get_image_version()
            ]
        )
        self.result = Result()

    def create(self):
        # media dir to store CD contents
        self.media_dir = mkdtemp(
            prefix='live-media.', dir=self.target_dir
        )
        rootsize = SystemSize(self.media_dir)

        # custom iso metadata
        log.info('Using following live ISO metadata:')
        log.info('--> Application id: %s', self.mbrid.get_id())
        log.info('--> Publisher: %s', Defaults.get_publisher())
        custom_iso_args = [
            '-A', self.mbrid.get_id(),
            '-p', '"' + Defaults.get_preparer() + '"',
            '-publisher', '"' + Defaults.get_publisher() + '"',
        ]
        if self.volume_id:
            log.info('--> Volume id: %s', self.volume_id)
            custom_iso_args.append('-V')
            custom_iso_args.append('"' + self.volume_id + '"')

        # prepare boot(initrd) root system
        log.info('Preparing live ISO boot system')
        self.boot_image_task.prepare()

        # export modprobe configuration to boot image
        self.system_setup.export_modprobe_setup(
            self.boot_image_task.boot_root_directory
        )

        # pack system into live boot structure
        log.info('Packing system into live ISO type: %s', self.live_type)
        if self.live_type in self.types:
            live_type_image = FileSystem(
                name=self.types[self.live_type],
                device_provider=None,
                root_dir=self.root_dir
            )
            live_type_image.create_on_file(self.live_image_file)
            Command.run(
                ['mv', self.live_image_file, self.media_dir]
            )
            self.__create_live_iso_client_config(self.live_type)
        else:
            raise KiwiLiveBootImageError(
                'live ISO type "%s" not supported' % self.live_type
            )

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

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

        # create initrd for live image
        log.info('Creating live ISO boot image')
        self.__create_live_iso_kernel_and_initrd()

        # calculate size and decide if we need UDF
        if rootsize.accumulate_mbyte_file_sizes() > 4096:
            log.info('ISO exceeds 4G size, using UDF filesystem')
            custom_iso_args.append('-allow-limited-size')
            custom_iso_args.append('-udf')

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

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

        self.result.add(
            'live_image', self.isoname
        )
        return self.result

    def __create_live_iso_kernel_and_initrd(self):
        boot_path = self.media_dir + '/boot/x86_64/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 KiwiLiveBootImageError(
                '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 KiwiLiveBootImageError(
                    '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'
            ]
        )

    def __create_live_iso_client_config(self, iso_type):
        """
            Setup IMAGE and UNIONFS_CONFIG variables as they are used in
            the kiwi isoboot code. Variable contents:

            + IMAGE=target_device;live_iso_name_definition
            + UNIONFS_CONFIG=rw_device,ro_device,union_type

            If no real block device is used or can be predefined the
            word 'loop' is set as a placeholder or indicator to use a loop
            device. For more details please refer to the kiwi shell boot
            code
        """
        iso_client_config_file = self.media_dir + '/config.isoclient'
        iso_client_params = Defaults.get_live_iso_client_parameters()
        (system_device, union_device, union_type) = iso_client_params[iso_type]

        with open(iso_client_config_file, 'w') as config:
            config.write(
                'IMAGE="%s;%s.%s;%s"\n' % (
                    system_device,
                    self.xml_state.xml_data.get_name(), self.arch,
                    self.xml_state.get_image_version()
                )
            )
            config.write(
                'UNIONFS_CONFIG="%s,loop,%s"\n' %
                (union_device, union_type)
            )

    def __del__(self):
        if self.media_dir:
            log.info('Cleaning up %s instance', type(self).__name__)
            Path.wipe(self.media_dir)
Esempio n. 5
0
class DiskBuilder(object):
    """
        Disk image builder
    """
    def __init__(self, xml_state, target_dir, root_dir):
        self.root_dir = root_dir
        self.target_dir = target_dir
        self.xml_state = xml_state
        self.custom_filesystem_args = None
        self.build_type_name = xml_state.get_build_type_name()
        self.image_format = xml_state.build_type.get_format()
        self.install_iso = xml_state.build_type.get_installiso()
        self.install_stick = xml_state.build_type.get_installstick()
        self.install_pxe = xml_state.build_type.get_installpxe()
        self.blocksize = xml_state.build_type.get_target_blocksize()
        self.volume_manager_name = xml_state.get_volume_management()
        self.volumes = xml_state.get_volumes()
        self.volume_group_name = xml_state.get_volume_group_name()
        self.mdraid = xml_state.build_type.get_mdraid()
        self.luks = xml_state.build_type.get_luks()
        self.luks_os = xml_state.build_type.get_luksOS()
        self.machine = xml_state.get_build_type_machine_section()
        self.requested_filesystem = xml_state.build_type.get_filesystem()
        self.requested_boot_filesystem = \
            xml_state.build_type.get_bootfilesystem()
        self.bootloader = xml_state.build_type.get_bootloader()
        self.disk_setup = DiskSetup(
            xml_state, root_dir
        )
        self.boot_image_task = BootImageTask(
            'kiwi', xml_state, target_dir
        )
        self.firmware = FirmWare(
            xml_state
        )
        self.system_setup = SystemSetup(
            xml_state=xml_state, description_dir=None, root_dir=self.root_dir
        )
        self.diskname = ''.join(
            [
                target_dir, '/',
                xml_state.xml_data.get_name(),
                '.' + platform.machine(),
                '-' + xml_state.get_image_version(),
                '.raw'
            ]
        )
        self.install_media = self.__install_image_requested()
        self.install_image = InstallImageBuilder(
            xml_state, target_dir, self.boot_image_task
        )
        # an instance of a class with the sync_data capability
        # representing the entire image system except for the boot/ area
        # which could live on another part of the disk
        self.system = None

        # an instance of a class with the sync_data capability
        # representing the boot/ area of the disk if not part of
        # self.system
        self.system_boot = None

        # an instance of a class with the sync_data capability
        # representing the boot/efi area of the disk
        self.system_efi = None

        # result store
        self.result = Result()

    def create(self):
        if self.install_media and self.build_type_name != 'oem':
            raise KiwiInstallMediaError(
                'Install media requires oem type setup, got %s' %
                self.build_type_name
            )

        # setup recovery archive, cleanup and create archive if requested
        self.system_setup.create_recovery_archive()

        # prepare boot(initrd) root system
        log.info('Preparing boot system')
        self.boot_image_task.prepare()

        # precalculate needed disk size
        disksize_mbytes = self.disk_setup.get_disksize_mbytes()

        # create the disk
        log.info('Creating raw disk image %s', self.diskname)
        loop_provider = LoopDevice(
            self.diskname, disksize_mbytes, self.blocksize
        )
        loop_provider.create()

        self.disk = Disk(
            self.firmware.get_partition_table_type(), loop_provider
        )

        # create the bootloader instance
        self.bootloader_config = BootLoaderConfig(
            self.bootloader, self.xml_state, self.root_dir,
            {'targetbase': loop_provider.get_device()}
        )

        # create disk partitions and instance device map
        device_map = self.__build_and_map_disk_partitions()

        # create raid on current root device if requested
        if self.mdraid:
            self.raid_root = RaidDevice(device_map['root'])
            self.raid_root.create_degraded_raid(raid_level=self.mdraid)
            device_map['root'] = self.raid_root.get_device()

        # create luks on current root device if requested
        if self.luks:
            self.luks_root = LuksDevice(device_map['root'])
            self.luks_root.create_crypto_luks(
                passphrase=self.luks, os=self.luks_os
            )
            device_map['root'] = self.luks_root.get_device()

        # create filesystems on boot partition(s) if any
        self.__build_boot_filesystems(device_map)

        # create volumes and filesystems for root system
        if self.volume_manager_name:
            volume_manager_custom_parameters = {
                'root_filesystem_args':
                    self.custom_filesystem_args,
                'root_label':
                    self.disk_setup.get_root_label(),
                'root_is_snapshot':
                    self.xml_state.build_type.get_btrfs_root_is_snapshot()
            }
            volume_manager = VolumeManager(
                self.volume_manager_name, device_map['root'],
                self.root_dir + '/',
                self.volumes, volume_manager_custom_parameters
            )
            volume_manager.setup(
                self.volume_group_name
            )
            volume_manager.create_volumes(
                self.requested_filesystem
            )
            volume_manager.mount_volumes()
            self.system = volume_manager
            device_map['root'] = volume_manager.get_device()['root']
        else:
            log.info(
                'Creating root(%s) filesystem on %s',
                self.requested_filesystem, device_map['root'].get_device()
            )
            filesystem = FileSystem(
                self.requested_filesystem, device_map['root'],
                self.root_dir + '/',
                self.custom_filesystem_args
            )
            filesystem.create_on_device(
                label=self.disk_setup.get_root_label()
            )
            self.system = filesystem

        # create a random image identifier
        self.mbrid = ImageIdentifier()
        self.mbrid.calculate_id()

        # create first stage metadata to boot image
        self.__write_partition_id_config_to_boot_image()

        self.__write_recovery_metadata_to_boot_image()

        self.__write_raid_config_to_boot_image()

        self.system_setup.export_modprobe_setup(
            self.boot_image_task.boot_root_directory
        )

        # create first stage metadata to system image
        self.__write_image_identifier_to_system_image()

        self.__write_crypttab_to_system_image()

        # create initrd cpio archive
        self.boot_image_task.create_initrd(self.mbrid)

        # create second stage metadata to boot
        self.__copy_first_boot_files_to_system_image()

        self.__write_bootloader_config_to_system_image(device_map)

        self.mbrid.write_to_disk(
            self.disk.storage_provider
        )

        # syncing system data to disk image
        log.info('Syncing system to image')
        if self.system_efi:
            log.info('--> Syncing EFI boot data to EFI partition')
            self.system_efi.sync_data()

        if self.system_boot:
            log.info('--> Syncing boot data at extra partition')
            self.system_boot.sync_data(
                self.__get_exclude_list_for_boot_data_sync()
            )

        log.info('--> Syncing root filesystem data')
        self.system.sync_data(
            self.__get_exclude_list_for_root_data_sync(device_map)
        )

        # install boot loader
        self.__install_bootloader(device_map)

        self.result.add(
            'disk_image', self.diskname
        )

        # create install media if requested
        if self.install_media:
            if self.image_format:
                log.warning('Install image requested, ignoring disk format')
            if self.install_iso or self.install_stick:
                log.info('Creating hybrid ISO installation image')
                self.install_image.create_install_iso()
                self.result.add(
                    'installation_image', self.install_image.isoname
                )

            if self.install_pxe:
                log.info('Creating PXE installation archive')
                self.install_image.create_install_pxe_archive()
                self.result.add(
                    'installation_pxe_archive', self.install_image.pxename
                )

        # create disk image format if requested
        elif self.image_format:
            log.info('Creating %s Disk Format', self.image_format)
            disk_format = DiskFormat(
                self.image_format, self.xml_state,
                self.root_dir, self.target_dir
            )
            disk_format.create_image_format()
            self.result.add(
                'disk_format_image',
                self.target_dir + '/' + disk_format.get_target_name_for_format(
                    self.image_format
                )
            )

        return self.result

    def __install_image_requested(self):
        if self.install_iso or self.install_stick or self.install_pxe:
            return True

    def __get_exclude_list_for_root_data_sync(self, device_map):
        exclude_list = [
            'image', '.profile', '.kconfig', 'var/cache/kiwi'
        ]
        if 'boot' in device_map and self.bootloader == 'grub2_s390x_emu':
            exclude_list.append('boot/zipl/*')
            exclude_list.append('boot/zipl/.*')
        elif 'boot' in device_map:
            exclude_list.append('boot/*')
            exclude_list.append('boot/.*')
        return exclude_list

    def __get_exclude_list_for_boot_data_sync(self):
        return ['efi/*']

    def __build_boot_filesystems(self, device_map):
        if 'efi' in device_map:
            log.info(
                'Creating EFI(fat16) filesystem on %s',
                device_map['efi'].get_device()
            )
            filesystem = FileSystem(
                'fat16', device_map['efi'], self.root_dir + '/boot/efi/'
            )
            filesystem.create_on_device(
                label=self.disk_setup.get_efi_label()
            )
            self.system_efi = filesystem

        if 'boot' in device_map:
            boot_filesystem = self.requested_boot_filesystem
            if not boot_filesystem:
                boot_filesystem = self.requested_filesystem
            boot_directory = self.root_dir + '/boot/'
            if self.bootloader == 'grub2_s390x_emu':
                boot_directory = self.root_dir + '/boot/zipl/'
                boot_filesystem = 'ext2'
            log.info(
                'Creating boot(%s) filesystem on %s',
                boot_filesystem, device_map['boot'].get_device()
            )
            filesystem = FileSystem(
                boot_filesystem, device_map['boot'], boot_directory
            )
            filesystem.create_on_device(
                label=self.disk_setup.get_boot_label()
            )
            self.system_boot = filesystem

    def __build_and_map_disk_partitions(self):
        self.disk.wipe()
        if self.firmware.legacy_bios_mode():
            log.info('--> creating EFI CSM(legacy bios) partition')
            self.disk.create_efi_csm_partition(
                self.firmware.get_legacy_bios_partition_size()
            )

        if self.firmware.efi_mode():
            log.info('--> creating EFI partition')
            self.disk.create_efi_partition(
                self.firmware.get_efi_partition_size()
            )

        if self.disk_setup.need_boot_partition():
            log.info('--> creating boot partition')
            self.disk.create_boot_partition(
                self.disk_setup.boot_partition_size()
            )

        if self.volume_manager_name and self.volume_manager_name == 'lvm':
            log.info('--> creating LVM root partition')
            self.disk.create_root_lvm_partition('all_free')

        elif self.mdraid:
            log.info('--> creating mdraid root partition')
            self.disk.create_root_raid_partition('all_free')

        else:
            log.info('--> creating root partition')
            self.disk.create_root_partition('all_free')

        if self.firmware.bios_mode():
            log.info('--> setting active flag to primary boot partition')
            self.disk.activate_boot_partition()

        self.disk.map_partitions()
        return self.disk.get_device()

    def __write_partition_id_config_to_boot_image(self):
        log.info('Creating config.partids in boot system')
        filename = self.boot_image_task.boot_root_directory + '/config.partids'
        partition_id_map = self.disk.get_partition_id_map()
        with open(filename, 'w') as partids:
            for id_name, id_value in partition_id_map.iteritems():
                partids.write('%s="%s"\n' % (id_name, id_value))

    def __write_raid_config_to_boot_image(self):
        if self.mdraid:
            log.info('Creating etc/mdadm.conf in boot system')
            self.raid_root.create_raid_config(
                self.boot_image_task.boot_root_directory + '/etc/mdadm.conf'
            )

    def __write_crypttab_to_system_image(self):
        if self.luks:
            log.info('Creating etc/crypttab')
            self.luks_root.create_crypttab(
                self.root_dir + '/etc/crypttab'
            )

    def __write_image_identifier_to_system_image(self):
        log.info('Creating image identifier: %s', self.mbrid.get_id())
        self.mbrid.write(
            self.root_dir + '/boot/mbrid'
        )

    def __write_recovery_metadata_to_boot_image(self):
        if os.path.exists(self.root_dir + '/recovery.partition.size'):
            log.info('Copying recovery metadata to boot image')
            Command.run(
                [
                    'cp', self.root_dir + '/recovery.partition.size',
                    self.boot_image_task.boot_root_directory
                ]
            )

    def __write_bootloader_config_to_system_image(self, device_map):
        log.info('Creating %s bootloader configuration', self.bootloader)
        boot_device = device_map['root']
        if 'boot' in device_map:
            boot_device = device_map['boot']

        partition_id_map = self.disk.get_partition_id_map()
        boot_partition_id = partition_id_map['kiwi_RootPart']
        if 'kiwi_BootPart' in partition_id_map:
            boot_partition_id = partition_id_map['kiwi_BootPart']

        boot_uuid = self.disk.get_uuid(
            boot_device.get_device()
        )
        self.bootloader_config.setup_disk_boot_images(boot_uuid)
        self.bootloader_config.setup_disk_image_config(boot_uuid)
        self.bootloader_config.write()

        self.system_setup.call_edit_boot_config_script(
            self.requested_filesystem, boot_partition_id
        )

    def __install_bootloader(self, device_map):
        boot_device = device_map['root']
        custom_install_arguments = {}
        if 'boot' in device_map:
            boot_device = device_map['boot']
            custom_install_arguments['boot_device'] = boot_device.get_device()

        bootloader = BootLoaderInstall(
            self.bootloader, self.root_dir, self.disk.storage_provider,
            custom_install_arguments
        )
        bootloader.install()

        self.system_setup.call_edit_boot_install_script(
            self.diskname, boot_device.get_device()
        )

    def __copy_first_boot_files_to_system_image(self):
        log.info('Copy boot files to system image')
        kernel = Kernel(self.boot_image_task.boot_root_directory)
        if kernel.get_kernel():
            log.info('--> boot image kernel as first boot linux.vmx')
            kernel.copy_kernel(
                self.root_dir, '/boot/linux.vmx'
            )
        else:
            raise KiwiDiskBootImageError(
                '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():
                log.info('--> boot image Xen hypervisor as xen.gz')
                kernel.copy_xen_hypervisor(
                    self.root_dir, '/boot/xen.gz'
                )
            else:
                raise KiwiDiskBootImageError(
                    'No hypervisor in boot image tree %s found' %
                    self.boot_image_task.boot_root_directory
                )
        log.info('--> initrd archive as first boot initrd.vmx')
        Command.run(
            [
                'mv', self.boot_image_task.initrd_filename,
                self.root_dir + '/boot/initrd.vmx'
            ]
        )
Esempio n. 6
0
    def create(self):
        if self.install_media and self.build_type_name != 'oem':
            raise KiwiInstallMediaError(
                'Install media requires oem type setup, got %s' %
                self.build_type_name
            )

        # setup recovery archive, cleanup and create archive if requested
        self.system_setup.create_recovery_archive()

        # prepare boot(initrd) root system
        log.info('Preparing boot system')
        self.boot_image_task.prepare()

        # precalculate needed disk size
        disksize_mbytes = self.disk_setup.get_disksize_mbytes()

        # create the disk
        log.info('Creating raw disk image %s', self.diskname)
        loop_provider = LoopDevice(
            self.diskname, disksize_mbytes, self.blocksize
        )
        loop_provider.create()

        self.disk = Disk(
            self.firmware.get_partition_table_type(), loop_provider
        )

        # create the bootloader instance
        self.bootloader_config = BootLoaderConfig(
            self.bootloader, self.xml_state, self.root_dir,
            {'targetbase': loop_provider.get_device()}
        )

        # create disk partitions and instance device map
        device_map = self.__build_and_map_disk_partitions()

        # create raid on current root device if requested
        if self.mdraid:
            self.raid_root = RaidDevice(device_map['root'])
            self.raid_root.create_degraded_raid(raid_level=self.mdraid)
            device_map['root'] = self.raid_root.get_device()

        # create luks on current root device if requested
        if self.luks:
            self.luks_root = LuksDevice(device_map['root'])
            self.luks_root.create_crypto_luks(
                passphrase=self.luks, os=self.luks_os
            )
            device_map['root'] = self.luks_root.get_device()

        # create filesystems on boot partition(s) if any
        self.__build_boot_filesystems(device_map)

        # create volumes and filesystems for root system
        if self.volume_manager_name:
            volume_manager_custom_parameters = {
                'root_filesystem_args':
                    self.custom_filesystem_args,
                'root_label':
                    self.disk_setup.get_root_label(),
                'root_is_snapshot':
                    self.xml_state.build_type.get_btrfs_root_is_snapshot()
            }
            volume_manager = VolumeManager(
                self.volume_manager_name, device_map['root'],
                self.root_dir + '/',
                self.volumes, volume_manager_custom_parameters
            )
            volume_manager.setup(
                self.volume_group_name
            )
            volume_manager.create_volumes(
                self.requested_filesystem
            )
            volume_manager.mount_volumes()
            self.system = volume_manager
            device_map['root'] = volume_manager.get_device()['root']
        else:
            log.info(
                'Creating root(%s) filesystem on %s',
                self.requested_filesystem, device_map['root'].get_device()
            )
            filesystem = FileSystem(
                self.requested_filesystem, device_map['root'],
                self.root_dir + '/',
                self.custom_filesystem_args
            )
            filesystem.create_on_device(
                label=self.disk_setup.get_root_label()
            )
            self.system = filesystem

        # create a random image identifier
        self.mbrid = ImageIdentifier()
        self.mbrid.calculate_id()

        # create first stage metadata to boot image
        self.__write_partition_id_config_to_boot_image()

        self.__write_recovery_metadata_to_boot_image()

        self.__write_raid_config_to_boot_image()

        self.system_setup.export_modprobe_setup(
            self.boot_image_task.boot_root_directory
        )

        # create first stage metadata to system image
        self.__write_image_identifier_to_system_image()

        self.__write_crypttab_to_system_image()

        # create initrd cpio archive
        self.boot_image_task.create_initrd(self.mbrid)

        # create second stage metadata to boot
        self.__copy_first_boot_files_to_system_image()

        self.__write_bootloader_config_to_system_image(device_map)

        self.mbrid.write_to_disk(
            self.disk.storage_provider
        )

        # syncing system data to disk image
        log.info('Syncing system to image')
        if self.system_efi:
            log.info('--> Syncing EFI boot data to EFI partition')
            self.system_efi.sync_data()

        if self.system_boot:
            log.info('--> Syncing boot data at extra partition')
            self.system_boot.sync_data(
                self.__get_exclude_list_for_boot_data_sync()
            )

        log.info('--> Syncing root filesystem data')
        self.system.sync_data(
            self.__get_exclude_list_for_root_data_sync(device_map)
        )

        # install boot loader
        self.__install_bootloader(device_map)

        self.result.add(
            'disk_image', self.diskname
        )

        # create install media if requested
        if self.install_media:
            if self.image_format:
                log.warning('Install image requested, ignoring disk format')
            if self.install_iso or self.install_stick:
                log.info('Creating hybrid ISO installation image')
                self.install_image.create_install_iso()
                self.result.add(
                    'installation_image', self.install_image.isoname
                )

            if self.install_pxe:
                log.info('Creating PXE installation archive')
                self.install_image.create_install_pxe_archive()
                self.result.add(
                    'installation_pxe_archive', self.install_image.pxename
                )

        # create disk image format if requested
        elif self.image_format:
            log.info('Creating %s Disk Format', self.image_format)
            disk_format = DiskFormat(
                self.image_format, self.xml_state,
                self.root_dir, self.target_dir
            )
            disk_format.create_image_format()
            self.result.add(
                'disk_format_image',
                self.target_dir + '/' + disk_format.get_target_name_for_format(
                    self.image_format
                )
            )

        return self.result