flowey_lib_hvlite/
run_vmm_perf.rs1use flowey::node::prelude::*;
7
8#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
9pub enum VmmPerfProfile {
10 BootTime,
11 Fio,
12 Iperf3,
13}
14
15impl VmmPerfProfile {
16 pub fn all() -> Vec<Self> {
17 vec![Self::BootTime, Self::Fio, Self::Iperf3]
18 }
19
20 fn cli_name(self) -> &'static str {
21 match self {
22 Self::BootTime => "boot-time",
23 Self::Fio => "fio",
24 Self::Iperf3 => "iperf3",
25 }
26 }
27}
28
29#[derive(Clone, Debug, Serialize, Deserialize)]
30pub struct VmmPerfRunOutput {
31 pub results_dir: PathBuf,
32 pub success: bool,
33 pub exit_code: Option<i32>,
34}
35
36flowey_request! {
37 pub struct Request {
38 pub runner: ReadVar<crate::build_vmm_perf::VmmPerfOutput>,
39 pub openvmm: ReadVar<crate::build_openvmm::OpenvmmOutput>,
40 pub firmware: ReadVar<PathBuf>,
41 pub runtime_archive: ReadVar<PathBuf>,
42 pub output_dir: ReadVar<PathBuf>,
43 pub temp_dir: Option<ReadVar<PathBuf>>,
44 pub profiles: Vec<VmmPerfProfile>,
45 pub vm_sizes_json: Option<String>,
46 pub parameters_json: Option<String>,
47 pub pre_run_deps: Vec<ReadVar<SideEffect>>,
49 pub output: WriteVar<VmmPerfRunOutput>,
50 }
51}
52
53new_simple_flow_node!(struct Node);
54
55impl SimpleFlowNode for Node {
56 type Request = Request;
57
58 fn imports(_ctx: &mut ImportCtx<'_>) {}
59
60 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
61 let Request {
62 runner,
63 openvmm,
64 firmware,
65 runtime_archive,
66 output_dir,
67 temp_dir,
68 profiles,
69 vm_sizes_json,
70 parameters_json,
71 pre_run_deps,
72 output,
73 } = request;
74
75 ctx.emit_rust_step("run VMM.Perf", |ctx| {
76 pre_run_deps.claim(ctx);
77 let runner = runner.claim(ctx);
78 let openvmm = openvmm.claim(ctx);
79 let firmware = firmware.claim(ctx);
80 let runtime_archive = runtime_archive.claim(ctx);
81 let output_dir = output_dir.claim(ctx);
82 let temp_dir = temp_dir.map(|temp_dir| temp_dir.claim(ctx));
83 let output = output.claim(ctx);
84
85 move |rt| {
86 let runner = match rt.read(runner) {
87 crate::build_vmm_perf::VmmPerfOutput::LinuxBin { bin, .. } => bin,
88 crate::build_vmm_perf::VmmPerfOutput::WindowsBin { exe, .. } => exe,
89 };
90 let openvmm = match rt.read(openvmm) {
91 crate::build_openvmm::OpenvmmOutput::LinuxBin { bin, .. } => bin,
92 crate::build_openvmm::OpenvmmOutput::WindowsBin { exe, .. } => exe,
93 };
94 let firmware = rt.read(firmware);
95 let runtime_archive = rt.read(runtime_archive);
96 let output_dir = rt.read(output_dir).absolute()?;
97 let temp_dir = temp_dir
98 .map(|temp_dir| rt.read(temp_dir).absolute())
99 .transpose()?;
100
101 runner.make_executable()?;
102 openvmm.make_executable()?;
103 fs_err::create_dir_all(&output_dir)?;
104 if let Some(temp_dir) = &temp_dir {
105 fs_err::create_dir_all(temp_dir)?;
106 }
107
108 let mut args = vec![
109 "--openvmm".to_string(),
110 openvmm.display().to_string(),
111 "--firmware".to_string(),
112 firmware.display().to_string(),
113 "--runtime-archive".to_string(),
114 runtime_archive.display().to_string(),
115 "--output-dir".to_string(),
116 output_dir.display().to_string(),
117 ];
118 if let Some(temp_dir) = &temp_dir {
119 args.push("--temp-dir".into());
120 args.push(temp_dir.display().to_string());
121 }
122 for profile in &profiles {
123 args.push("--profile".into());
124 args.push(profile.cli_name().into());
125 }
126 if let Some(vm_sizes_json) = &vm_sizes_json {
127 args.push("--vm-sizes-json".into());
128 args.push(vm_sizes_json.clone());
129 }
130 if let Some(parameters_json) = ¶meters_json {
131 args.push("--parameters-json".into());
132 args.push(parameters_json.clone());
133 }
134
135 let process = flowey::shell_cmd!(rt, "{runner} {args...}")
136 .ignore_status()
137 .output()?;
138 if !process.stdout.is_empty() {
139 log::info!("{}", String::from_utf8_lossy(&process.stdout));
140 }
141 if !process.stderr.is_empty() {
142 log::warn!("{}", String::from_utf8_lossy(&process.stderr));
143 }
144
145 rt.write(
146 output,
147 &VmmPerfRunOutput {
148 results_dir: output_dir,
149 success: process.status.success(),
150 exit_code: process.status.code(),
151 },
152 );
153 Ok(())
154 }
155 });
156
157 Ok(())
158 }
159}