@@ -62,6 +62,9 @@ pub enum VmCommand {
6262
6363 #[ arg( long, help = "Enable hugepages for memory allocation" ) ]
6464 hugepages : bool ,
65+
66+ #[ arg( long, help = "Path to ignition file or the content itself" ) ]
67+ ignition : Option < String > ,
6568 } ,
6669 /// Start an existing virtual machine
6770 Start {
@@ -126,6 +129,9 @@ pub enum VmCommand {
126129
127130 #[ arg( long, help = "Enable hugepages for memory allocation" ) ]
128131 hugepages : bool ,
132+
133+ #[ arg( long, help = "Path to ignition file or the content itself" ) ]
134+ ignition : Option < String > ,
129135 } ,
130136 /// Watch virtual machine state change events
131137 Events {
@@ -188,6 +194,17 @@ pub enum VmCommand {
188194 } ,
189195}
190196
197+ #[ derive( Debug , Clone ) ]
198+ struct CreateVmOptions {
199+ image_ref : String ,
200+ vcpus : u32 ,
201+ memory : u64 ,
202+ vm_id : Option < String > ,
203+ pci_devices : Vec < String > ,
204+ hugepages : bool ,
205+ ignition : Option < String > ,
206+ }
207+
191208pub async fn handle_vm_command ( args : VmArgs ) -> Result < ( ) > {
192209 let mut client = VmServiceClient :: connect ( args. address )
193210 . await
@@ -201,17 +218,18 @@ pub async fn handle_vm_command(args: VmArgs) -> Result<()> {
201218 vm_id,
202219 pci_device,
203220 hugepages,
221+ ignition,
204222 } => {
205- create_vm (
206- & mut client,
223+ let opts = CreateVmOptions {
207224 image_ref,
208225 vcpus,
209226 memory,
210227 vm_id,
211- pci_device,
228+ pci_devices : pci_device,
212229 hugepages,
213- )
214- . await ?
230+ ignition,
231+ } ;
232+ create_vm ( & mut client, opts) . await ?
215233 }
216234 VmCommand :: Start { vm_id } => start_vm ( & mut client, vm_id) . await ?,
217235 VmCommand :: Info { vm_id } => get_vm_info ( & mut client, vm_id) . await ?,
@@ -228,17 +246,18 @@ pub async fn handle_vm_command(args: VmArgs) -> Result<()> {
228246 vm_id,
229247 pci_device,
230248 hugepages,
249+ ignition,
231250 } => {
232- create_and_start_vm (
233- & mut client,
251+ let opts = CreateVmOptions {
234252 image_ref,
235253 vcpus,
236254 memory,
237255 vm_id,
238- pci_device,
256+ pci_devices : pci_device,
239257 hugepages,
240- )
241- . await ?
258+ ignition,
259+ } ;
260+ create_and_start_vm ( & mut client, opts) . await ?
242261 }
243262 VmCommand :: Events { vm_id } => watch_events ( & mut client, vm_id) . await ?,
244263 VmCommand :: Console { vm_id } => console_vm ( & mut client, vm_id) . await ?,
@@ -273,18 +292,33 @@ pub async fn handle_vm_command(args: VmArgs) -> Result<()> {
273292
274293async fn create_and_start_vm (
275294 client : & mut VmServiceClient < Channel > ,
276- image_ref : String ,
277- vcpus : u32 ,
278- memory : u64 ,
279- vm_id : Option < String > ,
280- pci_devices : Vec < String > ,
281- hugepages : bool ,
295+ opts : CreateVmOptions ,
282296) -> Result < ( ) > {
297+ let CreateVmOptions {
298+ image_ref,
299+ vcpus,
300+ memory,
301+ vm_id,
302+ pci_devices,
303+ hugepages,
304+ ignition,
305+ } = opts;
306+
283307 println ! ( "� Starting create and start operation for VM with image: {image_ref}" ) ;
284308
285309 // Step 1: Create the VM
286310 println ! ( "� Step 1: Creating VM..." ) ;
287311
312+ let ignition_data = if let Some ( ignition_str) = ignition {
313+ if tokio:: fs:: metadata ( & ignition_str) . await . is_ok ( ) {
314+ Some ( tokio:: fs:: read_to_string ( ignition_str) . await ?)
315+ } else {
316+ Some ( ignition_str)
317+ }
318+ } else {
319+ None
320+ } ;
321+
288322 let net_configs = pci_devices
289323 . iter ( )
290324 . map ( |bdf| {
@@ -310,6 +344,7 @@ async fn create_and_start_vm(
310344 } ) ,
311345 image_ref : image_ref. clone ( ) ,
312346 net : net_configs,
347+ ignition : ignition_data,
313348 ..Default :: default ( )
314349 } ) ,
315350 vm_id : vm_id. clone ( ) ,
@@ -405,17 +440,29 @@ async fn wait_for_vm_state(
405440 anyhow:: bail!( "Event stream ended before reaching target state: {target_state:?}" )
406441}
407442
408- async fn create_vm (
409- client : & mut VmServiceClient < Channel > ,
410- image_ref : String ,
411- vcpus : u32 ,
412- memory : u64 ,
413- vm_id : Option < String > ,
414- pci_devices : Vec < String > ,
415- hugepages : bool ,
416- ) -> Result < ( ) > {
443+ async fn create_vm ( client : & mut VmServiceClient < Channel > , opts : CreateVmOptions ) -> Result < ( ) > {
444+ let CreateVmOptions {
445+ image_ref,
446+ vcpus,
447+ memory,
448+ vm_id,
449+ pci_devices,
450+ hugepages,
451+ ignition,
452+ } = opts;
453+
417454 println ! ( "Requesting VM creation with image: {image_ref}..." ) ;
418455
456+ let ignition_data = if let Some ( ignition_str) = ignition {
457+ if tokio:: fs:: metadata ( & ignition_str) . await . is_ok ( ) {
458+ Some ( tokio:: fs:: read_to_string ( ignition_str) . await ?)
459+ } else {
460+ Some ( ignition_str)
461+ }
462+ } else {
463+ None
464+ } ;
465+
419466 let net_configs = pci_devices
420467 . into_iter ( )
421468 . map ( |bdf| {
@@ -439,6 +486,7 @@ async fn create_vm(
439486 } ) ,
440487 image_ref,
441488 net : net_configs,
489+ ignition : ignition_data,
442490 ..Default :: default ( )
443491 } ) ,
444492 vm_id,
0 commit comments