Skip to main content

flowey_lib_hvlite/
resolve_openvmm_test_virtio_win.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Download the `openvmm-test-virtio-win` archive from the `openvmm-deps`
5//! GitHub release, or use a local path if specified.
6//!
7//! The archive contains extracted virtio-win driver files (NetKVM, etc.)
8//! and is architecture-independent — a single tarball covers all Windows
9//! target OS versions and architectures.
10
11use flowey::node::prelude::*;
12
13flowey_config! {
14    /// Config for the resolve_openvmm_test_virtio_win node.
15    pub struct Config {
16        /// Specify version of the github release to pull from
17        pub version: Option<String>,
18        /// Use a locally available virtio-win driver directory
19        pub local_path: Option<ConfigVar<PathBuf>>,
20    }
21}
22
23flowey_request! {
24    pub enum Request {
25        /// Get the path to the extracted virtio-win driver directory
26        Get(WriteVar<PathBuf>),
27    }
28}
29
30new_flow_node_with_config!(struct Node);
31
32impl FlowNodeWithConfig for Node {
33    type Request = Request;
34    type Config = Config;
35
36    fn imports(ctx: &mut ImportCtx<'_>) {
37        ctx.import::<flowey_lib_common::download_gh_release::Node>();
38    }
39
40    fn emit(
41        config: Config,
42        requests: Vec<Self::Request>,
43        ctx: &mut NodeCtx<'_>,
44    ) -> anyhow::Result<()> {
45        let Config {
46            version,
47            local_path,
48        } = config;
49        let mut out_vars: Vec<WriteVar<PathBuf>> = Vec::new();
50
51        for req in requests {
52            match req {
53                Request::Get(var) => out_vars.push(var),
54            }
55        }
56
57        if version.is_some() && local_path.is_some() {
58            anyhow::bail!("Cannot specify both Version and LocalPath");
59        }
60
61        if version.is_none() && local_path.is_none() {
62            anyhow::bail!("Must specify a Version or LocalPath");
63        }
64
65        if out_vars.is_empty() {
66            return Ok(());
67        }
68
69        if let Some(local_path) = local_path {
70            ctx.emit_rust_step("use local virtio-win drivers", |ctx| {
71                let out_vars = out_vars.claim(ctx);
72                let local_path = local_path.claim(ctx);
73                move |rt| {
74                    let path = rt.read(local_path);
75                    rt.write_all(out_vars, &path);
76                    Ok(())
77                }
78            });
79            return Ok(());
80        }
81
82        let version = version.expect("local path handled above");
83        let archive = ctx.reqv(|v| flowey_lib_common::download_gh_release::Request {
84            repo_owner: "microsoft".into(),
85            repo_name: "openvmm-deps".into(),
86            needs_auth: false,
87            tag: version.clone(),
88            file_name: format!("openvmm-test-virtio-win.{version}.tar.gz"),
89            path: v,
90        });
91
92        let persistent_dir = ctx.persistent_dir();
93
94        ctx.emit_rust_step("unpack openvmm-test-virtio-win archive", |ctx| {
95            let persistent_dir = persistent_dir.claim(ctx);
96            let archive = archive.claim(ctx);
97            let out_vars = out_vars.claim(ctx);
98            let version = version.clone();
99            move |rt| {
100                let persistent_dir = persistent_dir.map(|d| rt.read(d));
101                let file = rt.read(archive);
102                let dir = flowey_lib_common::_util::extract::extract_tar_gz_if_new(
103                    rt,
104                    persistent_dir.as_deref(),
105                    &file,
106                    &version,
107                )?;
108                rt.write_all(out_vars, &dir);
109                Ok(())
110            }
111        });
112
113        Ok(())
114    }
115}