flowey_lib_hvlite/
download_openvmm_deps.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Download various pre-built `openvmm-deps` dependencies.
5
6use flowey::node::prelude::*;
7use std::collections::BTreeMap;
8
9#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
10pub enum OpenvmmDepsArch {
11    X86_64,
12    Aarch64,
13}
14
15flowey_request! {
16    pub enum Request {
17        /// Specify version of the github release to pull from
18        Version(String),
19        GetLinuxTestKernel(OpenvmmDepsArch, WriteVar<PathBuf>),
20        GetLinuxTestInitrd(OpenvmmDepsArch, WriteVar<PathBuf>),
21        GetOpenhclCpioDbgrd(OpenvmmDepsArch, WriteVar<PathBuf>),
22        GetOpenhclCpioShell(OpenvmmDepsArch, WriteVar<PathBuf>),
23        GetOpenhclSysroot(OpenvmmDepsArch, WriteVar<PathBuf>),
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 linux_test_kernel: BTreeMap<_, Vec<_>> = BTreeMap::new();
40        let mut linux_test_initrd: BTreeMap<_, Vec<_>> = BTreeMap::new();
41        let mut openhcl_cpio_dbgrd: BTreeMap<_, Vec<_>> = BTreeMap::new();
42        let mut openhcl_cpio_shell: BTreeMap<_, Vec<_>> = BTreeMap::new();
43        let mut openhcl_sysroot: BTreeMap<_, Vec<_>> = BTreeMap::new();
44
45        for req in requests {
46            match req {
47                Request::Version(v) => same_across_all_reqs("Version", &mut version, v)?,
48
49                Request::GetLinuxTestKernel(arch, var) => {
50                    linux_test_kernel.entry(arch).or_default().push(var)
51                }
52                Request::GetLinuxTestInitrd(arch, var) => {
53                    linux_test_initrd.entry(arch).or_default().push(var)
54                }
55                Request::GetOpenhclCpioDbgrd(arch, var) => {
56                    openhcl_cpio_dbgrd.entry(arch).or_default().push(var)
57                }
58                Request::GetOpenhclCpioShell(arch, var) => {
59                    openhcl_cpio_shell.entry(arch).or_default().push(var)
60                }
61                Request::GetOpenhclSysroot(arch, var) => {
62                    openhcl_sysroot.entry(arch).or_default().push(var)
63                }
64            }
65        }
66
67        let version = version.ok_or(anyhow::anyhow!("Missing essential request: Version"))?;
68
69        // -- end of req processing -- //
70
71        if linux_test_kernel.is_empty()
72            && linux_test_initrd.is_empty()
73            && openhcl_cpio_dbgrd.is_empty()
74            && openhcl_cpio_shell.is_empty()
75            && openhcl_sysroot.is_empty()
76        {
77            return Ok(());
78        }
79
80        let extract_tar_bz2_deps =
81            flowey_lib_common::_util::extract::extract_tar_bz2_if_new_deps(ctx);
82
83        let openvmm_deps_tar_bz2_x64 = if linux_test_initrd.contains_key(&OpenvmmDepsArch::X86_64)
84            || linux_test_kernel.contains_key(&OpenvmmDepsArch::X86_64)
85            || openhcl_cpio_dbgrd.contains_key(&OpenvmmDepsArch::X86_64)
86            || openhcl_cpio_shell.contains_key(&OpenvmmDepsArch::X86_64)
87            || openhcl_sysroot.contains_key(&OpenvmmDepsArch::X86_64)
88        {
89            Some(
90                ctx.reqv(|v| flowey_lib_common::download_gh_release::Request {
91                    repo_owner: "microsoft".into(),
92                    repo_name: "openvmm-deps".into(),
93                    needs_auth: false,
94                    tag: version.clone(),
95                    file_name: format!("openvmm-deps.x86_64.{version}.tar.bz2"),
96                    path: v,
97                }),
98            )
99        } else {
100            None
101        };
102
103        let openvmm_deps_tar_bz2_aarch64 = if linux_test_initrd
104            .contains_key(&OpenvmmDepsArch::Aarch64)
105            || linux_test_kernel.contains_key(&OpenvmmDepsArch::Aarch64)
106            || openhcl_cpio_dbgrd.contains_key(&OpenvmmDepsArch::Aarch64)
107            || openhcl_cpio_shell.contains_key(&OpenvmmDepsArch::Aarch64)
108            || openhcl_sysroot.contains_key(&OpenvmmDepsArch::Aarch64)
109        {
110            Some(
111                ctx.reqv(|v| flowey_lib_common::download_gh_release::Request {
112                    repo_owner: "microsoft".into(),
113                    repo_name: "openvmm-deps".into(),
114                    needs_auth: false,
115                    tag: version.clone(),
116                    file_name: format!("openvmm-deps.aarch64.{version}.tar.bz2"),
117                    path: v,
118                }),
119            )
120        } else {
121            None
122        };
123
124        ctx.emit_rust_step("unpack openvmm-deps archive", |ctx| {
125            let extract_tar_bz2_deps = extract_tar_bz2_deps.claim(ctx);
126            let openvmm_deps_tar_bz2_x64 = openvmm_deps_tar_bz2_x64.claim(ctx);
127            let openvmm_deps_tar_bz2_aarch64 = openvmm_deps_tar_bz2_aarch64.claim(ctx);
128
129            let linux_test_kernel = linux_test_kernel.claim(ctx);
130            let linux_test_initrd = linux_test_initrd.claim(ctx);
131            let openhcl_cpio_dbgrd = openhcl_cpio_dbgrd.claim(ctx);
132            let openhcl_cpio_shell = openhcl_cpio_shell.claim(ctx);
133            let openhcl_sysroot = openhcl_sysroot.claim(ctx);
134            move |rt| {
135                let extract_dir_x64 = openvmm_deps_tar_bz2_x64
136                    .map(|file| {
137                        let file = rt.read(file);
138                        flowey_lib_common::_util::extract::extract_tar_bz2_if_new(
139                            rt,
140                            extract_tar_bz2_deps.clone(),
141                            &file,
142                            &version,
143                        )
144                    })
145                    .transpose()?;
146                let extract_dir_aarch64 = openvmm_deps_tar_bz2_aarch64
147                    .map(|file| {
148                        let file = rt.read(file);
149                        flowey_lib_common::_util::extract::extract_tar_bz2_if_new(
150                            rt,
151                            extract_tar_bz2_deps.clone(),
152                            &file,
153                            &version,
154                        )
155                    })
156                    .transpose()?;
157
158                let base_dir = move |arch| match arch {
159                    OpenvmmDepsArch::X86_64 => extract_dir_x64.clone().unwrap(),
160                    OpenvmmDepsArch::Aarch64 => extract_dir_aarch64.clone().unwrap(),
161                };
162
163                let kernel_file_name = |arch| match arch {
164                    OpenvmmDepsArch::X86_64 => "vmlinux",
165                    OpenvmmDepsArch::Aarch64 => "Image",
166                };
167
168                for (arch, vars) in linux_test_kernel {
169                    let path = base_dir(arch).join(kernel_file_name(arch));
170                    rt.write_all(vars, &path)
171                }
172
173                for (arch, vars) in linux_test_initrd {
174                    let path = base_dir(arch).join("initrd");
175                    rt.write_all(vars, &path)
176                }
177
178                for (arch, vars) in openhcl_cpio_dbgrd {
179                    let path = base_dir(arch).join("dbgrd.cpio.gz");
180                    rt.write_all(vars, &path)
181                }
182
183                for (arch, vars) in openhcl_cpio_shell {
184                    let path = base_dir(arch).join("shell.cpio.gz");
185                    rt.write_all(vars, &path)
186                }
187
188                for (arch, vars) in openhcl_sysroot {
189                    let path = base_dir(arch).join("sysroot.tar.gz");
190                    rt.write_all(vars, &path)
191                }
192
193                Ok(())
194            }
195        });
196
197        Ok(())
198    }
199}