1use crate::build_openhcl_initrd::OpenhclInitrdExtraParams;
13use crate::build_openvmm_hcl::MaxTraceLevel;
14use crate::build_openvmm_hcl::OpenvmmHclBuildProfile;
15use crate::build_openvmm_hcl::OpenvmmHclFeature;
16use crate::download_openhcl_kernel_package::OpenhclKernelPackageArch;
17use crate::download_openhcl_kernel_package::OpenhclKernelPackageKind;
18use crate::download_openvmm_deps::OpenvmmDepsArch;
19use crate::download_uefi_mu_msvm::MuMsvmArch;
20use crate::run_cargo_build::BuildProfile;
21use crate::run_cargo_build::common::CommonArch;
22use crate::run_cargo_build::common::CommonPlatform;
23use crate::run_cargo_build::common::CommonTriple;
24use flowey::node::prelude::*;
25use igvmfilegen_config::ResourceType;
26use std::collections::BTreeMap;
27use std::collections::BTreeSet;
28
29#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
30pub enum OpenhclKernelPackage {
31 Main,
33 Cvm,
35 Dev,
37 CvmDev,
39 CustomLocal(PathBuf),
41}
42
43#[derive(Serialize, Deserialize, Debug, Clone)]
45pub enum Vtl0KernelType {
46 Example,
47 LocalOnlyCustom(PathBuf),
48}
49
50#[derive(Serialize, Deserialize, Clone, Debug)]
51pub enum IgvmManifestPath {
52 InTree(String),
54 LocalOnlyCustom(PathBuf),
56}
57
58#[derive(Serialize, Deserialize, Clone, Debug)]
59pub struct OpenhclIgvmRecipeDetails {
60 pub local_only: Option<OpenhclIgvmRecipeDetailsLocalOnly>,
61
62 pub igvm_manifest: IgvmManifestPath,
63 pub openhcl_kernel_package: OpenhclKernelPackage,
64 pub openvmm_hcl_features: BTreeSet<OpenvmmHclFeature>,
65 pub target: CommonTriple,
66 pub vtl0_kernel_type: Option<Vtl0KernelType>,
67 pub with_uefi: bool,
68 pub with_interactive: bool,
69 pub with_sidecar: bool,
70 pub max_trace_level: MaxTraceLevel,
71}
72
73#[derive(Serialize, Deserialize, Clone, Debug)]
74pub struct OpenhclIgvmRecipeDetailsLocalOnly {
75 pub openvmm_hcl_no_strip: bool,
76 pub openhcl_initrd_extra_params: Option<OpenhclInitrdExtraParams>,
77 pub custom_openvmm_hcl: Option<PathBuf>,
78 pub custom_openhcl_boot: Option<PathBuf>,
79 pub custom_uefi: Option<PathBuf>,
80 pub custom_kernel: Option<PathBuf>,
81 pub custom_sidecar: Option<PathBuf>,
82 pub custom_extra_rootfs: Vec<PathBuf>,
83}
84
85#[expect(clippy::large_enum_variant)]
86#[derive(Debug, Serialize, Deserialize, Clone)]
87pub enum OpenhclIgvmRecipe {
88 LocalOnlyCustom(OpenhclIgvmRecipeDetails),
89 X64,
90 X64Devkern,
91 X64TestLinuxDirect,
92 X64TestLinuxDirectDevkern,
93 X64Cvm,
94 X64CvmDevkern,
95 Aarch64,
96 Aarch64Devkern,
97}
98
99impl OpenhclIgvmRecipe {
100 pub fn recipe_details(&self, release_cfg: bool) -> OpenhclIgvmRecipeDetails {
101 let base_openvmm_hcl_features = || {
102 let mut m = BTreeSet::new();
103
104 m.insert(OpenvmmHclFeature::Tpm);
105
106 if !release_cfg {
107 m.insert(OpenvmmHclFeature::Gdb);
108 }
109
110 m
111 };
112
113 let in_repo_template = |debug_manifest: &'static str, release_manifest: &'static str| {
114 IgvmManifestPath::InTree(if release_cfg {
115 release_manifest.into()
116 } else {
117 debug_manifest.into()
118 })
119 };
120
121 let with_interactive = !release_cfg;
123
124 let max_trace_level = if release_cfg {
127 MaxTraceLevel::Debug
128 } else {
129 MaxTraceLevel::Trace
130 };
131
132 match self {
133 Self::LocalOnlyCustom(details) => details.clone(),
134 Self::X64 => OpenhclIgvmRecipeDetails {
135 local_only: None,
136 igvm_manifest: in_repo_template("openhcl-x64-dev.json", "openhcl-x64-release.json"),
137 openhcl_kernel_package: OpenhclKernelPackage::Main,
138 openvmm_hcl_features: base_openvmm_hcl_features(),
139 target: CommonTriple::X86_64_LINUX_MUSL,
140 vtl0_kernel_type: None,
141 with_uefi: true,
142 with_interactive,
143 with_sidecar: true,
144 max_trace_level,
145 },
146 Self::X64Devkern => OpenhclIgvmRecipeDetails {
147 local_only: None,
148 igvm_manifest: in_repo_template("openhcl-x64-dev.json", "openhcl-x64-release.json"),
149 openhcl_kernel_package: OpenhclKernelPackage::Dev,
150 openvmm_hcl_features: base_openvmm_hcl_features(),
151 target: CommonTriple::X86_64_LINUX_MUSL,
152 vtl0_kernel_type: None,
153 with_uefi: true,
154 with_interactive,
155 with_sidecar: true,
156 max_trace_level,
157 },
158 Self::X64CvmDevkern => OpenhclIgvmRecipeDetails {
159 local_only: None,
160 igvm_manifest: in_repo_template(
161 "openhcl-x64-cvm-dev.json",
162 "openhcl-x64-cvm-release.json",
163 ),
164 openhcl_kernel_package: OpenhclKernelPackage::CvmDev,
165 openvmm_hcl_features: base_openvmm_hcl_features(),
166 target: CommonTriple::X86_64_LINUX_MUSL,
167 vtl0_kernel_type: None,
168 with_uefi: true,
169 with_interactive,
170 with_sidecar: false,
171 max_trace_level,
172 },
173 Self::X64TestLinuxDirect => OpenhclIgvmRecipeDetails {
174 local_only: None,
175 igvm_manifest: in_repo_template(
176 "openhcl-x64-direct-dev.json",
177 "openhcl-x64-direct-release.json",
178 ),
179 openhcl_kernel_package: OpenhclKernelPackage::Main,
180 openvmm_hcl_features: base_openvmm_hcl_features(),
181 target: CommonTriple::X86_64_LINUX_MUSL,
182 vtl0_kernel_type: Some(Vtl0KernelType::Example),
183 with_uefi: false,
184 with_interactive,
185 with_sidecar: true,
186 max_trace_level,
187 },
188 Self::X64TestLinuxDirectDevkern => OpenhclIgvmRecipeDetails {
189 local_only: None,
190 igvm_manifest: in_repo_template(
191 "openhcl-x64-direct-dev.json",
192 "openhcl-x64-direct-release.json",
193 ),
194 openhcl_kernel_package: OpenhclKernelPackage::Dev,
195 openvmm_hcl_features: base_openvmm_hcl_features(),
196 target: CommonTriple::X86_64_LINUX_MUSL,
197 vtl0_kernel_type: Some(Vtl0KernelType::Example),
198 with_uefi: false,
199 with_interactive,
200 with_sidecar: true,
201 max_trace_level,
202 },
203 Self::X64Cvm => OpenhclIgvmRecipeDetails {
204 local_only: None,
205 igvm_manifest: in_repo_template(
206 "openhcl-x64-cvm-dev.json",
207 "openhcl-x64-cvm-release.json",
208 ),
209 openhcl_kernel_package: OpenhclKernelPackage::Cvm,
210 openvmm_hcl_features: base_openvmm_hcl_features(),
211 target: CommonTriple::X86_64_LINUX_MUSL,
212 vtl0_kernel_type: None,
213 with_uefi: true,
214 with_interactive,
215 with_sidecar: false,
216 max_trace_level,
217 },
218 Self::Aarch64 => OpenhclIgvmRecipeDetails {
219 local_only: None,
220 igvm_manifest: in_repo_template(
221 "openhcl-aarch64-dev.json",
222 "openhcl-aarch64-release.json",
223 ),
224 openhcl_kernel_package: OpenhclKernelPackage::Main,
225 openvmm_hcl_features: base_openvmm_hcl_features(),
226 target: CommonTriple::AARCH64_LINUX_MUSL,
227 vtl0_kernel_type: None,
228 with_uefi: true,
229 with_interactive: false, with_sidecar: false,
231 max_trace_level,
232 },
233 Self::Aarch64Devkern => OpenhclIgvmRecipeDetails {
234 local_only: None,
235 igvm_manifest: in_repo_template(
236 "openhcl-aarch64-dev.json",
237 "openhcl-aarch64-release.json",
238 ),
239 openhcl_kernel_package: OpenhclKernelPackage::Dev,
240 openvmm_hcl_features: base_openvmm_hcl_features(),
241 target: CommonTriple::AARCH64_LINUX_MUSL,
242 vtl0_kernel_type: None,
243 with_uefi: true,
244 with_interactive: false, with_sidecar: false,
246 max_trace_level,
247 },
248 }
249 }
250}
251
252flowey_request! {
253 pub struct Request {
254 pub build_profile: OpenvmmHclBuildProfile,
255 pub release_cfg: bool,
256 pub recipe: OpenhclIgvmRecipe,
257 pub custom_target: Option<CommonTriple>,
258
259 pub built_openvmm_hcl: WriteVar<crate::build_openvmm_hcl::OpenvmmHclOutput>,
260 pub built_openhcl_boot: WriteVar<crate::build_openhcl_boot::OpenhclBootOutput>,
261 pub built_openhcl_igvm: WriteVar<crate::run_igvmfilegen::IgvmOutput>,
262 pub built_sidecar: WriteVar<Option<crate::build_sidecar::SidecarOutput>>,
263 }
264}
265
266new_simple_flow_node!(struct Node);
267
268impl SimpleFlowNode for Node {
269 type Request = Request;
270
271 fn imports(ctx: &mut ImportCtx<'_>) {
272 ctx.import::<crate::build_igvmfilegen::Node>();
273 ctx.import::<crate::build_openhcl_boot::Node>();
274 ctx.import::<crate::build_openhcl_initrd::Node>();
275 ctx.import::<crate::build_openvmm_hcl::Node>();
276 ctx.import::<crate::build_sidecar::Node>();
277 ctx.import::<crate::download_openhcl_kernel_package::Node>();
278 ctx.import::<crate::download_openvmm_deps::Node>();
279 ctx.import::<crate::download_uefi_mu_msvm::Node>();
280 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
281 ctx.import::<crate::run_igvmfilegen::Node>();
282 ctx.import::<crate::run_split_debug_info::Node>();
283 }
284
285 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
286 let Request {
287 build_profile,
288 release_cfg,
289 recipe,
290 custom_target,
291 built_openvmm_hcl,
292 built_openhcl_boot,
293 built_openhcl_igvm,
294 built_sidecar,
295 } = request;
296
297 let OpenhclIgvmRecipeDetails {
298 local_only,
299 igvm_manifest,
300 openhcl_kernel_package,
301 openvmm_hcl_features,
302 target,
303 vtl0_kernel_type,
304 with_uefi,
305 with_interactive,
306 with_sidecar,
307 max_trace_level,
308 } = recipe.recipe_details(release_cfg);
309
310 let OpenhclIgvmRecipeDetailsLocalOnly {
311 openvmm_hcl_no_strip,
312 openhcl_initrd_extra_params,
313 custom_openvmm_hcl,
314 custom_openhcl_boot,
315 custom_uefi,
316 custom_kernel,
317 custom_sidecar,
318 custom_extra_rootfs,
319 } = local_only.unwrap_or(OpenhclIgvmRecipeDetailsLocalOnly {
320 openvmm_hcl_no_strip: false,
321 openhcl_initrd_extra_params: None,
322 custom_openvmm_hcl: None,
323 custom_openhcl_boot: None,
324 custom_uefi: None,
325 custom_kernel: None,
326 custom_sidecar: None,
327 custom_extra_rootfs: Vec::new(),
328 });
329
330 let target = custom_target.unwrap_or(target);
331 let arch = CommonArch::from_triple(&target.as_triple())
332 .ok_or_else(|| anyhow::anyhow!("cannot build openHCL from recipe on {target}"))?;
333
334 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
335
336 let vtl2_kernel_package_root = {
337 let arch = match arch {
338 CommonArch::X86_64 => OpenhclKernelPackageArch::X86_64,
339 CommonArch::Aarch64 => OpenhclKernelPackageArch::Aarch64,
340 };
341
342 enum DownloadOrLocal {
343 Local(PathBuf),
344 Download(OpenhclKernelPackageKind),
345 }
346
347 let download_kind = match openhcl_kernel_package {
348 OpenhclKernelPackage::Main => {
349 DownloadOrLocal::Download(OpenhclKernelPackageKind::Main)
350 }
351 OpenhclKernelPackage::Cvm => {
352 DownloadOrLocal::Download(OpenhclKernelPackageKind::Cvm)
353 }
354 OpenhclKernelPackage::Dev => {
355 DownloadOrLocal::Download(OpenhclKernelPackageKind::Dev)
356 }
357 OpenhclKernelPackage::CvmDev => {
358 DownloadOrLocal::Download(OpenhclKernelPackageKind::CvmDev)
359 }
360 OpenhclKernelPackage::CustomLocal(path) => DownloadOrLocal::Local(path),
361 };
362
363 match download_kind {
364 DownloadOrLocal::Local(path) => ReadVar::from_static(path),
365 DownloadOrLocal::Download(kind) => {
366 ctx.reqv(
367 |v| crate::download_openhcl_kernel_package::Request::GetPackage {
368 kind,
369 arch,
370 pkg: v,
371 },
372 )
373 }
374 }
375 };
376
377 let uefi_resource = with_uefi.then(|| UefiResource {
378 msvm_fd: if let Some(path) = custom_uefi {
379 ReadVar::from_static(path)
380 } else {
381 ctx.reqv(|v| crate::download_uefi_mu_msvm::Request::GetMsvmFd {
382 arch: match arch {
383 CommonArch::X86_64 => MuMsvmArch::X86_64,
384 CommonArch::Aarch64 => MuMsvmArch::Aarch64,
385 },
386 msvm_fd: v,
387 })
388 },
389 });
390
391 let vtl0_kernel_resource = vtl0_kernel_type.map(|typ| {
392 let kernel = if let Vtl0KernelType::LocalOnlyCustom(path) = typ {
393 ReadVar::from_static(path)
394 } else {
395 match typ {
396 Vtl0KernelType::Example => ctx.reqv(|v| {
397 crate::download_openvmm_deps::Request::GetLinuxTestKernel(
398 match arch {
399 CommonArch::X86_64 => OpenvmmDepsArch::X86_64,
400 CommonArch::Aarch64 => OpenvmmDepsArch::Aarch64,
401 },
402 v,
403 )
404 }),
405 Vtl0KernelType::LocalOnlyCustom(_) => unreachable!("special cased above"),
406 }
407 };
408
409 let initrd = ctx.reqv(|v| {
410 crate::download_openvmm_deps::Request::GetLinuxTestInitrd(
411 match arch {
412 CommonArch::X86_64 => OpenvmmDepsArch::X86_64,
413 CommonArch::Aarch64 => OpenvmmDepsArch::Aarch64,
414 },
415 v,
416 )
417 });
418
419 Vtl0KernelResource { kernel, initrd }
420 });
421
422 let sidecar_bin = if with_sidecar {
424 let sidecar_bin = if let Some(path) = custom_sidecar {
425 ctx.emit_rust_stepv("set custom_sidecar", |_ctx| {
426 |_rt| {
427 let fake_dbg_path = std::env::current_dir()?
428 .join("fake_sidecar.dbg")
429 .absolute()?;
430 fs_err::write(&fake_dbg_path, "")?;
431
432 Ok(crate::build_sidecar::SidecarOutput {
433 bin: path,
434 dbg: fake_dbg_path,
435 })
436 }
437 })
438 } else {
439 ctx.reqv(|v| crate::build_sidecar::Request {
440 build_params: crate::build_sidecar::SidecarBuildParams {
441 arch,
442 profile: match build_profile {
443 OpenvmmHclBuildProfile::Debug => {
444 crate::build_sidecar::SidecarBuildProfile::Debug
445 }
446 OpenvmmHclBuildProfile::Release
447 | OpenvmmHclBuildProfile::OpenvmmHclShip => {
448 crate::build_sidecar::SidecarBuildProfile::Release
449 }
450 },
451 },
452 sidecar: v,
453 })
454 };
455 sidecar_bin.write_into(ctx, built_sidecar, Some);
456 Some(sidecar_bin)
457 } else {
458 built_sidecar.write_static(ctx, None);
459 None
460 };
461
462 let openvmm_hcl_bin = ctx.reqv(|v| {
464 crate::build_openvmm_hcl::Request {
465 build_params: crate::build_openvmm_hcl::OpenvmmHclBuildParams {
466 target: target.clone(),
467 profile: build_profile,
468 features: openvmm_hcl_features,
469 no_split_dbg_info: true,
471 max_trace_level,
472 },
473 openvmm_hcl_output: v,
474 }
475 });
476
477 let igvmfilegen_arch = match ctx.arch() {
479 FlowArch::X86_64 => CommonArch::X86_64,
480 FlowArch::Aarch64 => CommonArch::Aarch64,
481 arch => anyhow::bail!("unsupported arch {arch}"),
482 };
483
484 let igvmfilegen = ctx.reqv(|v| crate::build_igvmfilegen::Request {
485 build_params: crate::build_igvmfilegen::IgvmfilegenBuildParams {
486 target: CommonTriple::Common {
487 arch: igvmfilegen_arch,
488 platform: CommonPlatform::LinuxGnu,
489 },
490 profile: BuildProfile::Light,
491 },
492 igvmfilegen: v,
493 });
494
495 let openhcl_boot_bin = if let Some(path) = custom_openhcl_boot {
497 ctx.emit_rust_stepv("set custom_openhcl_boot", |_ctx| {
498 |_rt| {
499 let fake_dbg_path = std::env::current_dir()?.join("fake.dbg").absolute()?;
500 fs_err::write(&fake_dbg_path, "")?;
501
502 Ok(crate::build_openhcl_boot::OpenhclBootOutput {
503 bin: path,
504 dbg: fake_dbg_path,
505 })
506 }
507 })
508 } else {
509 ctx.reqv(|v| crate::build_openhcl_boot::Request {
510 build_params: crate::build_openhcl_boot::OpenhclBootBuildParams {
511 arch,
512 profile: match build_profile {
513 OpenvmmHclBuildProfile::Debug => {
514 crate::build_openhcl_boot::OpenhclBootBuildProfile::Debug
515 }
516 OpenvmmHclBuildProfile::Release
517 | OpenvmmHclBuildProfile::OpenvmmHclShip => {
518 crate::build_openhcl_boot::OpenhclBootBuildProfile::Release
519 }
520 },
521 },
522 openhcl_boot: v,
523 })
524 };
525 openhcl_boot_bin.write_into(ctx, built_openhcl_boot, |x| x);
526
527 let use_stripped_openvmm_hcl = {
528 if custom_openvmm_hcl.is_some() {
529 false
532 } else {
533 !openvmm_hcl_no_strip
534 }
535 };
536
537 let openvmm_hcl_bin = if use_stripped_openvmm_hcl {
539 let (read, write) = ctx.new_var();
540 let (read_dbg, write_dbg) = ctx.new_var();
541
542 let in_bin = openvmm_hcl_bin.map(ctx, |o| o.bin);
543 ctx.req(crate::run_split_debug_info::Request {
544 arch,
545 in_bin,
546 out_bin: write,
547 out_dbg_info: write_dbg,
548 });
549
550 read.zip(ctx, read_dbg).map(ctx, |(bin, dbg)| {
551 crate::build_openvmm_hcl::OpenvmmHclOutput {
552 bin,
553 dbg: Some(dbg),
554 }
555 })
556 } else {
557 openvmm_hcl_bin
558 };
559
560 openvmm_hcl_bin.write_into(ctx, built_openvmm_hcl, |x| x);
562
563 let initrd = {
564 let rootfs_config = [openvmm_repo_path.map(ctx, |p| p.join("openhcl/rootfs.config"))]
565 .into_iter()
566 .chain(
567 custom_extra_rootfs
568 .into_iter()
569 .map(|p| ReadVar::from_static(p)),
570 )
571 .collect();
572 let openvmm_hcl_bin = openvmm_hcl_bin.map(ctx, |o| o.bin);
573
574 ctx.reqv(|v| crate::build_openhcl_initrd::Request {
575 interactive: with_interactive,
576 arch,
577 extra_params: openhcl_initrd_extra_params,
578 rootfs_config,
579 extra_env: None,
580 kernel_package_root: vtl2_kernel_package_root.clone(),
581 bin_openhcl: openvmm_hcl_bin,
582 initrd: v,
583 })
584 };
585
586 let kernel =
587 if let Some(path) = custom_kernel {
588 ReadVar::from_static(path)
589 } else {
590 match arch {
591 CommonArch::X86_64 => vtl2_kernel_package_root
592 .map(ctx, |p| p.join("build/native/bin/x64/vmlinux")),
593 CommonArch::Aarch64 => vtl2_kernel_package_root
594 .map(ctx, |p| p.join("build/native/bin/arm64/Image")),
595 }
596 };
597
598 let resources = ctx.emit_minor_rust_stepv("enumerate igvm resources", |ctx| {
599 let initrd = initrd.claim(ctx);
600 let kernel = kernel.claim(ctx);
601 let openhcl_boot_bin = openhcl_boot_bin.claim(ctx);
602 let sidecar_bin = sidecar_bin.claim(ctx);
603 let uefi_resource = uefi_resource.claim(ctx);
604 let vtl0_kernel_resource = vtl0_kernel_resource.claim(ctx);
605 |rt| {
606 let mut resources = BTreeMap::<ResourceType, PathBuf>::new();
607 resources.insert(ResourceType::UnderhillKernel, rt.read(kernel));
608 resources.insert(ResourceType::UnderhillInitrd, rt.read(initrd).initrd);
609 resources.insert(ResourceType::OpenhclBoot, rt.read(openhcl_boot_bin).bin);
610 if let Some(sidecar_bin) = sidecar_bin {
611 resources.insert(ResourceType::UnderhillSidecar, rt.read(sidecar_bin).bin);
612 }
613 if let Some(uefi_resource) = uefi_resource {
614 uefi_resource.add_to_resources(&mut resources, rt);
615 }
616 if let Some(vtl0_kernel_resource) = vtl0_kernel_resource {
617 vtl0_kernel_resource.add_to_resources(&mut resources, rt);
618 }
619 resources
620 }
621 });
622
623 let igvmfilegen = igvmfilegen.map(ctx, |o| match o {
624 crate::build_igvmfilegen::IgvmfilegenOutput::LinuxBin { bin, dbg: _ } => bin,
625 crate::build_igvmfilegen::IgvmfilegenOutput::WindowsBin { exe, pdb: _ } => exe,
626 });
627
628 let manifest = match igvm_manifest {
629 IgvmManifestPath::InTree(path) => {
630 openvmm_repo_path.map(ctx, |p| p.join("vm/loader/manifests").join(path))
631 }
632 IgvmManifestPath::LocalOnlyCustom(p) => ReadVar::from_static(p),
633 };
634
635 ctx.req(crate::run_igvmfilegen::Request {
636 igvmfilegen,
637 manifest,
638 resources,
639 igvm: built_openhcl_igvm,
640 });
641
642 Ok(())
643 }
644}
645
646#[derive(Debug)]
647pub struct UefiResource<C = VarNotClaimed> {
648 pub msvm_fd: ReadVar<PathBuf, C>,
649}
650
651impl ClaimVar for UefiResource {
652 type Claimed = UefiResource<VarClaimed>;
653
654 fn claim(self, ctx: &mut StepCtx<'_>) -> UefiResource<VarClaimed> {
655 UefiResource {
656 msvm_fd: self.msvm_fd.claim(ctx),
657 }
658 }
659}
660
661impl UefiResource<VarClaimed> {
662 pub fn add_to_resources(
663 self,
664 resources: &mut BTreeMap<ResourceType, PathBuf>,
665 rt: &mut RustRuntimeServices<'_>,
666 ) {
667 let path = rt.read(self.msvm_fd);
668 resources.insert(ResourceType::Uefi, path);
669 }
670}
671
672pub struct Vtl0KernelResource<C = VarNotClaimed> {
673 pub kernel: ReadVar<PathBuf, C>,
674 pub initrd: ReadVar<PathBuf, C>,
675}
676
677impl ClaimVar for Vtl0KernelResource {
678 type Claimed = Vtl0KernelResource<VarClaimed>;
679
680 fn claim(self, ctx: &mut StepCtx<'_>) -> Vtl0KernelResource<VarClaimed> {
681 Vtl0KernelResource {
682 kernel: self.kernel.claim(ctx),
683 initrd: self.initrd.claim(ctx),
684 }
685 }
686}
687
688impl Vtl0KernelResource<VarClaimed> {
689 pub fn add_to_resources(
690 self,
691 resources: &mut BTreeMap<ResourceType, PathBuf>,
692 rt: &mut RustRuntimeServices<'_>,
693 ) {
694 let kernel = rt.read(self.kernel);
695 let initrd = rt.read(self.initrd);
696 resources.insert(ResourceType::LinuxKernel, kernel);
697 resources.insert(ResourceType::LinuxInitrd, initrd);
698 }
699}