flowey_lib_hvlite/
build_openhcl_initrd.rs1use crate::download_openvmm_deps::OpenvmmDepsArch;
7use crate::run_cargo_build::common::CommonArch;
8use flowey::node::prelude::*;
9use std::collections::BTreeMap;
10
11#[derive(Serialize, Deserialize)]
12pub struct OpenhclInitrdOutput {
13 pub initrd: PathBuf,
14}
15
16#[derive(Default, Clone, Serialize, Deserialize, Debug)]
18pub struct OpenhclInitrdExtraParams {
19 pub extra_initrd_layers: Vec<PathBuf>,
21 pub extra_initrd_directories: Vec<PathBuf>,
23 pub custom_kernel_modules: Option<PathBuf>,
26}
27
28flowey_request! {
29 pub struct Request {
30 pub arch: CommonArch,
31 pub interactive: bool,
33 pub extra_params: Option<OpenhclInitrdExtraParams>,
35 pub rootfs_config: Vec<ReadVar<PathBuf>>,
37 pub extra_env: Option<ReadVar<BTreeMap<String, String>>>,
40 pub kernel_package_root: ReadVar<PathBuf>,
42 pub bin_openhcl: ReadVar<PathBuf>,
44 pub initrd: WriteVar<OpenhclInitrdOutput>,
46 }
47}
48
49new_flow_node!(struct Node);
50
51impl FlowNode for Node {
52 type Request = Request;
53
54 fn imports(ctx: &mut ImportCtx<'_>) {
55 ctx.import::<crate::download_openvmm_deps::Node>();
56 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
57 ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
58 }
59
60 fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
61 let pydeps =
63 ctx.reqv(
64 |side_effect| flowey_lib_common::install_dist_pkg::Request::Install {
65 package_names: ["python3"].map(Into::into).into(),
66 done: side_effect,
67 },
68 );
69
70 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
71
72 for Request {
73 arch,
74 extra_params,
75 rootfs_config,
76 kernel_package_root,
77 extra_env,
78 bin_openhcl,
79 initrd,
80 interactive,
81 } in requests
82 {
83 let OpenhclInitrdExtraParams {
84 extra_initrd_layers,
85 extra_initrd_directories,
86 custom_kernel_modules,
87 } = extra_params.unwrap_or_default();
88
89 let openvmm_deps_arch = match arch {
90 CommonArch::X86_64 => OpenvmmDepsArch::X86_64,
91 CommonArch::Aarch64 => OpenvmmDepsArch::Aarch64,
92 };
93
94 let interactive_dep = if interactive {
95 ctx.reqv(|v| {
96 crate::download_openvmm_deps::Request::GetOpenhclCpioDbgrd(openvmm_deps_arch, v)
97 })
98 } else {
99 ctx.reqv(|v| {
100 crate::download_openvmm_deps::Request::GetOpenhclCpioShell(openvmm_deps_arch, v)
101 })
102 };
103
104 if rootfs_config.is_empty() {
105 anyhow::bail!("no rootfs files provided");
106 }
107
108 ctx.emit_rust_step("building openhcl initrd", |ctx| {
109 pydeps.clone().claim(ctx);
110 let interactive_dep = interactive_dep.claim(ctx);
111 let rootfs_config = rootfs_config.claim(ctx);
112 let extra_env = extra_env.claim(ctx);
113 let bin_openhcl = bin_openhcl.claim(ctx);
114 let openvmm_repo_path = openvmm_repo_path.clone().claim(ctx);
115 let kernel_package_root = kernel_package_root.claim(ctx);
116 let initrd = initrd.claim(ctx);
117 move |rt| {
118 let interactive_dep = rt.read(interactive_dep);
119 let rootfs_config = rt.read(rootfs_config);
120 let extra_env = rt.read(extra_env);
121 let bin_openhcl = rt.read(bin_openhcl);
122 let openvmm_repo_path = rt.read(openvmm_repo_path);
123 let kernel_package_root = rt.read(kernel_package_root);
124
125 let sh = xshell::Shell::new()?;
126
127 let initrd_path = sh.current_dir().join("openhcl.cpio.gz");
128
129 let initrd_contents = {
130 let mut v = Vec::new();
131
132 if interactive {
133 v.push("--interactive".to_string());
135 } else {
136 v.push("--min-interactive".to_string());
138 }
139
140 for dir in extra_initrd_layers {
141 v.push("--layer".into());
142 v.push(dir.display().to_string());
143 }
144
145 for dir in extra_initrd_directories {
146 v.push("--add-dir".into());
147 v.push(dir.display().to_string());
148 }
149
150 v
151 };
152
153 let kernel_modules =
154 custom_kernel_modules.unwrap_or(kernel_package_root.join("."));
155
156 let rootfs_py_arch = match arch {
157 CommonArch::X86_64 => "x86_64",
158 CommonArch::Aarch64 => "aarch64",
159 };
160
161 match arch {
166 CommonArch::X86_64 => {
167 sh.set_var("OPENVMM_DEPS_X64", interactive_dep.parent().unwrap());
168 }
169 CommonArch::Aarch64 => {
170 sh.set_var("OPENVMM_DEPS_AARCH64", interactive_dep.parent().unwrap());
171 }
172 }
173
174 for (k, v) in extra_env.into_iter().flatten() {
175 sh.set_var(k, v);
176 }
177
178 sh.change_dir(openvmm_repo_path);
181
182 let rootfs_config = rootfs_config
183 .iter()
184 .flat_map(|x| ["--rootfs-config".as_ref(), x.as_os_str()]);
185
186 xshell::cmd!(
187 sh,
188 "python3 openhcl/update-rootfs.py
189 {bin_openhcl}
190 {initrd_path}
191 --arch {rootfs_py_arch}
192 --package-root {kernel_package_root}
193 --kernel-modules {kernel_modules}
194 {rootfs_config...}
195 {initrd_contents...}
196 "
197 )
198 .run()?;
199
200 rt.write(
201 initrd,
202 &OpenhclInitrdOutput {
203 initrd: initrd_path,
204 },
205 );
206
207 Ok(())
208 }
209 });
210 }
211
212 Ok(())
213 }
214}