diff options
-rwxr-xr-x | scripts/runqemu | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/scripts/runqemu b/scripts/runqemu index 3d77046972..c668906bdd 100755 --- a/scripts/runqemu +++ b/scripts/runqemu | |||
@@ -197,7 +197,7 @@ class BaseConfig(object): | |||
197 | self.portlocks = {} | 197 | self.portlocks = {} |
198 | self.bitbake_e = '' | 198 | self.bitbake_e = '' |
199 | self.snapshot = False | 199 | self.snapshot = False |
200 | self.wictypes = ('wic', 'wic.vmdk', 'wic.qcow2', 'wic.vdi', "wic.vhd", "wic.vhdx") | 200 | self.wictypes = ('wic.zst', 'wic', 'wic.vmdk', 'wic.qcow2', 'wic.vdi', "wic.vhd", "wic.vhdx") |
201 | self.fstypes = ('ext2', 'ext3', 'ext4', 'jffs2', 'nfs', 'btrfs', | 201 | self.fstypes = ('ext2', 'ext3', 'ext4', 'jffs2', 'nfs', 'btrfs', |
202 | 'cpio.gz', 'cpio', 'ramfs', 'tar.bz2', 'tar.gz', | 202 | 'cpio.gz', 'cpio', 'ramfs', 'tar.bz2', 'tar.gz', |
203 | 'squashfs', 'squashfs-xz', 'squashfs-lzo', | 203 | 'squashfs', 'squashfs-xz', 'squashfs-lzo', |
@@ -418,6 +418,48 @@ class BaseConfig(object): | |||
418 | else: | 418 | else: |
419 | raise RunQemuError("Unknown path arg %s" % p) | 419 | raise RunQemuError("Unknown path arg %s" % p) |
420 | 420 | ||
421 | def uncompress_rootfs(self): | ||
422 | """Decompress ZST rootfs image if needed""" | ||
423 | if not self.rootfs or not self.fstype.endswith('.zst'): | ||
424 | return | ||
425 | |||
426 | # Ensure snapshot mode is active before allowing decompression. | ||
427 | if not self.snapshot: | ||
428 | raise RunQemuError(".zst images are only supported with snapshot mode. " \ | ||
429 | "You can either use the \"snapshot\" option or use an uncompressed image.") | ||
430 | |||
431 | # Get the real path to the image to avoid issues when a symbolic link is passed. | ||
432 | # This ensures we always operate on the actual file. | ||
433 | image_path = os.path.realpath(self.rootfs) | ||
434 | # Extract target filename by removing .zst | ||
435 | image_dir = os.path.dirname(image_path) | ||
436 | uncompressed_name = os.path.basename(image_path).replace(".zst", "") | ||
437 | uncompressed_path = os.path.join(image_dir, uncompressed_name) | ||
438 | |||
439 | # If the decompressed image already exists (e.g., in the deploy directory), | ||
440 | # we use it directly to avoid overwriting artifacts generated by the build system. | ||
441 | # This prevents redundant decompression and preserves build outputs. | ||
442 | if os.path.exists(uncompressed_path): | ||
443 | logger.warning(f"Found existing decompressed image: {uncompressed_path}, Using it directly.") | ||
444 | else: | ||
445 | logger.info(f"Decompressing {self.rootfs} to {uncompressed_path}") | ||
446 | # Ensure the 'zstd' tool is installed before attempting to decompress. | ||
447 | if not shutil.which('zstd'): | ||
448 | raise RunQemuError(f"'zstd' is required to decompress {self.rootfs} but was not found in PATH") | ||
449 | try: | ||
450 | with open(uncompressed_path, 'wb') as out_file: | ||
451 | subprocess.check_call(['zstd', '-d', '-c', image_path], stdout=out_file) | ||
452 | except subprocess.CalledProcessError as e: | ||
453 | self.cleanup_files.append(uncompressed_path) | ||
454 | raise RunQemuError(f"Failed to decompress {self.rootfs}: {e}") | ||
455 | |||
456 | # Mark for deletion at the end | ||
457 | self.cleanup_files.append(uncompressed_path) | ||
458 | |||
459 | # Use the decompressed image as the rootfs | ||
460 | self.rootfs = uncompressed_path | ||
461 | self.fstype = self.fstype.removesuffix(".zst") | ||
462 | |||
421 | def check_arg_machine(self, arg): | 463 | def check_arg_machine(self, arg): |
422 | """Check whether it is a machine""" | 464 | """Check whether it is a machine""" |
423 | if self.get('MACHINE') == arg: | 465 | if self.get('MACHINE') == arg: |
@@ -1762,6 +1804,7 @@ def main(): | |||
1762 | config.check_args() | 1804 | config.check_args() |
1763 | config.read_qemuboot() | 1805 | config.read_qemuboot() |
1764 | config.check_and_set() | 1806 | config.check_and_set() |
1807 | config.uncompress_rootfs() | ||
1765 | # Check whether the combos is valid or not | 1808 | # Check whether the combos is valid or not |
1766 | config.validate_combos() | 1809 | config.validate_combos() |
1767 | config.print_config() | 1810 | config.print_config() |