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