Skip to main content

flowey_lib_hvlite/
run_prep_steps.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Raw bindings to `prep_steps`, used to prepare test images before running tests.
5
6use crate::build_prep_steps::PrepStepsOutput;
7use flowey::node::prelude::*;
8use std::collections::BTreeMap;
9
10flowey_request! {
11    pub struct Request {
12        /// Path to prep_steps bin to use
13        pub prep_steps: ReadVar<PrepStepsOutput>,
14        /// Arguments to pass to prep_steps (e.g. "standard" or "no-vmbus")
15        pub args: Vec<String>,
16        /// Environment variables to set when running prep_steps
17        pub env: ReadVar<BTreeMap<String, String>>,
18        /// Completion indicator
19        pub done: WriteVar<SideEffect>,
20    }
21}
22
23new_simple_flow_node!(struct Node);
24
25impl SimpleFlowNode for Node {
26    type Request = Request;
27
28    fn imports(_ctx: &mut ImportCtx<'_>) {}
29
30    fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
31        let Request {
32            prep_steps,
33            args,
34            env,
35            done,
36        } = request;
37
38        ctx.emit_rust_step("running vmm_test prep_steps", |ctx| {
39            let prep_steps = prep_steps.claim(ctx);
40            let env = env.claim(ctx);
41            done.claim(ctx);
42            move |rt| {
43                let prep_steps = rt.read(prep_steps);
44                let env = rt.read(env);
45
46                let binary_path = match &prep_steps {
47                    PrepStepsOutput::WindowsBin { exe, .. } => exe,
48                    PrepStepsOutput::LinuxBin { bin, .. } => {
49                        bin.make_executable()?;
50                        bin
51                    }
52                };
53
54                // When running a Windows exe from WSL2, environment variables don't
55                // automatically propagate. We need to set WSLENV to tell WSL which
56                // env vars to share with Windows processes.
57                let is_windows_exe_via_wsl = flowey_lib_common::_util::running_in_wsl(rt)
58                    && matches!(prep_steps, PrepStepsOutput::WindowsBin { .. });
59
60                let mut env = env;
61                if is_windows_exe_via_wsl {
62                    // Inherit the existing WSLENV value if any and append any
63                    // new vars to add. No /p flag needed since paths are
64                    // already converted to Windows format.
65                    let old_wslenv = std::env::var("WSLENV");
66                    let new_wslenv = env.keys().cloned().collect::<Vec<_>>().join(":");
67                    env.insert(
68                        "WSLENV".into(),
69                        format!(
70                            "{}{}",
71                            old_wslenv.map(|s| s + ":").unwrap_or_default(),
72                            new_wslenv
73                        ),
74                    );
75                }
76
77                flowey::shell_cmd!(rt, "{binary_path}")
78                    .args(&args)
79                    .envs(env)
80                    .run()?;
81
82                Ok(())
83            }
84        });
85
86        Ok(())
87    }
88}