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