From 37e23a16a35c4b34eda2474f417414e0f680e1ed Mon Sep 17 00:00:00 2001 From: Zhang Junyang Date: Thu, 23 May 2024 08:47:50 +0000 Subject: [PATCH] Bring OSDK's full support of QCOW2 booting --- osdk/src/bundle/mod.rs | 36 ++++++++++++++-------------- osdk/src/bundle/vm_image.rs | 4 ++++ osdk/src/commands/build/mod.rs | 13 +++++++---- osdk/src/commands/build/qcow2.rs | 40 ++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 osdk/src/commands/build/qcow2.rs diff --git a/osdk/src/bundle/mod.rs b/osdk/src/bundle/mod.rs index db8a89007..9a0f19bd6 100644 --- a/osdk/src/bundle/mod.rs +++ b/osdk/src/bundle/mod.rs @@ -200,18 +200,9 @@ impl Bundle { ActionChoice::Test => &config.test, }; let mut qemu_cmd = Command::new(&action.qemu.path); + qemu_cmd.current_dir(&config.work_dir); - match shlex::split(&action.qemu.args) { - Some(v) => { - for arg in v { - qemu_cmd.arg(arg); - } - } - None => { - error_msg!("Failed to parse qemu args: {:#?}", &action.qemu.args); - process::exit(Errno::ParseMetadata as _); - } - } + match action.boot.method { BootMethod::QemuDirect => { let aster_bin = self.manifest.aster_bin.as_ref().unwrap(); @@ -228,22 +219,33 @@ impl Bundle { BootMethod::GrubRescueIso => { let vm_image = self.manifest.vm_image.as_ref().unwrap(); assert!(matches!(vm_image.typ(), AsterVmImageType::GrubIso(_))); - qemu_cmd.arg("-cdrom").arg(self.path.join(vm_image.path())); + qemu_cmd.arg("-drive").arg(format!( + "file={},index=2,media=cdrom", + self.path.join(vm_image.path()).to_string_lossy() + )); } BootMethod::GrubQcow2 => { let vm_image = self.manifest.vm_image.as_ref().unwrap(); assert!(matches!(vm_image.typ(), AsterVmImageType::Qcow2(_))); qemu_cmd.arg("-drive").arg(format!( "file={},index=0,media=disk,format=qcow2", - self.path - .join(vm_image.path()) - .into_os_string() - .into_string() - .unwrap() + self.path.join(vm_image.path()).to_string_lossy() )); } }; + match shlex::split(&action.qemu.args) { + Some(v) => { + for arg in v { + qemu_cmd.arg(arg); + } + } + None => { + error_msg!("Failed to parse qemu args: {:#?}", &action.qemu.args); + process::exit(Errno::ParseMetadata as _); + } + } + info!("Running QEMU: {:#?}", qemu_cmd); let exit_status = qemu_cmd.status().unwrap(); diff --git a/osdk/src/bundle/vm_image.rs b/osdk/src/bundle/vm_image.rs index 1c052c78a..5c90d2956 100644 --- a/osdk/src/bundle/vm_image.rs +++ b/osdk/src/bundle/vm_image.rs @@ -72,4 +72,8 @@ impl AsterVmImage { sha256sum: self.sha256sum, } } + + pub fn aster_version(&self) -> &String { + &self.aster_version + } } diff --git a/osdk/src/commands/build/mod.rs b/osdk/src/commands/build/mod.rs index 98247bd19..80165df0c 100644 --- a/osdk/src/commands/build/mod.rs +++ b/osdk/src/commands/build/mod.rs @@ -2,6 +2,7 @@ mod bin; mod grub; +mod qcow2; use std::{ ffi::OsString, @@ -159,7 +160,7 @@ pub fn do_build( ); match boot.method { - BootMethod::GrubRescueIso => { + BootMethod::GrubRescueIso | BootMethod::GrubQcow2 => { info!("Building boot device image"); let bootdev_image = grub::create_bootdev_image( &osdk_output_directory, @@ -168,16 +169,18 @@ pub fn do_build( config, action, ); - bundle.consume_vm_image(bootdev_image); + if matches!(boot.method, BootMethod::GrubQcow2) { + let qcow2_image = qcow2::convert_iso_to_qcow2(bootdev_image); + bundle.consume_vm_image(qcow2_image); + } else { + bundle.consume_vm_image(bootdev_image); + } bundle.consume_aster_bin(aster_elf); } BootMethod::QemuDirect => { let qemu_elf = make_elf_for_qemu(&osdk_output_directory, &aster_elf, build.strip_elf); bundle.consume_aster_bin(qemu_elf); } - BootMethod::GrubQcow2 => { - todo!() - } } bundle diff --git a/osdk/src/commands/build/qcow2.rs b/osdk/src/commands/build/qcow2.rs new file mode 100644 index 000000000..39418b7a6 --- /dev/null +++ b/osdk/src/commands/build/qcow2.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MPL-2.0 + +use std::process; + +use crate::{ + bundle::{ + file::BundleFile, + vm_image::{AsterQcow2ImageMeta, AsterVmImage, AsterVmImageType}, + }, + error_msg, +}; + +pub fn convert_iso_to_qcow2(iso: AsterVmImage) -> AsterVmImage { + let AsterVmImageType::GrubIso(meta) = iso.typ() else { + panic!("Expected a GRUB ISO image, but got: {:?}", iso.typ()); + }; + let iso_path = iso.path(); + let qcow2_path = iso_path.with_extension("qcow2"); + // Convert the ISO to QCOW2 using `qemu-img`. + let mut qemu_img = process::Command::new("qemu-img"); + qemu_img.args([ + "convert", + "-O", + "qcow2", + iso_path.to_str().unwrap(), + qcow2_path.to_str().unwrap(), + ]); + info!("Converting the ISO to QCOW2 using {:#?}", qemu_img); + if !qemu_img.status().unwrap().success() { + error_msg!("Failed to convert the ISO to QCOW2: {:?}", qemu_img); + process::exit(1); + } + AsterVmImage::new( + qcow2_path, + AsterVmImageType::Qcow2(AsterQcow2ImageMeta { + grub_version: meta.grub_version.clone(), + }), + iso.aster_version().clone(), + ) +}