flowey_hvlite/pipelines/
custom_vmfirmwareigvm_dll.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! See [`CustomVmfirmwareigvmDllCli`]
5
6use crate::pipelines_shared::cfg_common_params::CommonArchCli;
7use anyhow::Context;
8use flowey::node::prelude::ReadVar;
9use flowey::pipeline::prelude::*;
10use std::path::PathBuf;
11
12/// Encapsulate an existing pre-built IGVM file into *unsigned*
13/// `vmfirmwareigvm.dll` resource DLL.
14///
15/// Unlike `build-igvm`, this tool will NOT build OpenHCL from scratch. This
16/// tool streamlines the process of building the in-tree `vmfirmwareigvm_dll`
17/// crate (which requires setting various env vars, installing certain
18/// dependencies, etc...).
19///
20/// NOTE: This tool is primarily intended for use by Microsoft employees, as
21/// open-source deployments of OpenHCL typically load the IGVM file directly
22/// (rather than being encapsulated in a resource-DLL).
23#[derive(clap::Args)]
24pub struct CustomVmfirmwareigvmDllCli {
25    /// Path to IGVM payload to encapsulate in the vmfirmwareigvm resource DLL.
26    pub igvm_payload: PathBuf,
27
28    /// Architecture the DLL should be built for.
29    ///
30    /// Defaults to the current host architecture.
31    #[clap(long)]
32    pub arch: Option<CommonArchCli>,
33}
34
35impl IntoPipeline for CustomVmfirmwareigvmDllCli {
36    fn into_pipeline(self, backend_hint: PipelineBackendHint) -> anyhow::Result<Pipeline> {
37        if !matches!(backend_hint, PipelineBackendHint::Local) {
38            anyhow::bail!("build-igvm is for local use only")
39        }
40
41        // DEVNOTE: it would be nice to figure out what sort of magic is
42        // required for the WSL2 case to work. The tricky part is dealing with
43        // the underlying invocations to `rc.exe` via WSL2.
44        if !matches!(FlowPlatform::host(backend_hint), FlowPlatform::Windows) {
45            anyhow::bail!("custom-vmfirmwareigvm-dll only runs on Windows (WSL2 is NOT supported)")
46        }
47
48        let CustomVmfirmwareigvmDllCli { arch, igvm_payload } = self;
49
50        let arch = match arch {
51            Some(arch) => arch,
52            None => FlowArch::host(backend_hint).try_into()?,
53        };
54        let igvm_payload = std::path::absolute(igvm_payload)
55            .context("could not make path to igvm payload absolute")?;
56
57        let openvmm_repo = flowey_lib_common::git_checkout::RepoSource::ExistingClone(
58            ReadVar::from_static(crate::repo_root()),
59        );
60
61        let mut pipeline = Pipeline::new();
62
63        let (pub_out_dir, _) = pipeline.new_artifact("custom-vmfirmwareigvm-dll");
64
65        pipeline
66            .new_job(
67                FlowPlatform::host(backend_hint),
68                FlowArch::host(backend_hint),
69                "custom-vmfirmwareigvm-dll",
70            )
71            .dep_on(|_| flowey_lib_hvlite::_jobs::cfg_versions::Request {})
72            .dep_on(
73                |_| flowey_lib_hvlite::_jobs::cfg_hvlite_reposource::Params {
74                    hvlite_repo_source: openvmm_repo,
75                },
76            )
77            .dep_on(|_| flowey_lib_hvlite::_jobs::cfg_common::Params {
78                local_only: Some(flowey_lib_hvlite::_jobs::cfg_common::LocalOnlyParams {
79                    interactive: true,
80                    auto_install: false,
81                    force_nuget_mono: false, // no oss nuget packages
82                    external_nuget_auth: false,
83                    ignore_rust_version: true,
84                }),
85                verbose: ReadVar::from_static(false),
86                locked: false,
87                deny_warnings: false,
88            })
89            .dep_on(
90                |ctx| flowey_lib_hvlite::_jobs::local_custom_vmfirmwareigvm_dll::Params {
91                    arch: arch.into(),
92                    igvm_payload,
93                    artifact_dir: ctx.publish_artifact(pub_out_dir),
94                    done: ctx.new_done_handle(),
95                },
96            )
97            .finish();
98
99        Ok(pipeline)
100    }
101}