qemu_command_builder/
lib.rs

1pub mod accel;
2pub mod acpitable;
3pub mod action;
4pub mod addfs;
5pub mod audio;
6pub mod audiodev;
7pub mod blockdev;
8pub mod boot;
9pub mod chardev;
10pub mod common;
11pub mod compact;
12pub mod cpu;
13pub mod cpu_flags;
14pub mod cpu_type;
15pub mod device;
16pub mod display;
17pub mod drive;
18pub mod fsdev;
19pub mod fw_cfg;
20pub mod global;
21pub mod icount;
22pub mod incoming;
23pub mod iscsi;
24pub mod machine;
25pub mod machine_type;
26pub mod memory;
27pub mod mon;
28pub mod msg;
29pub mod name;
30pub mod netdev;
31pub mod numa;
32pub mod object;
33pub mod overcommit;
34pub mod plugin;
35pub mod rtc;
36pub mod runwith;
37pub mod sandbox;
38pub mod serial;
39pub mod set;
40pub mod smbios;
41pub mod smp;
42pub mod spice;
43pub mod to_command;
44pub mod tpmdev;
45pub mod trace;
46pub mod usb;
47pub mod vga;
48pub mod virtfs;
49pub mod vnc;
50
51use std::path::PathBuf;
52
53use bon::Builder;
54
55use crate::accel::Accel;
56use crate::acpitable::AcpiTable;
57use crate::action::{Action, WatchdogAction};
58use crate::addfs::AddFd;
59use crate::audio::Audio;
60use crate::audiodev::AudioDev;
61use crate::blockdev::BlockDev;
62use crate::boot::Boot;
63use crate::chardev::CharDev;
64use crate::compact::Compact;
65use crate::cpu::CpuX86;
66use crate::cpu_type::CpuTypeAarch64;
67use crate::device::Device;
68use crate::display::QemuDisplay;
69use crate::drive::Drive;
70use crate::fsdev::FsDev;
71use crate::fw_cfg::FwCfg;
72use crate::global::Global;
73use crate::icount::Icount;
74use crate::incoming::Incoming;
75use crate::iscsi::Iscsi;
76use crate::machine::{MachineForAarch64, MachineForX86};
77use crate::memory::Memory;
78use crate::mon::Mon;
79use crate::msg::Msg;
80use crate::name::Name;
81use crate::netdev::NetDev;
82use crate::numa::NUMA;
83use crate::object::Object;
84use crate::overcommit::Overcommit;
85use crate::plugin::Plugin;
86use crate::rtc::Rtc;
87use crate::runwith::RunWith;
88use crate::sandbox::Sandbox;
89use crate::serial::SpecialDevice;
90use crate::set::Set;
91use crate::smbios::Smbios;
92use crate::smp::SMP;
93use crate::spice::Spice;
94use crate::to_command::{ToArg, ToCommand};
95use crate::tpmdev::TpmDev;
96use crate::trace::Trace;
97use crate::usb::USBDevice;
98use crate::vga::VGA;
99use crate::virtfs::Virtfs;
100use crate::vnc::VNC;
101
102#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
103pub struct QemuInstanceBase<M, C> {
104    pub qemu_binary: PathBuf,
105
106    pub machine: Option<M>,
107    #[builder(into)]
108    pub cpu: Option<C>,
109
110    pub accel: Option<Accel>,
111    pub smp: Option<SMP>,
112    pub numa: Option<Vec<NUMA>>,
113    pub add_fd: Option<AddFd>,
114    pub set: Option<Vec<Set>>,
115    pub global: Option<Vec<Global>>,
116    pub boot: Option<Boot>,
117    pub m: Option<Memory>,
118    pub mem_path: Option<PathBuf>,
119    pub mem_prealloc: Option<bool>,
120    pub k: Option<String>,
121    pub audio: Option<Audio>,
122    pub audiodev: Option<AudioDev>,
123    pub device: Option<Vec<Device>>,
124    pub name: Option<Name>,
125    pub uuid: Option<String>,
126    pub fda: Option<PathBuf>,
127    pub fdb: Option<PathBuf>,
128    pub hda: Option<PathBuf>,
129    pub hdb: Option<PathBuf>,
130    pub hdc: Option<PathBuf>,
131    pub hdd: Option<PathBuf>,
132    pub cdrom: Option<PathBuf>,
133    pub blockdev: Option<Vec<BlockDev>>,
134    pub drive: Option<Vec<Drive>>,
135    pub mdtblock: Option<PathBuf>,
136    pub sd: Option<PathBuf>,
137    pub snapshot: Option<bool>,
138    pub fsdev: Option<FsDev>,
139    pub virtfs: Option<Virtfs>,
140    pub iscsi: Option<Iscsi>,
141    pub usb: Option<bool>,
142    pub usbdevice: Option<USBDevice>,
143    pub display: Option<QemuDisplay>,
144    pub nographic: Option<bool>,
145    pub spice: Option<Spice>,
146    pub vga: Option<VGA>,
147    pub full_screen: Option<bool>,
148    pub g: Option<(usize, usize, Option<usize>)>,
149    pub vnc: Option<VNC>,
150    pub win2k_hack: Option<bool>,
151    pub no_fd_bootchk: Option<bool>,
152    pub acpitable: Option<AcpiTable>,
153    pub smbios: Option<Vec<Smbios>>,
154    pub netdev: Option<Vec<NetDev>>,
155    pub chardev: Option<Vec<CharDev>>,
156    pub tpmdev: Option<TpmDev>,
157    pub bios: Option<PathBuf>,
158    pub pflash: Option<PathBuf>,
159    pub kernel: Option<PathBuf>,
160    pub shim: Option<PathBuf>,
161    pub append: Option<String>,
162    pub initrd: Option<PathBuf>,
163    pub dtb: Option<PathBuf>,
164    pub compact: Option<Compact>,
165    pub fw_cfg: Option<FwCfg>,
166    pub serial: Option<SpecialDevice>,
167    pub parallel: Option<Vec<SpecialDevice>>,
168    pub monitor: Option<SpecialDevice>,
169    pub qmp: Option<SpecialDevice>,
170    pub qmp_pretty: Option<SpecialDevice>,
171    pub mon: Option<Vec<Mon>>,
172    pub debugcon: Option<CharDev>,
173    pub pidfile: Option<PathBuf>,
174    pub preconfig: Option<bool>,
175    pub big_s: Option<bool>,
176    pub overcommit: Option<Overcommit>,
177    pub gdb: Option<SpecialDevice>,
178    pub s: Option<bool>,
179    pub d: Option<Vec<String>>,
180    pub big_d: Option<PathBuf>,
181    pub dfilter: Option<Vec<String>>,
182    pub seed: Option<usize>,
183    pub big_l: Option<PathBuf>,
184    pub enable_kvm: Option<bool>,
185    pub xen_id: Option<String>,
186    pub xen_attach: Option<bool>,
187    pub xen_domid_restrict: Option<bool>,
188    pub no_reboot: Option<bool>,
189    pub no_shutdown: Option<bool>,
190    pub action: Option<Action>,
191    pub loadvm: Option<String>,
192    pub daemonize: Option<bool>,
193    pub option_rom: Option<PathBuf>,
194    pub rtc: Option<Rtc>,
195    pub icount: Option<Icount>,
196    pub watchdog_action: Option<WatchdogAction>,
197    pub echr: Option<String>,
198    pub incoming: Option<Vec<Incoming>>,
199    pub only_migratable: Option<bool>,
200    pub nodefaults: Option<bool>,
201    pub sandbox: Option<Sandbox>,
202    pub readconfig: Option<PathBuf>,
203    pub no_user_config: Option<bool>,
204    pub trace: Option<Trace>,
205    pub plugin: Option<Plugin>,
206    pub run_with: Option<RunWith>,
207    pub msg: Option<Msg>,
208    pub dump_vmstate: Option<PathBuf>,
209    pub enable_sync_profile: Option<bool>,
210    pub perfmap: Option<PathBuf>,
211    pub jitdump: Option<PathBuf>,
212    pub object: Option<Vec<Object>>,
213}
214
215impl<M: ToCommand, C: ToCommand> ToCommand for QemuInstanceBase<M, C> {
216    fn to_command(&self) -> Vec<String> {
217        let mut cmd = vec![];
218
219        cmd.push(self.qemu_binary.display().to_string());
220
221        if let Some(machine) = &self.machine {
222            cmd.append(&mut machine.to_command());
223        }
224        if let Some(cpu) = &self.cpu {
225            cmd.append(&mut cpu.to_command());
226        }
227        if let Some(accel) = &self.accel {
228            cmd.append(&mut accel.to_command());
229        }
230        if let Some(smp) = &self.smp {
231            cmd.append(&mut smp.to_command());
232        }
233        if let Some(numas) = &self.numa {
234            for numa in numas {
235                cmd.append(&mut numa.to_command());
236            }
237        }
238        if let Some(add_fd) = &self.add_fd {
239            cmd.append(&mut add_fd.to_command());
240        }
241        if let Some(sets) = &self.set {
242            for set in sets {
243                cmd.append(&mut set.to_command());
244            }
245        }
246        if let Some(globals) = &self.global {
247            for global in globals {
248                cmd.append(&mut global.to_command());
249            }
250        }
251        if let Some(boot) = &self.boot {
252            cmd.append(&mut boot.to_command());
253        }
254        if let Some(m) = &self.m {
255            cmd.append(&mut m.to_command());
256        }
257        if let Some(path) = &self.mem_path {
258            cmd.push("-mem-path".to_string());
259            cmd.push(path.display().to_string());
260        }
261        if let Some(state) = self.mem_prealloc
262            && state
263        {
264            cmd.push("-mem-prealloc".to_string());
265        }
266        if let Some(lang) = &self.k {
267            cmd.push("-k".to_string());
268            cmd.push(lang.to_string());
269        }
270        if let Some(audio) = &self.audio {
271            cmd.append(&mut audio.to_command());
272        }
273        if let Some(audiodev) = &self.audiodev {
274            cmd.append(&mut audiodev.to_command());
275        }
276        if let Some(devices) = &self.device {
277            for device in devices {
278                cmd.append(&mut device.to_command());
279            }
280        }
281        if let Some(name) = &self.name {
282            cmd.append(&mut name.to_command());
283        }
284        if let Some(uuid) = &self.uuid {
285            cmd.push("-uuid".to_string());
286            cmd.push(uuid.to_string());
287        }
288        if let Some(fda) = &self.fda {
289            cmd.push("-fda".to_string());
290            cmd.push(fda.display().to_string());
291        }
292        if let Some(fdb) = &self.fdb {
293            cmd.push("-fdb".to_string());
294            cmd.push(fdb.display().to_string());
295        }
296        if let Some(hda) = &self.hda {
297            cmd.push("-hda".to_string());
298            cmd.push(hda.display().to_string());
299        }
300        if let Some(hdb) = &self.hdb {
301            cmd.push("-hdb".to_string());
302            cmd.push(hdb.display().to_string());
303        }
304        if let Some(hdc) = &self.hdc {
305            cmd.push("-hdc".to_string());
306            cmd.push(hdc.display().to_string());
307        }
308        if let Some(hdd) = &self.hdd {
309            cmd.push("-hdd".to_string());
310            cmd.push(hdd.display().to_string());
311        }
312        if let Some(cdrom) = &self.cdrom {
313            cmd.push("-cdrom".to_string());
314            cmd.push(cdrom.display().to_string());
315        }
316        if let Some(blockdevs) = &self.blockdev {
317            for blockdev in blockdevs {
318                cmd.append(&mut blockdev.to_command());
319            }
320        }
321        if let Some(drives) = &self.drive {
322            for drive in drives {
323                cmd.append(&mut drive.to_command());
324            }
325        }
326        if let Some(mdtblock) = &self.mdtblock {
327            cmd.push("-mtdblock".to_string());
328            cmd.push(mdtblock.display().to_string());
329        }
330        if let Some(sd) = &self.sd {
331            cmd.push("-sd".to_string());
332            cmd.push(sd.display().to_string());
333        }
334        if let Some(state) = &self.snapshot
335            && *state
336        {
337            cmd.push("-snapshot".to_string());
338        }
339        if let Some(fsdev) = &self.fsdev {
340            cmd.append(&mut fsdev.to_command());
341        }
342        if let Some(virtfs) = &self.virtfs {
343            cmd.append(&mut virtfs.to_command());
344        }
345        if let Some(iscsi) = &self.iscsi {
346            cmd.append(&mut iscsi.to_command());
347        }
348        if let Some(state) = &self.usb
349            && *state
350        {
351            cmd.push("-usb".to_string());
352        }
353        if let Some(usbdevice) = &self.usbdevice {
354            cmd.append(&mut usbdevice.to_command());
355        }
356        if let Some(display) = &self.display {
357            cmd.append(&mut display.to_command());
358        }
359        if let Some(state) = &self.nographic
360            && *state
361        {
362            cmd.push("-nographic".to_string());
363        }
364        if let Some(spice) = &self.spice {
365            cmd.append(&mut spice.to_command());
366        }
367        if let Some(vga) = &self.vga {
368            cmd.append(&mut vga.to_command());
369        }
370        if let Some(full_screen) = &self.full_screen
371            && *full_screen
372        {
373            cmd.push("-full-screen".to_string());
374        }
375        if let Some((w, h, d)) = &self.g {
376            cmd.push("-g".to_string());
377            let mut dimensions = format!("{}x{}", w, h);
378
379            if let Some(d) = d {
380                dimensions.push_str(format!("x{}", &d.to_string()).as_str());
381            }
382            cmd.push(dimensions);
383        }
384        if let Some(vnc) = &self.vnc {
385            cmd.append(&mut vnc.to_command());
386        }
387        if let Some(win2k_hack) = &self.win2k_hack
388            && *win2k_hack
389        {
390            cmd.push("-win2k-hack".to_string());
391        }
392        if let Some(no_fd_bootchk) = &self.no_fd_bootchk
393            && *no_fd_bootchk
394        {
395            cmd.push("-no-fd-bootchk".to_string());
396        }
397        if let Some(acpitable) = &self.acpitable {
398            cmd.append(&mut acpitable.to_command());
399        }
400        if let Some(smbioss) = &self.smbios {
401            for smbios in smbioss {
402                cmd.append(&mut smbios.to_command());
403            }
404        }
405        if let Some(netdevs) = &self.netdev {
406            for netdev in netdevs {
407                cmd.append(&mut netdev.to_command());
408            }
409        }
410        if let Some(chardevs) = &self.chardev {
411            for chardev in chardevs {
412                cmd.append(&mut chardev.to_command());
413            }
414        }
415        if let Some(tpmdev) = &self.tpmdev {
416            cmd.append(&mut tpmdev.to_command());
417        }
418        if let Some(bios) = &self.bios {
419            cmd.push("-bios".to_string());
420            cmd.push(bios.display().to_string());
421        }
422        if let Some(pflash) = &self.pflash {
423            cmd.push("-pflash".to_string());
424            cmd.push(pflash.display().to_string());
425        }
426        if let Some(kernel) = &self.kernel {
427            cmd.push("-kernel".to_string());
428            cmd.push(kernel.display().to_string());
429        }
430        if let Some(shim) = &self.shim {
431            cmd.push("-shim".to_string());
432            cmd.push(shim.display().to_string());
433        }
434        if let Some(append) = &self.append {
435            cmd.push("-append".to_string());
436            cmd.push(append.clone());
437        }
438        if let Some(initrd) = &self.initrd {
439            cmd.push("-initrd".to_string());
440            cmd.push(initrd.display().to_string());
441        }
442        if let Some(dtb) = &self.dtb {
443            cmd.push("-dtb".to_string());
444            cmd.push(dtb.display().to_string());
445        }
446        if let Some(compact) = &self.compact {
447            cmd.append(&mut compact.to_command());
448        }
449        if let Some(fw_cfg) = &self.fw_cfg {
450            cmd.append(&mut fw_cfg.to_command());
451        }
452        if let Some(serial) = &self.serial {
453            cmd.push("-serial".to_string());
454            cmd.append(&mut serial.to_command());
455        }
456        if let Some(parallels) = &self.parallel {
457            for parallel in parallels {
458                cmd.push("-parallel".to_string());
459                cmd.append(&mut parallel.to_command());
460            }
461        }
462        if let Some(monitor) = &self.monitor {
463            cmd.push("-monitor".to_string());
464            cmd.append(&mut monitor.to_command());
465        }
466        if let Some(qmp) = &self.qmp {
467            cmd.push("-qmp".to_string());
468            cmd.append(&mut qmp.to_command());
469        }
470        if let Some(qmp_pretty) = &self.qmp_pretty {
471            cmd.push("-qmp-pretty".to_string());
472            cmd.append(&mut qmp_pretty.to_command());
473        }
474        if let Some(mons) = &self.mon {
475            for mon in mons {
476                cmd.append(&mut mon.to_command());
477            }
478        }
479        if let Some(debugcon) = &self.debugcon {
480            cmd.push("-debugcon".to_string());
481            cmd.append(&mut debugcon.to_command());
482        }
483        if let Some(pidfile) = &self.pidfile {
484            cmd.push("-pidfile".to_string());
485            cmd.push(pidfile.display().to_string());
486        }
487        if let Some(preconfig) = &self.preconfig
488            && *preconfig
489        {
490            cmd.push("--preconfig".to_string());
491        }
492        if let Some(s) = &self.big_s
493            && *s
494        {
495            cmd.push("-S".to_string());
496        }
497        if let Some(overcommit) = &self.overcommit {
498            cmd.append(&mut overcommit.to_command());
499        }
500        if let Some(gdb) = &self.gdb {
501            cmd.push("-gdb".to_string());
502            cmd.append(&mut gdb.to_command());
503        }
504        if let Some(s) = &self.s
505            && *s
506        {
507            cmd.push("-s".to_string());
508        }
509        if let Some(d) = &self.d {
510            cmd.push("-d".to_string());
511            cmd.push(d.join(","));
512        }
513        if let Some(big_d) = &self.big_d {
514            cmd.push("-D".to_string());
515            cmd.push(big_d.display().to_string());
516        }
517        if let Some(dfilter) = &self.dfilter {
518            cmd.push("-dfilter".to_string());
519            cmd.push(dfilter.join(","));
520        }
521        if let Some(seed) = &self.seed {
522            cmd.push("-seed".to_string());
523            cmd.push(seed.to_string());
524        }
525        if let Some(seed) = &self.seed {
526            cmd.push("-seed".to_string());
527            cmd.push(seed.to_string());
528        }
529        if let Some(l) = &self.big_l {
530            cmd.push("-L".to_string());
531            cmd.push(l.display().to_string());
532        }
533        if let Some(enable_kvm) = &self.enable_kvm
534            && *enable_kvm
535        {
536            cmd.push("-enable-kvm".to_string());
537        }
538        if let Some(xen_id) = &self.xen_id {
539            cmd.push("-xen-id".to_string());
540            cmd.push(xen_id.to_string());
541        }
542        if let Some(xen_attach) = &self.xen_attach
543            && *xen_attach
544        {
545            cmd.push("-xen-attach".to_string());
546        }
547        if let Some(xen_domid_restrict) = &self.xen_domid_restrict
548            && *xen_domid_restrict
549        {
550            cmd.push("-xen-domid-restrict".to_string());
551        }
552        if let Some(no_reboot) = &self.no_reboot
553            && *no_reboot
554        {
555            cmd.push("-no-reboot".to_string());
556        }
557        if let Some(no_shutdown) = &self.no_shutdown
558            && *no_shutdown
559        {
560            cmd.push("-no-shutdown".to_string());
561        }
562        if let Some(action) = &self.action {
563            cmd.append(&mut action.to_command());
564        }
565        if let Some(loadvm) = &self.loadvm {
566            cmd.push("-loadvm".to_string());
567            cmd.push(loadvm.to_string());
568        }
569        if let Some(daemonize) = &self.daemonize
570            && *daemonize
571        {
572            cmd.push("-daemonize".to_string());
573        }
574        if let Some(option_rom) = &self.option_rom {
575            cmd.push("-option-rom".to_string());
576            cmd.push(option_rom.display().to_string());
577        }
578        if let Some(rtc) = &self.rtc {
579            cmd.append(&mut rtc.to_command());
580        }
581        if let Some(icount) = &self.icount {
582            cmd.append(&mut icount.to_command());
583        }
584        if let Some(watchdog_action) = &self.watchdog_action {
585            cmd.push("-watchdog-action".to_string());
586            cmd.push(watchdog_action.to_arg().to_string());
587        }
588        if let Some(echr) = &self.echr {
589            cmd.push("-echr".to_string());
590            cmd.push(echr.to_string());
591        }
592        if let Some(incomings) = &self.incoming {
593            for incoming in incomings {
594                cmd.append(&mut incoming.to_command());
595            }
596        }
597        if let Some(only_migratable) = &self.only_migratable
598            && *only_migratable
599        {
600            cmd.push("-only-migratable".to_string());
601        }
602        if let Some(nodefaults) = &self.nodefaults
603            && *nodefaults
604        {
605            cmd.push("-nodefaults".to_string());
606        }
607        if let Some(sandbox) = &self.sandbox {
608            cmd.append(&mut sandbox.to_command());
609        }
610        if let Some(readconfig) = &self.readconfig {
611            cmd.push("-readconfig".to_string());
612            cmd.push(readconfig.display().to_string());
613        }
614        if let Some(no_user_config) = &self.no_user_config
615            && *no_user_config
616        {
617            cmd.push("-no-user-config".to_string());
618        }
619        if let Some(trace) = &self.trace {
620            cmd.append(&mut trace.to_command());
621        }
622        if let Some(plugin) = &self.plugin {
623            cmd.append(&mut plugin.to_command());
624        }
625        if let Some(run_with) = &self.run_with {
626            cmd.append(&mut run_with.to_command());
627        }
628        if let Some(msg) = &self.msg {
629            cmd.append(&mut msg.to_command());
630        }
631        if let Some(dump_vmstate) = &self.dump_vmstate {
632            cmd.push("-dump-vmstate".to_string());
633            cmd.push(dump_vmstate.display().to_string());
634        }
635        if let Some(enable_sync_profile) = &self.enable_sync_profile
636            && *enable_sync_profile
637        {
638            cmd.push("-enable-sync-profile".to_string());
639        }
640        if let Some(perfmap) = &self.perfmap {
641            cmd.push("-perfmap".to_string());
642            cmd.push(perfmap.display().to_string());
643        }
644        if let Some(jitdump) = &self.jitdump {
645            cmd.push("-jitdump".to_string());
646            cmd.push(jitdump.display().to_string());
647        }
648        if let Some(objects) = &self.object {
649            for object in objects {
650                cmd.append(&mut object.to_command());
651            }
652        }
653        cmd
654    }
655}
656
657pub type QemuInstanceForX86_64 = QemuInstanceBase<MachineForX86, CpuX86>;
658pub type QemuInstanceForAarch64 = QemuInstanceBase<MachineForAarch64, CpuTypeAarch64>;