summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xscripts/runqemu45
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()