Skip to main content

qemu_command_builder/
lib.rs

1#![recursion_limit = "256"]
2
3pub mod accel;
4pub mod acpitable;
5pub mod action;
6pub mod addfs;
7pub mod audio;
8pub mod audiodev;
9pub mod blockdev;
10pub mod boot;
11pub mod chardev;
12pub mod common;
13pub mod compact;
14pub mod cpu;
15pub mod cpu_flags;
16pub mod cpu_type;
17pub mod device;
18pub mod display;
19pub mod drive;
20pub mod fsdev;
21pub mod fw_cfg;
22pub mod global;
23pub mod icount;
24pub mod incoming;
25pub mod iscsi;
26pub mod machine;
27pub mod machine_type;
28pub mod memory;
29pub mod mon;
30pub mod msg;
31pub mod name;
32pub mod netdev;
33pub mod numa;
34pub mod object;
35pub mod overcommit;
36pub mod parser;
37pub mod parsers;
38pub mod plugin;
39pub mod rtc;
40pub mod runwith;
41pub mod sandbox;
42pub mod serial;
43pub mod set;
44pub mod shell_path;
45pub mod shell_string;
46pub mod smbios;
47pub mod smp;
48pub mod spice;
49pub mod to_command;
50pub mod tpmdev;
51pub mod trace;
52pub mod usb;
53pub mod vga;
54pub mod virtfs;
55pub mod vnc;
56
57use std::path::PathBuf;
58use std::str::FromStr;
59
60use bon::Builder;
61use chrono::{DateTime, TimeZone, Utc};
62use newtype_uuid::{TypedUuidKind, TypedUuidTag};
63use proptest::prelude::{Arbitrary, Just};
64use proptest_derive::Arbitrary;
65
66use crate::accel::Accel;
67use crate::acpitable::AcpiTable;
68use crate::action::{Action, WatchdogAction};
69use crate::addfs::AddFd;
70use crate::audio::Audio;
71use crate::audiodev::AudioDev;
72use crate::blockdev::BlockDev;
73use crate::boot::Boot;
74use crate::chardev::CharDev;
75use crate::compact::Compact;
76use crate::cpu::{CpuAarch64, CpuX86};
77use crate::device::Device;
78use crate::display::QemuDisplay;
79use crate::drive::Drive;
80use crate::fsdev::FsDev;
81use crate::fw_cfg::FwCfg;
82use crate::global::Global;
83use crate::icount::Icount;
84use crate::incoming::Incoming;
85use crate::iscsi::Iscsi;
86use crate::machine::{MachineAarch64, MachineX86_64};
87use crate::memory::Memory;
88use crate::mon::Mon;
89use crate::msg::Msg;
90use crate::name::Name;
91use crate::netdev::NetDev;
92use crate::numa::NUMA;
93use crate::object::Object;
94use crate::overcommit::Overcommit;
95use crate::parsers::{
96    ARG_APPEND, ARG_BIG_D, ARG_BIG_S, ARG_BIOS, ARG_CDROM, ARG_DAEMONIZE, ARG_DEBUGCON, ARG_DTB, ARG_DUMP_VMSTATE, ARG_ECHR, ARG_ENABLE_KVM, ARG_ENABLE_SYNC_PROFILE, ARG_FDA, ARG_FDB,
97    ARG_FULL_SCREEN, ARG_G, ARG_GDB, ARG_HDA, ARG_HDB, ARG_HDC, ARG_HDD, ARG_INITRD, ARG_JITDUMP, ARG_K, ARG_KERNEL, ARG_L, ARG_LITTLE_D, ARG_LITTLE_S, ARG_LOADVM, ARG_MEM_PATH, ARG_MEM_PREALLOC,
98    ARG_MONITOR, ARG_MTDBLOCK, ARG_NO_FD_BOOTCHK, ARG_NO_REBOOT, ARG_NO_SHUTDOWN, ARG_NO_USER_CONFIG, ARG_NODEFAULTS, ARG_NOGRAPHIC, ARG_ONLY_MIGRATABLE, ARG_OPTION_ROM, ARG_PARALLEL, ARG_PERFMAP,
99    ARG_PFLASH, ARG_PIDFILE, ARG_PRECONFIG, ARG_QMP, ARG_QMP_PRETTY, ARG_READCONFIG, ARG_SD, ARG_SEED, ARG_SERIAL, ARG_SHIM, ARG_SNAPSHOT, ARG_USB, ARG_UUID, ARG_WIN2K_HACK, ARG_XEN_ATTACH,
100    ARG_XEN_DOMID_RESTRICT, ARG_XEN_ID, DELIM_COMMA,
101};
102use crate::plugin::Plugin;
103use crate::rtc::Rtc;
104use crate::runwith::RunWith;
105use crate::sandbox::Sandbox;
106use crate::serial::SpecialDevice;
107use crate::set::Set;
108use crate::shell_string::ShellString;
109use crate::smbios::Smbios;
110use crate::smp::SMP;
111use crate::spice::Spice;
112use crate::to_command::{ToArg, ToCommand};
113use crate::tpmdev::TpmDev;
114use crate::trace::Trace;
115use crate::usb::USBDevice;
116use crate::vga::VGA;
117use crate::virtfs::Virtfs;
118use crate::vnc::VNC;
119
120/// QEMU binary name for x86_64
121const QEMU_BIN_X86_64: &str = "qemu-system-x86_64";
122
123/// QEMU binary name for aarch64
124const QEMU_BIN_AARCH64: &str = "qemu-system-aarch64";
125
126#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder, Arbitrary)]
127pub struct QemuInstanceBase<Machine, Cpu> {
128    pub qemu_binary: PathBuf,
129
130    pub machine: Option<Machine>,
131    pub cpu: Option<Cpu>,
132
133    pub accel: Option<Accel>,
134    pub smp: Option<SMP>,
135    pub numa: Option<Vec<NUMA>>,
136    pub add_fd: Option<AddFd>,
137    pub set: Option<Vec<Set>>,
138    pub global: Option<Vec<Global>>,
139    pub boot: Option<Boot>,
140    pub m: Option<Memory>,
141    pub mem_path: Option<PathBuf>,
142    pub mem_prealloc: Option<bool>,
143    pub k: Option<String>,
144    pub audio: Option<Audio>,
145    pub audiodev: Option<AudioDev>,
146    pub device: Option<Vec<Device>>,
147    pub name: Option<Name>,
148    pub uuid: Option<newtype_uuid::TypedUuid<QUuid>>,
149    pub fda: Option<PathBuf>,
150    pub fdb: Option<PathBuf>,
151    pub hda: Option<PathBuf>,
152    pub hdb: Option<PathBuf>,
153    pub hdc: Option<PathBuf>,
154    pub hdd: Option<PathBuf>,
155    pub cdrom: Option<PathBuf>,
156    pub blockdev: Option<Vec<BlockDev>>,
157    pub drive: Option<Vec<Drive>>,
158    pub mdtblock: Option<PathBuf>,
159    pub sd: Option<PathBuf>,
160    pub snapshot: Option<bool>,
161    pub fsdev: Option<FsDev>,
162    pub virtfs: Option<Virtfs>,
163    pub iscsi: Option<Iscsi>,
164    pub usb: Option<bool>,
165    pub usbdevice: Option<USBDevice>,
166    pub display: Option<QemuDisplay>,
167    pub nographic: Option<bool>,
168    pub spice: Option<Spice>,
169    pub vga: Option<VGA>,
170    pub full_screen: Option<bool>,
171    pub g: Option<(usize, usize, Option<usize>)>,
172    pub vnc: Option<VNC>,
173    pub win2k_hack: Option<bool>,
174    pub no_fd_bootchk: Option<bool>,
175    pub acpitable: Option<AcpiTable>,
176    pub smbios: Option<Vec<Smbios>>,
177    pub netdev: Option<Vec<NetDev>>,
178    pub chardev: Option<Vec<CharDev>>,
179    pub tpmdev: Option<TpmDev>,
180    pub bios: Option<PathBuf>,
181    pub pflash: Option<PathBuf>,
182    pub kernel: Option<PathBuf>,
183    pub shim: Option<PathBuf>,
184    pub append: Option<ShellString>,
185    pub initrd: Option<PathBuf>,
186    pub dtb: Option<PathBuf>,
187    pub compact: Option<Compact>,
188    pub fw_cfg: Option<FwCfg>,
189    pub serial: Option<SpecialDevice>,
190    pub parallel: Option<Vec<SpecialDevice>>,
191    pub monitor: Option<SpecialDevice>,
192    pub qmp: Option<SpecialDevice>,
193    pub qmp_pretty: Option<SpecialDevice>,
194    pub mon: Option<Vec<Mon>>,
195    pub debugcon: Option<CharDev>,
196    pub pidfile: Option<PathBuf>,
197    pub preconfig: Option<bool>,
198    pub big_s: Option<bool>,
199    pub overcommit: Option<Overcommit>,
200    pub gdb: Option<SpecialDevice>,
201    pub s: Option<bool>,
202    pub d: Option<Vec<String>>,
203    pub big_d: Option<PathBuf>,
204    pub dfilter: Option<Vec<String>>,
205    pub seed: Option<usize>,
206    pub big_l: Option<PathBuf>,
207    pub enable_kvm: Option<bool>,
208    pub xen_id: Option<String>,
209    pub xen_attach: Option<bool>,
210    pub xen_domid_restrict: Option<bool>,
211    pub no_reboot: Option<bool>,
212    pub no_shutdown: Option<bool>,
213    pub action: Option<Action>,
214    pub loadvm: Option<String>,
215    pub daemonize: Option<bool>,
216    pub option_rom: Option<PathBuf>,
217    pub rtc: Option<Rtc>,
218    pub icount: Option<Icount>,
219    pub watchdog_action: Option<WatchdogAction>,
220    pub echr: Option<String>,
221    pub incoming: Option<Vec<Incoming>>,
222    pub only_migratable: Option<bool>,
223    pub nodefaults: Option<bool>,
224    pub sandbox: Option<Sandbox>,
225    pub readconfig: Option<PathBuf>,
226    pub no_user_config: Option<bool>,
227    pub trace: Option<Trace>,
228    pub plugin: Option<Plugin>,
229    pub run_with: Option<RunWith>,
230    // compat w/ qemu 7.x+
231    pub runas: Option<String>,
232    // compat w/ qemu 7.x+
233    pub chroot: Option<PathBuf>,
234    pub msg: Option<Msg>,
235    pub dump_vmstate: Option<PathBuf>,
236    pub enable_sync_profile: Option<bool>,
237    pub perfmap: Option<PathBuf>,
238    pub jitdump: Option<PathBuf>,
239    pub object: Option<Vec<Object>>,
240}
241
242impl<Machine: ToCommand, Cpu: ToCommand> ToCommand for QemuInstanceBase<Machine, Cpu>
243where
244    QemuInstanceBase<Machine, Cpu>: FromStr,
245{
246    fn command(&self) -> String {
247        self.qemu_binary.display().to_string()
248    }
249
250    fn to_args(&self) -> Vec<String> {
251        let mut cmd = vec![];
252
253        if let Some(machine) = &self.machine {
254            cmd.append(&mut machine.to_command());
255        }
256        if let Some(cpu) = &self.cpu {
257            cmd.append(&mut cpu.to_command());
258        }
259        if let Some(accel) = &self.accel {
260            cmd.append(&mut accel.to_command());
261        }
262        if let Some(smp) = &self.smp {
263            cmd.append(&mut smp.to_command());
264        }
265        if let Some(numas) = &self.numa {
266            for numa in numas {
267                cmd.append(&mut numa.to_command());
268            }
269        }
270        if let Some(add_fd) = &self.add_fd {
271            cmd.append(&mut add_fd.to_command());
272        }
273        if let Some(sets) = &self.set {
274            for set in sets {
275                cmd.append(&mut set.to_command());
276            }
277        }
278        if let Some(globals) = &self.global {
279            for global in globals {
280                cmd.append(&mut global.to_command());
281            }
282        }
283        if let Some(boot) = &self.boot {
284            cmd.append(&mut boot.to_command());
285        }
286        if let Some(m) = &self.m {
287            cmd.append(&mut m.to_command());
288        }
289        if let Some(path) = &self.mem_path {
290            cmd.push(ARG_MEM_PATH.to_string());
291            cmd.push(path.display().to_string());
292        }
293        if let Some(state) = self.mem_prealloc
294            && state
295        {
296            cmd.push(ARG_MEM_PREALLOC.to_string());
297        }
298        if let Some(lang) = &self.k {
299            cmd.push(ARG_K.to_string());
300            cmd.push(lang.to_string());
301        }
302        if let Some(audio) = &self.audio {
303            cmd.append(&mut audio.to_command());
304        }
305        if let Some(audiodev) = &self.audiodev {
306            cmd.append(&mut audiodev.to_command());
307        }
308        if let Some(devices) = &self.device {
309            for device in devices {
310                cmd.append(&mut device.to_command());
311            }
312        }
313        if let Some(name) = &self.name {
314            cmd.append(&mut name.to_command());
315        }
316        if let Some(uuid) = &self.uuid {
317            cmd.push(ARG_UUID.to_string());
318            cmd.push(uuid.to_string());
319        }
320        if let Some(fda) = &self.fda {
321            cmd.push(ARG_FDA.to_string());
322            cmd.push(fda.display().to_string());
323        }
324        if let Some(fdb) = &self.fdb {
325            cmd.push(ARG_FDB.to_string());
326            cmd.push(fdb.display().to_string());
327        }
328        if let Some(hda) = &self.hda {
329            cmd.push(ARG_HDA.to_string());
330            cmd.push(hda.display().to_string());
331        }
332        if let Some(hdb) = &self.hdb {
333            cmd.push(ARG_HDB.to_string());
334            cmd.push(hdb.display().to_string());
335        }
336        if let Some(hdc) = &self.hdc {
337            cmd.push(ARG_HDC.to_string());
338            cmd.push(hdc.display().to_string());
339        }
340        if let Some(hdd) = &self.hdd {
341            cmd.push(ARG_HDD.to_string());
342            cmd.push(hdd.display().to_string());
343        }
344        if let Some(cdrom) = &self.cdrom {
345            cmd.push(ARG_CDROM.to_string());
346            cmd.push(cdrom.display().to_string());
347        }
348        if let Some(blockdevs) = &self.blockdev {
349            for blockdev in blockdevs {
350                cmd.append(&mut blockdev.to_command());
351            }
352        }
353        if let Some(drives) = &self.drive {
354            for drive in drives {
355                cmd.append(&mut drive.to_command());
356            }
357        }
358        if let Some(mdtblock) = &self.mdtblock {
359            cmd.push(ARG_MTDBLOCK.to_string());
360            cmd.push(mdtblock.display().to_string());
361        }
362        if let Some(sd) = &self.sd {
363            cmd.push(ARG_SD.to_string());
364            cmd.push(sd.display().to_string());
365        }
366        if let Some(state) = &self.snapshot
367            && *state
368        {
369            cmd.push(ARG_SNAPSHOT.to_string());
370        }
371        if let Some(fsdev) = &self.fsdev {
372            cmd.append(&mut fsdev.to_command());
373        }
374        if let Some(virtfs) = &self.virtfs {
375            cmd.append(&mut virtfs.to_command());
376        }
377        if let Some(iscsi) = &self.iscsi {
378            cmd.append(&mut iscsi.to_command());
379        }
380        if let Some(state) = &self.usb
381            && *state
382        {
383            cmd.push(ARG_USB.to_string());
384        }
385        if let Some(usbdevice) = &self.usbdevice {
386            cmd.append(&mut usbdevice.to_command());
387        }
388        if let Some(display) = &self.display {
389            cmd.append(&mut display.to_command());
390        }
391        if let Some(state) = &self.nographic
392            && *state
393        {
394            cmd.push(ARG_NOGRAPHIC.to_string());
395        }
396        if let Some(spice) = &self.spice {
397            cmd.append(&mut spice.to_command());
398        }
399        if let Some(vga) = &self.vga {
400            cmd.append(&mut vga.to_command());
401        }
402        if let Some(full_screen) = &self.full_screen
403            && *full_screen
404        {
405            cmd.push(ARG_FULL_SCREEN.to_string());
406        }
407        if let Some((w, h, d)) = &self.g {
408            cmd.push(ARG_G.to_string());
409            let mut dimensions = format!("{}x{}", w, h);
410
411            if let Some(d) = d {
412                dimensions.push_str(format!("x{}", &d.to_string()).as_str());
413            }
414            cmd.push(dimensions);
415        }
416        if let Some(vnc) = &self.vnc {
417            cmd.append(&mut vnc.to_command());
418        }
419        if let Some(win2k_hack) = &self.win2k_hack
420            && *win2k_hack
421        {
422            cmd.push(ARG_WIN2K_HACK.to_string());
423        }
424        if let Some(no_fd_bootchk) = &self.no_fd_bootchk
425            && *no_fd_bootchk
426        {
427            cmd.push(ARG_NO_FD_BOOTCHK.to_string());
428        }
429        if let Some(acpitable) = &self.acpitable {
430            cmd.append(&mut acpitable.to_command());
431        }
432        if let Some(smbioss) = &self.smbios {
433            for smbios in smbioss {
434                cmd.append(&mut smbios.to_command());
435            }
436        }
437        if let Some(netdevs) = &self.netdev {
438            for netdev in netdevs {
439                cmd.append(&mut netdev.to_command());
440            }
441        }
442        if let Some(chardevs) = &self.chardev {
443            for chardev in chardevs {
444                cmd.append(&mut chardev.to_command());
445            }
446        }
447        if let Some(tpmdev) = &self.tpmdev {
448            cmd.append(&mut tpmdev.to_command());
449        }
450        if let Some(bios) = &self.bios {
451            cmd.push(ARG_BIOS.to_string());
452            cmd.push(bios.display().to_string());
453        }
454        if let Some(pflash) = &self.pflash {
455            cmd.push(ARG_PFLASH.to_string());
456            cmd.push(pflash.display().to_string());
457        }
458        if let Some(kernel) = &self.kernel {
459            cmd.push(ARG_KERNEL.to_string());
460            cmd.push(kernel.display().to_string());
461        }
462        if let Some(shim) = &self.shim {
463            cmd.push(ARG_SHIM.to_string());
464            cmd.push(shim.display().to_string());
465        }
466        if let Some(append) = &self.append {
467            cmd.push(ARG_APPEND.to_string());
468            cmd.push(append.as_ref().to_string());
469        }
470        if let Some(initrd) = &self.initrd {
471            cmd.push(ARG_INITRD.to_string());
472            cmd.push(initrd.display().to_string());
473        }
474        if let Some(dtb) = &self.dtb {
475            cmd.push(ARG_DTB.to_string());
476            cmd.push(dtb.display().to_string());
477        }
478        if let Some(compact) = &self.compact {
479            cmd.append(&mut compact.to_command());
480        }
481        if let Some(fw_cfg) = &self.fw_cfg {
482            cmd.append(&mut fw_cfg.to_command());
483        }
484        if let Some(serial) = &self.serial {
485            cmd.push(ARG_SERIAL.to_string());
486            cmd.append(&mut serial.to_args());
487        }
488        if let Some(parallels) = &self.parallel {
489            for parallel in parallels {
490                cmd.push(ARG_PARALLEL.to_string());
491                cmd.append(&mut parallel.to_args());
492            }
493        }
494        if let Some(monitor) = &self.monitor {
495            cmd.push(ARG_MONITOR.to_string());
496            cmd.append(&mut monitor.to_command());
497        }
498        if let Some(qmp) = &self.qmp {
499            cmd.push(ARG_QMP.to_string());
500            cmd.append(&mut qmp.to_command());
501        }
502        if let Some(qmp_pretty) = &self.qmp_pretty {
503            cmd.push(ARG_QMP_PRETTY.to_string());
504            cmd.append(&mut qmp_pretty.to_command());
505        }
506        if let Some(mons) = &self.mon {
507            for mon in mons {
508                cmd.append(&mut mon.to_command());
509            }
510        }
511        if let Some(debugcon) = &self.debugcon {
512            cmd.push(ARG_DEBUGCON.to_string());
513            cmd.append(&mut debugcon.to_command());
514        }
515        if let Some(pidfile) = &self.pidfile {
516            cmd.push(ARG_PIDFILE.to_string());
517            cmd.push(pidfile.display().to_string());
518        }
519        if let Some(preconfig) = &self.preconfig
520            && *preconfig
521        {
522            cmd.push(ARG_PRECONFIG.to_string());
523        }
524        if let Some(s) = &self.big_s
525            && *s
526        {
527            cmd.push(ARG_BIG_S.to_string());
528        }
529        if let Some(overcommit) = &self.overcommit {
530            cmd.append(&mut overcommit.to_command());
531        }
532        if let Some(gdb) = &self.gdb {
533            cmd.push(ARG_GDB.to_string());
534            cmd.append(&mut gdb.to_command());
535        }
536        if let Some(s) = &self.s
537            && *s
538        {
539            cmd.push(ARG_LITTLE_S.to_string());
540        }
541        if let Some(d) = &self.d {
542            cmd.push(ARG_LITTLE_D.to_string());
543            cmd.push(d.join(DELIM_COMMA));
544        }
545        if let Some(big_d) = &self.big_d {
546            cmd.push(ARG_BIG_D.to_string());
547            cmd.push(big_d.display().to_string());
548        }
549        if let Some(dfilter) = &self.dfilter {
550            cmd.push("-dfilter".to_string());
551            cmd.push(dfilter.join(DELIM_COMMA));
552        }
553        if let Some(seed) = &self.seed {
554            cmd.push(ARG_SEED.to_string());
555            cmd.push(seed.to_string());
556        }
557        if let Some(l) = &self.big_l {
558            cmd.push(ARG_L.to_string());
559            cmd.push(l.display().to_string());
560        }
561        if let Some(enable_kvm) = &self.enable_kvm
562            && *enable_kvm
563        {
564            cmd.push(ARG_ENABLE_KVM.to_string());
565        }
566        if let Some(xen_id) = &self.xen_id {
567            cmd.push(ARG_XEN_ID.to_string());
568            cmd.push(xen_id.to_string());
569        }
570        if let Some(xen_attach) = &self.xen_attach
571            && *xen_attach
572        {
573            cmd.push(ARG_XEN_ATTACH.to_string());
574        }
575        if let Some(xen_domid_restrict) = &self.xen_domid_restrict
576            && *xen_domid_restrict
577        {
578            cmd.push(ARG_XEN_DOMID_RESTRICT.to_string());
579        }
580        if let Some(no_reboot) = &self.no_reboot
581            && *no_reboot
582        {
583            cmd.push(ARG_NO_REBOOT.to_string());
584        }
585        if let Some(no_shutdown) = &self.no_shutdown
586            && *no_shutdown
587        {
588            cmd.push(ARG_NO_SHUTDOWN.to_string());
589        }
590        if let Some(action) = &self.action {
591            cmd.append(&mut action.to_command());
592        }
593        if let Some(loadvm) = &self.loadvm {
594            cmd.push(ARG_LOADVM.to_string());
595            cmd.push(loadvm.to_string());
596        }
597        if let Some(daemonize) = &self.daemonize
598            && *daemonize
599        {
600            cmd.push(ARG_DAEMONIZE.to_string());
601        }
602        if let Some(option_rom) = &self.option_rom {
603            cmd.push(ARG_OPTION_ROM.to_string());
604            cmd.push(option_rom.display().to_string());
605        }
606        if let Some(rtc) = &self.rtc {
607            cmd.append(&mut rtc.to_command());
608        }
609        if let Some(icount) = &self.icount {
610            cmd.append(&mut icount.to_command());
611        }
612        if let Some(watchdog_action) = &self.watchdog_action {
613            cmd.push("-watchdog-action".to_string());
614            cmd.push(watchdog_action.to_arg().to_string());
615        }
616        if let Some(echr) = &self.echr {
617            cmd.push(ARG_ECHR.to_string());
618            cmd.push(echr.to_string());
619        }
620        if let Some(incomings) = &self.incoming {
621            for incoming in incomings {
622                cmd.append(&mut incoming.to_command());
623            }
624        }
625        if let Some(only_migratable) = &self.only_migratable
626            && *only_migratable
627        {
628            cmd.push(ARG_ONLY_MIGRATABLE.to_string());
629        }
630        if let Some(nodefaults) = &self.nodefaults
631            && *nodefaults
632        {
633            cmd.push(ARG_NODEFAULTS.to_string());
634        }
635        if let Some(sandbox) = &self.sandbox {
636            cmd.append(&mut sandbox.to_command());
637        }
638        if let Some(readconfig) = &self.readconfig {
639            cmd.push(ARG_READCONFIG.to_string());
640            cmd.push(readconfig.display().to_string());
641        }
642        if let Some(no_user_config) = &self.no_user_config
643            && *no_user_config
644        {
645            cmd.push(ARG_NO_USER_CONFIG.to_string());
646        }
647        if let Some(trace) = &self.trace {
648            cmd.append(&mut trace.to_command());
649        }
650        if let Some(plugin) = &self.plugin {
651            cmd.append(&mut plugin.to_command());
652        }
653        if let Some(run_with) = &self.run_with {
654            cmd.append(&mut run_with.to_command());
655        }
656        if let Some(runas) = &self.runas {
657            cmd.push(runas.to_string());
658        }
659        if let Some(chroot) = &self.chroot {
660            cmd.push(chroot.display().to_string());
661        }
662        if let Some(msg) = &self.msg {
663            cmd.append(&mut msg.to_command());
664        }
665        if let Some(dump_vmstate) = &self.dump_vmstate {
666            cmd.push(ARG_DUMP_VMSTATE.to_string());
667            cmd.push(dump_vmstate.display().to_string());
668        }
669        if let Some(enable_sync_profile) = &self.enable_sync_profile
670            && *enable_sync_profile
671        {
672            cmd.push(ARG_ENABLE_SYNC_PROFILE.to_string());
673        }
674        if let Some(perfmap) = &self.perfmap {
675            cmd.push(ARG_PERFMAP.to_string());
676            cmd.push(perfmap.display().to_string());
677        }
678        if let Some(jitdump) = &self.jitdump {
679            cmd.push(ARG_JITDUMP.to_string());
680            cmd.push(jitdump.display().to_string());
681        }
682        if let Some(objects) = &self.object {
683            for object in objects {
684                cmd.append(&mut object.to_command());
685            }
686        }
687        cmd
688    }
689}
690
691pub type QemuInstanceForX86_64 = QemuInstanceBase<MachineX86_64, CpuX86>;
692pub type QemuInstanceForAarch64 = QemuInstanceBase<MachineAarch64, CpuAarch64>;
693
694pub struct QUuid {}
695
696impl TypedUuidKind for QUuid {
697    fn tag() -> TypedUuidTag {
698        // Tags are required to be ASCII identifiers, with underscores
699        // and dashes also supported. The validity of a tag can be checked
700        // at compile time by assigning it to a const, like so:
701        const TAG: TypedUuidTag = TypedUuidTag::new("my_kind");
702        TAG
703    }
704}
705
706#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
707pub struct QDateTime(DateTime<Utc>);
708
709impl Arbitrary for QDateTime {
710    type Parameters = ();
711    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
712        let dt = Utc.with_ymd_and_hms(1984, 10, 22, 0, 1, 5).unwrap();
713        Just(QDateTime(dt))
714    }
715
716    type Strategy = proptest::strategy::Just<Self>;
717}
718
719#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
720pub struct QIpv4Net {
721    ip: ipnet::Ipv4Net,
722}
723
724impl Arbitrary for QIpv4Net {
725    type Parameters = ();
726    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
727        todo!()
728    }
729
730    type Strategy = proptest::strategy::Just<Self>;
731}
732
733#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
734pub struct QIpv6Net {
735    ip: ipnet::Ipv6Net,
736}
737
738impl Arbitrary for QIpv6Net {
739    type Parameters = ();
740    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
741        todo!()
742    }
743
744    type Strategy = proptest::strategy::Just<Self>;
745}