diff options
Diffstat (limited to 'scripts/runqemu')
| -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() |
