flowey_lib_hvlite/
download_uefi_mu_msvm.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Download pre-built mu_msvm package from its GitHub Release.
5
6use flowey::node::prelude::*;
7use std::collections::BTreeMap;
8
9#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
10pub enum MuMsvmArch {
11    X86_64,
12    Aarch64,
13}
14
15flowey_request! {
16    pub enum Request {
17        /// Specify version of mu_msvm to use
18        Version(String),
19        /// Download the mu_msvm package for the given arch
20        GetMsvmFd {
21            arch: MuMsvmArch,
22            msvm_fd: WriteVar<PathBuf>
23        }
24    }
25}
26
27new_flow_node!(struct Node);
28
29impl FlowNode for Node {
30    type Request = Request;
31
32    fn imports(ctx: &mut ImportCtx<'_>) {
33        ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
34        ctx.import::<flowey_lib_common::download_gh_release::Node>();
35    }
36
37    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
38        let mut version = None;
39        let mut reqs: BTreeMap<MuMsvmArch, Vec<WriteVar<PathBuf>>> = BTreeMap::new();
40
41        for req in requests {
42            match req {
43                Request::Version(v) => same_across_all_reqs("Version", &mut version, v)?,
44                Request::GetMsvmFd { arch, msvm_fd } => reqs.entry(arch).or_default().push(msvm_fd),
45            }
46        }
47
48        let version = version.ok_or(anyhow::anyhow!("Missing essential request: Version"))?;
49
50        // -- end of req processing -- //
51
52        if reqs.is_empty() {
53            return Ok(());
54        }
55
56        let extract_zip_deps = flowey_lib_common::_util::extract::extract_zip_if_new_deps(ctx);
57
58        for (arch, out_vars) in reqs {
59            let file_name = match arch {
60                MuMsvmArch::X86_64 => "RELEASE-X64-artifacts.zip",
61                MuMsvmArch::Aarch64 => "RELEASE-AARCH64-artifacts.zip",
62            };
63
64            let mu_msvm_zip = ctx.reqv(|v| flowey_lib_common::download_gh_release::Request {
65                repo_owner: "microsoft".into(),
66                repo_name: "mu_msvm".into(),
67                needs_auth: false,
68                tag: format!("v{version}"),
69                file_name: file_name.into(),
70                path: v,
71            });
72
73            let zip_file_version = format!("{version}-{file_name}");
74
75            ctx.emit_rust_step(
76                {
77                    format!(
78                        "unpack mu_msvm package ({})",
79                        match arch {
80                            MuMsvmArch::X86_64 => "x64",
81                            MuMsvmArch::Aarch64 => "aarch64",
82                        },
83                    )
84                },
85                |ctx| {
86                    let extract_zip_deps = extract_zip_deps.clone().claim(ctx);
87                    let out_vars = out_vars.claim(ctx);
88                    let mu_msvm_zip = mu_msvm_zip.claim(ctx);
89                    move |rt| {
90                        let mu_msvm_zip = rt.read(mu_msvm_zip);
91
92                        let extract_dir = flowey_lib_common::_util::extract::extract_zip_if_new(
93                            rt,
94                            extract_zip_deps,
95                            &mu_msvm_zip,
96                            &zip_file_version,
97                        )?;
98
99                        let msvm_fd = extract_dir.join("FV/MSVM.fd");
100
101                        for var in out_vars {
102                            rt.write(var, &msvm_fd)
103                        }
104
105                        Ok(())
106                    }
107                },
108            );
109        }
110
111        Ok(())
112    }
113}