flowey_lib_hvlite/
artifact_openhcl_igvm_from_recipe.rs1use crate::build_openhcl_igvm_from_recipe::OpenhclIgvmRecipe;
7
8pub(crate) fn recipe_to_filename(flavor: &OpenhclIgvmRecipe) -> &str {
10 match flavor {
11 OpenhclIgvmRecipe::X64 => "openhcl",
12 OpenhclIgvmRecipe::X64Devkern => "openhcl-dev",
13 OpenhclIgvmRecipe::X64TestLinuxDirect => "openhcl-direct",
14 OpenhclIgvmRecipe::X64TestLinuxDirectDevkern => "openhcl-direct-dev",
15 OpenhclIgvmRecipe::X64Cvm => "openhcl-cvm",
16 OpenhclIgvmRecipe::X64CvmDevkern => "openhcl-cvm-dev",
17 OpenhclIgvmRecipe::Aarch64 => "openhcl-aarch64",
18 OpenhclIgvmRecipe::Aarch64Devkern => "openhcl-aarch64-dev",
19 OpenhclIgvmRecipe::LocalOnlyCustom(_) => unreachable!(),
20 }
21}
22
23pub(crate) fn filename_to_recipe(filename: &str) -> Option<OpenhclIgvmRecipe> {
25 let ret = match filename {
26 "openhcl" => OpenhclIgvmRecipe::X64,
27 "openhcl-dev" => OpenhclIgvmRecipe::X64Devkern,
28 "openhcl-direct" => OpenhclIgvmRecipe::X64TestLinuxDirect,
29 "openhcl-direct-dev" => OpenhclIgvmRecipe::X64TestLinuxDirectDevkern,
30 "openhcl-cvm" => OpenhclIgvmRecipe::X64Cvm,
31 "openhcl-cvm-dev" => OpenhclIgvmRecipe::X64CvmDevkern,
32 "openhcl-aarch64" => OpenhclIgvmRecipe::Aarch64,
33 "openhcl-aarch64-dev" => OpenhclIgvmRecipe::Aarch64Devkern,
34 _ => return None,
35 };
36
37 Some(ret)
38}
39
40pub mod publish {
42 use crate::build_openhcl_igvm_from_recipe::OpenhclIgvmRecipe;
43 use crate::run_igvmfilegen::IgvmOutput;
44 use flowey::node::prelude::*;
45
46 flowey_request! {
47 pub struct Request {
48 pub openhcl_igvm_files: Vec<ReadVar<(OpenhclIgvmRecipe, IgvmOutput)>>,
49 pub artifact_dir: ReadVar<PathBuf>,
50 pub done: WriteVar<SideEffect>,
51 }
52 }
53
54 new_simple_flow_node!(struct Node);
55
56 impl SimpleFlowNode for Node {
57 type Request = Request;
58
59 fn imports(ctx: &mut ImportCtx<'_>) {
60 ctx.import::<flowey_lib_common::copy_to_artifact_dir::Node>();
61 }
62
63 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
64 let Request {
65 openhcl_igvm_files,
66 artifact_dir,
67 done,
68 } = request;
69
70 let files = ctx.emit_minor_rust_stepv("describe OpenHCL igvm artifact", |ctx| {
71 let openhcl_igvm_files = openhcl_igvm_files.claim(ctx);
72 |rt| {
73 let mut files = Vec::new();
74 for igvm in openhcl_igvm_files {
75 let (recipe, igvm) = rt.read(igvm);
76
77 let IgvmOutput {
78 igvm_bin,
79 igvm_tdx_json,
80 igvm_snp_json,
81 igvm_vbs_json,
82 ..
83 } = igvm;
84 files.push((
85 format!("{}.bin", super::recipe_to_filename(&recipe)).into(),
86 igvm_bin,
87 ));
88
89 if let Some(igvm_tdx_json) = igvm_tdx_json {
90 files.push((
91 format!("{}-tdx.json", super::recipe_to_filename(&recipe)).into(),
92 igvm_tdx_json,
93 ));
94 }
95
96 if let Some(igvm_snp_json) = igvm_snp_json {
97 files.push((
98 format!("{}-snp.json", super::recipe_to_filename(&recipe)).into(),
99 igvm_snp_json,
100 ));
101 }
102
103 if let Some(igvm_vbs_json) = igvm_vbs_json {
104 files.push((
105 format!("{}-vbs.json", super::recipe_to_filename(&recipe)).into(),
106 igvm_vbs_json,
107 ));
108 }
109 }
110 files
111 }
112 });
113
114 ctx.req(flowey_lib_common::copy_to_artifact_dir::Request {
115 debug_label: "OpenHCL igvm files".into(),
116 files,
117 artifact_dir,
118 done,
119 });
120
121 Ok(())
122 }
123 }
124}
125
126pub mod resolve {
128 use crate::build_openhcl_igvm_from_recipe::OpenhclIgvmRecipe;
129 use crate::run_igvmfilegen::IgvmOutput;
130 use flowey::node::prelude::*;
131
132 flowey_request! {
133 pub struct Request {
134 pub artifact_dir: ReadVar<PathBuf>,
135 pub igvm_files: WriteVar<Vec<(OpenhclIgvmRecipe, IgvmOutput)>>,
136 }
137 }
138
139 new_simple_flow_node!(struct Node);
140
141 impl SimpleFlowNode for Node {
142 type Request = Request;
143
144 fn imports(ctx: &mut ImportCtx<'_>) {
145 ctx.import::<flowey_lib_common::copy_to_artifact_dir::Node>();
146 }
147
148 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
149 let Request {
150 artifact_dir,
151 igvm_files,
152 } = request;
153
154 ctx.emit_rust_step("resolve OpenHCL igvm artifact", |ctx| {
155 let artifact_dir = artifact_dir.claim(ctx);
156 let igvm_files = igvm_files.claim(ctx);
157 move |rt| {
158 let artifact_dir = rt.read(artifact_dir);
159
160 let mut files = Vec::new();
161 for entry in fs_err::read_dir(&artifact_dir)? {
162 let entry = entry?;
163 if entry.file_type()?.is_dir() {
164 anyhow::bail!("unexpected folder in root");
165 }
166
167 let entry_file_name = entry
171 .file_name()
172 .into_string()
173 .map_err(|_| anyhow::anyhow!("unexpected filename"))?;
174 let entry_file_stem =
175 if let Some(file_stem) = entry_file_name.strip_suffix(".bin") {
176 file_stem
177 } else {
178 continue;
179 };
180
181 let Some(recipe) = super::filename_to_recipe(entry_file_stem) else {
182 anyhow::bail!(
183 "unexpected file in openhcl_igvm artifact folder: {}",
184 entry.path().display()
185 );
186 };
187
188 let igvm_path_file_name = super::recipe_to_filename(&recipe);
190 let igvm_tdx_json = {
191 let path = artifact_dir.join(format!("{igvm_path_file_name}-tdx.json"));
192 path.exists().then_some(path)
193 };
194 let igvm_snp_json = {
195 let path = artifact_dir.join(format!("{igvm_path_file_name}-snp.json"));
196 path.exists().then_some(path)
197 };
198 let igvm_vbs_json = {
199 let path = artifact_dir.join(format!("{igvm_path_file_name}-vbs.json"));
200 path.exists().then_some(path)
201 };
202
203 files.push((
204 recipe,
205 IgvmOutput {
206 igvm_bin: entry.path(),
207 igvm_map: None, igvm_tdx_json,
209 igvm_snp_json,
210 igvm_vbs_json,
211 },
212 ))
213 }
214
215 rt.write(igvm_files, &files);
216
217 Ok(())
218 }
219 });
220
221 Ok(())
222 }
223 }
224}