flowey_lib_hvlite/
download_lxutil.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Download pre-built lxutil package from its GitHub Release.
5//!
6//! NOTE: In the future, `lxutil` will be rewritten in Rust, and downloading a
7//! pre-compiled dll will no longer be necessary.
8
9use flowey::node::prelude::*;
10use std::collections::BTreeMap;
11
12#[derive(Serialize, Deserialize)]
13pub struct LxutilPackage {
14    pub lxutil_dll: PathBuf,
15    pub lxutil_pdb: PathBuf,
16    pub lxutil_lib: PathBuf,
17    pub lxutil_h: PathBuf,
18}
19
20#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
21pub enum LxutilArch {
22    X86_64,
23    Aarch64,
24}
25
26flowey_request! {
27    pub enum Request {
28        /// Specify version of lxutil to use
29        Version(String),
30        /// Download the lxutil package for the given arch
31        GetPackage {
32            arch: LxutilArch,
33            pkg: WriteVar<LxutilPackage>
34        }
35    }
36}
37
38new_flow_node!(struct Node);
39
40impl FlowNode for Node {
41    type Request = Request;
42
43    fn imports(ctx: &mut ImportCtx<'_>) {
44        ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
45        ctx.import::<flowey_lib_common::download_gh_release::Node>();
46    }
47
48    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
49        let mut version = None;
50        let mut reqs: BTreeMap<LxutilArch, Vec<WriteVar<LxutilPackage>>> = BTreeMap::new();
51
52        for req in requests {
53            match req {
54                Request::Version(v) => same_across_all_reqs("Version", &mut version, v)?,
55                Request::GetPackage { arch, pkg } => reqs.entry(arch).or_default().push(pkg),
56            }
57        }
58
59        let version = version.ok_or(anyhow::anyhow!("Missing essential request: Version"))?;
60
61        // -- end of req processing -- //
62
63        if reqs.is_empty() {
64            return Ok(());
65        }
66
67        let extract_zip_deps = flowey_lib_common::_util::extract::extract_zip_if_new_deps(ctx);
68
69        for (arch, out_vars) in reqs {
70            let tag = format!("Microsoft.WSL.LxUtil.{}", version);
71
72            let file_name = {
73                let arch_str = match arch {
74                    LxutilArch::X86_64 => "x64",
75                    LxutilArch::Aarch64 => "AARCH64",
76                };
77                format!("Microsoft.WSL.LxUtil.{}.zip", arch_str)
78            };
79
80            // NOTE: this release is part of the openvmm-deps repo, simply
81            // because that's a convenient repo to hang host this artifact.
82            let lxutil_zip = ctx.reqv(|v| flowey_lib_common::download_gh_release::Request {
83                repo_owner: "microsoft".into(),
84                repo_name: "openvmm-deps".into(),
85                needs_auth: false,
86                tag: tag.clone(),
87                file_name: file_name.clone(),
88                path: v,
89            });
90
91            ctx.emit_rust_step(format!("unpack {}", file_name), |ctx| {
92                let extract_zip_deps = extract_zip_deps.clone().claim(ctx);
93                let out_vars = out_vars.claim(ctx);
94                let lxutil_zip = lxutil_zip.claim(ctx);
95                move |rt| {
96                    let lxutil_zip = rt.read(lxutil_zip);
97
98                    let extract_dir = flowey_lib_common::_util::extract::extract_zip_if_new(
99                        rt,
100                        extract_zip_deps,
101                        &lxutil_zip,
102                        &tag,
103                    )?;
104
105                    let lxutil_package = LxutilPackage {
106                        lxutil_dll: extract_dir.join("native/bin/lxutil.dll"),
107                        lxutil_pdb: extract_dir.join("native/bin/lxutil.pdb"),
108                        lxutil_lib: extract_dir.join("native/lib/lxutil.lib"),
109                        lxutil_h: extract_dir.join("native/include/lxutil.h"),
110                    };
111
112                    rt.write_all(out_vars, &lxutil_package);
113
114                    Ok(())
115                }
116            });
117        }
118
119        Ok(())
120    }
121}