flowey_hvlite/pipelines/
build_reproducible.rs1use flowey::node::prelude::FlowPlatformLinuxDistro;
7use flowey::node::prelude::ReadVar;
8use flowey::pipeline::prelude::*;
9use flowey_lib_common::git_checkout::RepoSource;
10use flowey_lib_hvlite::_jobs::build_and_publish_openhcl_igvm_from_recipe::OpenhclIgvmBuildParams;
11use flowey_lib_hvlite::build_openhcl_igvm_from_recipe::OpenhclIgvmRecipe;
12use flowey_lib_hvlite::build_openvmm_hcl::OpenvmmHclBuildProfile;
13use flowey_lib_hvlite::common::CommonArch;
14use flowey_lib_hvlite::common::CommonPlatform;
15use flowey_lib_hvlite::common::CommonTriple;
16use flowey_lib_hvlite::resolve_openhcl_kernel_package::OpenhclKernelPackageKind;
17use std::collections::BTreeSet;
18use target_lexicon::Triple;
19
20#[derive(clap::ValueEnum, Copy, Clone)]
22pub enum ReproducibleOpenHclRecipe {
23 X64Cvm,
24}
25
26#[derive(clap::Args)]
28pub struct BuildReproducibleCli {
29 pub recipe: ReproducibleOpenHclRecipe,
38
39 #[clap(long)]
44 pub release: bool,
45}
46
47impl IntoPipeline for BuildReproducibleCli {
48 fn into_pipeline(self, backend_hint: PipelineBackendHint) -> anyhow::Result<Pipeline> {
49 if !matches!(backend_hint, PipelineBackendHint::Local) {
50 anyhow::bail!("build-reproducible is for local use only")
51 }
52
53 let Self { recipe, release } = self;
54
55 let mut pipeline = Pipeline::new();
56
57 let (pub_openhcl_igvm, _use_openhcl_igvm) = pipeline.new_artifact("x64-cvm-openhcl-igvm");
58 let (pub_openhcl_igvm_extras, _use_openhcl_igvm_extras) =
59 pipeline.new_artifact("x64-cvm-openhcl-igvm-extras");
60
61 let local_run_args = {
62 let mut args = crate::pipelines_shared::cfg_common_params::LocalRunArgs::default();
63 args.locked = true;
64 args.no_incremental = true;
65 args
66 };
67 let cfg_common_params = crate::pipelines_shared::cfg_common_params::get_cfg_common_params(
68 &mut pipeline,
69 backend_hint,
70 Some(local_run_args),
71 )?;
72
73 let openvmm_repo_source =
74 RepoSource::ExistingClone(ReadVar::from_static(crate::repo_root()));
75
76 let mut job = pipeline.new_job(
77 FlowPlatform::Linux(FlowPlatformLinuxDistro::Nix),
78 FlowArch::host(backend_hint),
79 "build-reproducible",
80 );
81
82 job = job.set_command_wrapper(flowey::shell::CommandWrapperKind::NixShell {
84 path: Some(crate::repo_root().join("shell.nix")),
85 });
86
87 let openvmm_hcl_profile = if release {
88 OpenvmmHclBuildProfile::OpenvmmHclShip
89 } else {
90 OpenvmmHclBuildProfile::Debug
91 };
92
93 let (recipe_arch, kernel_kind) = match recipe {
94 ReproducibleOpenHclRecipe::X64Cvm => {
95 (CommonArch::X86_64, OpenhclKernelPackageKind::Cvm)
96 }
97 };
98
99 let igvm_file = match recipe {
100 ReproducibleOpenHclRecipe::X64Cvm => OpenhclIgvmRecipe::X64Cvm,
101 };
102
103 let openhcl_musl_target = |arch: CommonArch| -> Triple {
104 CommonTriple::Common {
105 arch,
106 platform: CommonPlatform::LinuxMusl,
107 }
108 .as_triple()
109 };
110
111 job = job.dep_on(&cfg_common_params);
112 job = job.dep_on(
113 |_| flowey_lib_hvlite::_jobs::cfg_hvlite_reposource::Params {
114 hvlite_repo_source: openvmm_repo_source.clone(),
115 },
116 );
117 job = job.dep_on(|ctx| {
118 flowey_lib_hvlite::_jobs::build_openhcl_igvm_from_recipe_nix::Params {
119 arch: recipe_arch,
120 kernel_kind,
121 igvm_files: vec![igvm_file]
122 .into_iter()
123 .map(|recipe| OpenhclIgvmBuildParams {
124 profile: openvmm_hcl_profile,
125 recipe,
126 custom_target: Some(CommonTriple::Custom(openhcl_musl_target(recipe_arch))),
127 extra_features: BTreeSet::new(),
128 release_cfg: release,
129 })
130 .collect(),
131 artifact_dir_openhcl_igvm: ctx.publish_artifact(pub_openhcl_igvm),
132 artifact_dir_openhcl_igvm_extras: ctx.publish_artifact(pub_openhcl_igvm_extras),
133 artifact_openhcl_verify_size_baseline: None,
134 done: ctx.new_done_handle(),
135 }
136 });
137
138 job.finish();
139
140 Ok(pipeline)
141 }
142}