def create_image( self, location: Location, system_context: SystemContext, export_volume: str, *, efi_partition: str, root_partition: str, verity_partition: str, root_hash: str, ): image_name = system_context.substitution_expanded( "CLRM_IMAGE_FILENAME", "") assert image_name image_filename = os.path.join( export_volume, image_name, ) assert efi_partition assert root_partition assert verity_partition total_size = ((2 * 1024 * 1024) + file_size(None, efi_partition) + file_size(None, root_partition) + file_size(None, verity_partition)) root_uuid = _uuid_ify(root_hash[:32]) if root_hash else "" verity_uuid = _uuid_ify(root_hash[32:]) if root_hash else "" with open(image_filename, "wb") as fd: fd.seek(total_size - 1) fd.write(b"\b") self._execute( location, system_context, "_create_export_image", image_filename, efi_fsimage=efi_partition, efi_label="ESP", root_fsimage=root_partition, root_label=system_context.substitution_expanded( "ROOTFS_PARTLABEL", ""), root_uuid=root_uuid, verity_fsimage=verity_partition, verity_label=system_context.substitution_expanded( "VRTYFS_PARTLABEL", ""), verity_uuid=verity_uuid, )
def __call__( self, location: Location, system_context: SystemContext, *args: typing.Any, **kwargs: typing.Any, ) -> None: """Execute command.""" image_filename = args[0] efi_partition = kwargs.get("efi_fsimage", "") efi_label = kwargs.get("efi_label", "") efi_uuid = kwargs.get("efi_uuid", "") assert efi_partition root_partition = kwargs.get("root_fsimage", "") root_label = kwargs.get("root_label", "") root_uuid = kwargs.get("root_uuid", "") assert root_partition verity_partition = kwargs.get("verity_fsimage", "") verity_label = kwargs.get("verity_label", "") verity_uuid = kwargs.get("verity_uuid", "") assert verity_partition efi_size = file_size(None, efi_partition) root_size = file_size(None, root_partition) verity_size = file_size(None, verity_partition) total_size = (2 * 1024 * 1024) + efi_size + root_size + verity_size debug( f"Creating export image with {total_size} bytes (EFI: {efi_size}, root: {root_size}, verity: {verity_size})" ) with open(image_filename, "wb") as fd: fd.seek(total_size - 1) fd.write(b"\0") repart_d_directory = os.path.join(system_context.cache_directory, "repart.d") os.makedirs(repart_d_directory) _write_repart_config( repart_d_directory, "10_efi.conf", type="esp", image=efi_partition, label=efi_label, uuid=efi_uuid, ) _write_repart_config( repart_d_directory, "20_rootfs.conf", type="root-x86-64", image=root_partition, label=root_label, uuid=root_uuid, ) _write_repart_config( repart_d_directory, "30_verity.conf", type="root-x86-64-verity", image=verity_partition, label=verity_label, uuid=verity_uuid, ) run( self._binary(Binaries.SYSTEMD_REPART), "--dry-run=no", "--empty=require", f"--root={system_context.fs_directory}", f"--definitions={repart_d_directory}", image_filename, )
def __call__( self, location: Location, system_context: SystemContext, *args: typing.Any, **kwargs: typing.Any, ) -> None: """Execute command.""" efi_file = args[0] kernel_file = kwargs.get("kernel_file", "") boot_loader_file = kwargs.get("systemd_boot_loader", "") requested_size = int(kwargs.get("requested_size", "0")) extra_files = kwargs.get("extra_files", "") efi_emulator = kwargs.get("efi_emulator", "") partition_label = kwargs.get("partition_label", "") root_hash = kwargs.get("root_hash", "") if kernel_file: if not os.path.isfile(boot_loader_file): raise GenerateError( "You must provide a boot loader file and that must be a file when passing a kernel file." ) if extra_files: extra_files = os.path.join( system_context.systems_definition_directory, extra_files) if not os.path.isdir(extra_files): raise GenerateError( f"extra_files {extra_files} is not a directory.") kernel_size = file_size(None, kernel_file) if kernel_file else 256 * 1024 boot_loader_size = file_size(None, boot_loader_file) min_efi_size = kernel_size if kernel_file: if efi_emulator: min_efi_size += 10 * mib if extra_files: min_efi_size += _get_tree_size(extra_files) min_efi_size += 2 * boot_loader_size efi_size = _calculate_efi_size(min_efi_size, requested_size) # create file: with open(efi_file, "wb") as fd: fd.seek(efi_size - 1) fd.write(b"\0") # format file: self._format_efi_partition(efi_file, partition_label=partition_label) with TemporaryDirectory() as staging_area: if kernel_file: if efi_emulator: _populate_with_efi_emulator(staging_area, efi_emulator) trace("... Clover binaries have been installed.") if extra_files: shutil.copytree(extra_files, staging_area, dirs_exist_ok=True) trace("... Extra EFI files installed.") # install systemd as default boot loader: default_boot_path = os.path.join(staging_area, "EFI/Boot") os.makedirs(default_boot_path) trace('... "EFI/boot" directory created.') _copy_efi_file(boot_loader_file, os.path.join(default_boot_path, "BOOTX64.EFI")) trace("... default boot loader installed") os.makedirs(os.path.join(staging_area, "EFI/systemd")) trace('... "EFI/systemd" directory created.') _copy_efi_file( boot_loader_file, os.path.join(staging_area, "EFI/systemd/" "systemd-bootx64.efi"), ) trace("... systemd boot loader installed.") linux_dir = os.path.join(staging_area, "EFI/Linux") os.makedirs(linux_dir) trace('... "EFI/Linux" created.') _copy_efi_file(kernel_file, linux_dir) trace("... kernel installed") else: with open(os.path.join(staging_area, "no_boot.txt"), "w") as f: f.write("No EFI boot support installed\n") if root_hash: with open(os.path.join(staging_area, "root_hash"), "w") as f: f.write(f"{root_hash}") _copy_staging_area_into_efi_partition_file( staging_area, efi_file, mmd=self._binary(Binaries.MTOOLS_MMD), mcopy=self._binary(Binaries.MTOOLS_MCOPY), )