flowey_lib_hvlite/
run_igvmfilegen.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Raw bindings to `igvmfilegen`, used to build an igvm file from a manifest +
5//! set of resources.
6
7use flowey::node::prelude::*;
8use igvmfilegen_config::ResourceType;
9use std::collections::BTreeMap;
10
11#[derive(Serialize, Deserialize)]
12pub struct IgvmOutput {
13    pub igvm_bin: PathBuf,
14    pub igvm_map: Option<PathBuf>,
15    pub igvm_tdx_json: Option<PathBuf>,
16    pub igvm_snp_json: Option<PathBuf>,
17    pub igvm_vbs_json: Option<PathBuf>,
18}
19
20flowey_request! {
21    pub struct Request {
22        /// Path to igvmfilegen bin to use
23        pub igvmfilegen: ReadVar<PathBuf>,
24        /// IGVM manifest to build
25        pub manifest: ReadVar<PathBuf>,
26        /// Resources required by the provided IGVM manifest
27        pub resources: ReadVar<BTreeMap<ResourceType, PathBuf>>,
28        /// Output path of generated igvm file
29        pub igvm: WriteVar<IgvmOutput>,
30    }
31}
32
33new_simple_flow_node!(struct Node);
34
35impl SimpleFlowNode for Node {
36    type Request = Request;
37
38    fn imports(ctx: &mut ImportCtx<'_>) {
39        ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
40    }
41
42    fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
43        let Request {
44            igvmfilegen,
45            manifest,
46            resources,
47            igvm,
48        } = request;
49
50        ctx.emit_rust_step("building igvm file", |ctx| {
51            let igvm = igvm.claim(ctx);
52            let igvmfilegen = igvmfilegen.claim(ctx);
53            let manifest = manifest.claim(ctx);
54            let resources = resources.claim(ctx);
55            move |rt| {
56                let igvmfilegen = rt.read(igvmfilegen);
57                let manifest = rt.read(manifest);
58                let resources = rt.read(resources);
59
60                let sh = xshell::Shell::new()?;
61
62                let igvm_file_stem = "igvm";
63                let igvm_path = sh.current_dir().join(format!("{igvm_file_stem}.bin"));
64                let resources_path = sh.current_dir().join("igvm.json");
65
66                let resources = igvmfilegen_config::Resources::new(resources.into_iter().collect())
67                    .context("creating igvm resources")?;
68                std::fs::write(&resources_path, serde_json::to_string_pretty(&resources)?)
69                    .context("writing resources")?;
70
71                xshell::cmd!(
72                    sh,
73                    "{igvmfilegen} manifest
74                            -m {manifest}
75                            -r {resources_path}
76                            --debug-validation
77                            -o {igvm_path}
78                        "
79                )
80                .run()?;
81
82                let igvm_map_path = igvm_path.with_extension("bin.map");
83                let igvm_map_path = igvm_map_path.exists().then_some(igvm_map_path);
84                let igvm_tdx_json = {
85                    let path = igvm_path.with_file_name(format!("{igvm_file_stem}-tdx.json"));
86                    path.exists().then_some(path)
87                };
88                let igvm_snp_json = {
89                    let path = igvm_path.with_file_name(format!("{igvm_file_stem}-snp.json"));
90                    path.exists().then_some(path)
91                };
92                let igvm_vbs_json = {
93                    let path = igvm_path.with_file_name(format!("{igvm_file_stem}-vbs.json"));
94                    path.exists().then_some(path)
95                };
96
97                rt.write(
98                    igvm,
99                    &IgvmOutput {
100                        igvm_bin: igvm_path,
101                        igvm_map: igvm_map_path,
102                        igvm_tdx_json,
103                        igvm_snp_json,
104                        igvm_vbs_json,
105                    },
106                );
107
108                Ok(())
109            }
110        });
111
112        Ok(())
113    }
114}