git.delta.rocks / jrsonnet / refs/commits / 7de62040eec5

difftreelog

refactor replace builtins.currentSystem with pure alternative

Yaroslav Bolyukin2024-11-30parent: #3e7b063.patch.diff
in: trunk

5 files changed

addedcrates/fleet-base/build.rsdiffbeforeafterboth
--- /dev/null
+++ b/crates/fleet-base/build.rs
@@ -0,0 +1,15 @@
+use std::env;
+
+fn main() {
+	let target = env::var("TARGET").expect("TARGET env var is set by cargo");
+
+	let nix_system = if target.starts_with("x86_64-unknown-linux-") {
+		"x86_64-linux"
+	} else if target.starts_with("aarch64-unknown-linux-") {
+		"aarch64-linux"
+	} else {
+		panic!("unknown nix system name for rust {target} triple!");
+	};
+
+	println!("cargo:rustc-env=NIX_SYSTEM={nix_system}");
+}
modifiedcrates/fleet-base/src/opts.rsdiffbeforeafterboth
--- a/crates/fleet-base/src/opts.rs
+++ b/crates/fleet-base/src/opts.rs
@@ -8,7 +8,7 @@
 
 use anyhow::Result;
 use clap::Parser;
-use nix_eval::{nix_go, nix_go_json, util::assert_warn, NixSessionPool, Value};
+use nix_eval::{nix_go, util::assert_warn, NixSessionPool, Value};
 use nom::{
 	bytes::complete::take_while1,
 	character::complete::char,
@@ -85,14 +85,16 @@
 
 	/// Override detected system for host, to perform builds via
 	/// binfmt-declared qemu instead of trying to crosscompile
-	// TODO: Remove, as it is not used anymore.
-	#[clap(long, default_value = "detect")]
+	#[clap(long, default_value = env!("NIX_SYSTEM"))]
 	pub local_system: String,
 }
 
 impl FleetOpts {
-	pub async fn filter_skipped(&self, hosts: impl IntoIterator<Item = ConfigHost>) -> Result<Vec<ConfigHost>> {
-		let mut out = Vec::new();	
+	pub async fn filter_skipped(
+		&self,
+		hosts: impl IntoIterator<Item = ConfigHost>,
+	) -> Result<Vec<ConfigHost>> {
+		let mut out = Vec::new();
 		for host in hosts {
 			if self.should_skip(&host).await? {
 				continue;
@@ -182,15 +184,15 @@
 	pub async fn build(&self, nix_args: Vec<OsString>) -> Result<Config> {
 		let directory = current_dir()?;
 
-		let pool = NixSessionPool::new(directory.as_os_str().to_owned(), nix_args.clone()).await?;
+		let pool = NixSessionPool::new(
+			directory.as_os_str().to_owned(),
+			nix_args.clone(),
+			self.local_system.clone(),
+		)
+		.await?;
 		let nix_session = pool.get().await?;
 
 		let builtins_field = Value::binding(nix_session.clone(), "builtins").await?;
-		let local_system = if self.local_system == "detect" {
-			nix_go_json!(builtins_field.currentSystem)
-		} else {
-			self.local_system.clone()
-		};
 
 		let mut fleet_data_path = directory.clone();
 		fleet_data_path.push("fleet.nix");
@@ -210,14 +212,14 @@
 
 		let default_pkgs = nix_go!(nixpkgs(Obj {
 			overlays,
-			system: local_system.clone(),
+			system: self.local_system.clone(),
 		}));
 
 		Ok(Config(Arc::new(FleetConfigInternals {
 			nix_session,
 			directory,
 			data,
-			local_system,
+			local_system: self.local_system.clone(),
 			nix_args,
 			config_field,
 			default_pkgs,
modifiedcrates/nix-eval/src/lib.rsdiffbeforeafterboth
before · crates/nix-eval/src/lib.rs
1//! This whole library should be replaced with either binding to nix libexpr,2//! or with tvix (once it is able to build NixOS).3//!4//! Current api is awful, little effort was put into this implementation.56use std::{collections::HashMap, path::PathBuf, sync::Arc};78pub use pool::NixSessionPool;9use pool::NixSessionPoolInner;10use r2d2::PooledConnection;11pub use session::{Error, Result};12use tokio::sync::{mpsc, oneshot};13use tracing::instrument;14pub use value::{Index, Value};1516mod pool;17mod session;18mod value;19// Contains macros helpers20#[doc(hidden)]21pub mod macros;22pub mod util;23// #[allow(non_upper_case_globals, non_camel_case_types, non_snake_case)]24// mod nix_raw {25// 	include!(concat!(env!("OUT_DIR"), "/bindings.rs"));26// }2728// fn init() {29// 	nix_raw::libutil_init();30// }3132#[derive(Clone)]33pub struct NixSession(pub(crate) Arc<tokio::sync::Mutex<PooledConnection<NixSessionPoolInner>>>);3435struct NixBuildTask(Value, oneshot::Sender<Result<HashMap<String, PathBuf>>>);3637#[derive(Clone)]38pub struct NixBuildBatch {39	tx: mpsc::UnboundedSender<NixBuildTask>,40}4142#[instrument(skip(session, values))]43async fn build_multiple(name: String, session: NixSession, values: Vec<Value>) -> Result<()> {44	let builtins = Value::binding(session, "builtins").await?;45	let system = nix_go!(builtins.currentSystem);46	let drv = nix_go!(builtins.derivation(Obj {47		system,48		name,49		builder: "/bin/sh",50		// we want nothing from this derivation, it is only used to perform multiple builds at once.51		args: vec!["-c", "echo > $out"],52		preferLocalBuild: true,53		allowSubstitutes: false,54		buildInputs: values,55	}));56	drv.build().await?;57	Ok(())58}5960impl NixBuildBatch {61	fn new(name: String, session: NixSession) -> Self {62		let (tx, mut rx) = mpsc::unbounded_channel::<NixBuildTask>();6364		tokio::task::spawn(async move {65			let mut deps = vec![];66			let mut build_data = vec![];67			while let Some(task) = rx.recv().await {68				build_data.push(task.0.clone());69				deps.push(task);70			}71			if deps.is_empty() {72				return;73			}74			match build_multiple(name, session, build_data).await {75				Ok(_) => {76					for NixBuildTask(v, o) in deps {77						let _ = o.send(v.build().await);78					}79				}80				Err(e) => {81					for NixBuildTask(v, o) in deps {82						let s = v.to_string_weak().await.expect("drv is string-like");83						if PathBuf::from(s).exists() {84							let _ = o.send(v.build().await);85						} else {86							let _ = o.send(Err(e.clone()));87						}88					}89				}90			};91		});92		Self { tx }93	}94	pub async fn submit(self, task: Value) -> Result<HashMap<String, PathBuf>> {95		let Self { tx: task_tx } = self;96		let (tx, rx) = oneshot::channel();97		let _ = task_tx.send(NixBuildTask(task, tx));98		drop(task_tx);99		rx.await.expect("shoudn't be cancelled here")100	}101}102103impl NixSession {104	fn ptr_eq(a: &Self, b: &Self) -> bool {105		Arc::ptr_eq(&a.0, &b.0)106	}107108	pub fn new_build_batch(&self, name: String) -> NixBuildBatch {109		NixBuildBatch::new(name, self.clone())110	}111}112113pub fn init_tokio() {114	let _ = pool::TOKIO_RUNTIME.set(tokio::runtime::Handle::current());115}
after · crates/nix-eval/src/lib.rs
1//! This whole library should be replaced with either binding to nix libexpr,2//! or with tvix (once it is able to build NixOS).3//!4//! Current api is awful, little effort was put into this implementation.56use std::{collections::HashMap, path::PathBuf, sync::Arc};78pub use pool::NixSessionPool;9use pool::NixSessionPoolInner;10use r2d2::PooledConnection;11pub use session::{Error, Result};12use tokio::sync::{mpsc, oneshot};13use tracing::instrument;14pub use value::{Index, Value};1516mod pool;17mod session;18mod value;19// Contains macros helpers20#[doc(hidden)]21pub mod macros;22pub mod util;23// #[allow(non_upper_case_globals, non_camel_case_types, non_snake_case)]24// mod nix_raw {25// 	include!(concat!(env!("OUT_DIR"), "/bindings.rs"));26// }2728// fn init() {29// 	nix_raw::libutil_init();30// }3132#[derive(Clone)]33pub struct NixSession(pub(crate) Arc<tokio::sync::Mutex<PooledConnection<NixSessionPoolInner>>>);3435struct NixBuildTask(Value, oneshot::Sender<Result<HashMap<String, PathBuf>>>);3637#[derive(Clone)]38pub struct NixBuildBatch {39	tx: mpsc::UnboundedSender<NixBuildTask>,40}4142#[instrument(skip(session, values))]43async fn build_multiple(name: String, session: NixSession, values: Vec<Value>) -> Result<()> {44	let system = session.0.lock().await.nix_system.clone();45	let builtins = Value::binding(session, "builtins").await?;46	let drv = nix_go!(builtins.derivation(Obj {47		system,48		name,49		builder: "/bin/sh",50		// we want nothing from this derivation, it is only used to perform multiple builds at once.51		args: vec!["-c", "echo > $out"],52		preferLocalBuild: true,53		allowSubstitutes: false,54		buildInputs: values,55	}));56	drv.build().await?;57	Ok(())58}5960impl NixBuildBatch {61	fn new(name: String, session: NixSession) -> Self {62		let (tx, mut rx) = mpsc::unbounded_channel::<NixBuildTask>();6364		tokio::task::spawn(async move {65			let mut deps = vec![];66			let mut build_data = vec![];67			while let Some(task) = rx.recv().await {68				build_data.push(task.0.clone());69				deps.push(task);70			}71			if deps.is_empty() {72				return;73			}74			match build_multiple(name, session, build_data).await {75				Ok(_) => {76					for NixBuildTask(v, o) in deps {77						let _ = o.send(v.build().await);78					}79				}80				Err(e) => {81					for NixBuildTask(v, o) in deps {82						let s = v.to_string_weak().await.expect("drv is string-like");83						if PathBuf::from(s).exists() {84							let _ = o.send(v.build().await);85						} else {86							let _ = o.send(Err(e.clone()));87						}88					}89				}90			};91		});92		Self { tx }93	}94	pub async fn submit(self, task: Value) -> Result<HashMap<String, PathBuf>> {95		let Self { tx: task_tx } = self;96		let (tx, rx) = oneshot::channel();97		let _ = task_tx.send(NixBuildTask(task, tx));98		drop(task_tx);99		rx.await.expect("shoudn't be cancelled here")100	}101}102103impl NixSession {104	fn ptr_eq(a: &Self, b: &Self) -> bool {105		Arc::ptr_eq(&a.0, &b.0)106	}107108	pub fn new_build_batch(&self, name: String) -> NixBuildBatch {109		NixBuildBatch::new(name, self.clone())110	}111}112113pub fn init_tokio() {114	let _ = pool::TOKIO_RUNTIME.set(tokio::runtime::Handle::current());115}
modifiedcrates/nix-eval/src/pool.rsdiffbeforeafterboth
--- a/crates/nix-eval/src/pool.rs
+++ b/crates/nix-eval/src/pool.rs
@@ -1,18 +1,23 @@
-use std::ffi::OsString;
-use std::sync::{Arc, OnceLock};
+use std::{
+	ffi::OsString,
+	sync::{Arc, OnceLock},
+};
 
 use r2d2::Pool;
 
-use crate::session::NixSessionInner;
-use crate::{Error, NixSession, Result};
+use crate::{session::NixSessionInner, Error, NixSession, Result};
 
 pub struct NixSessionPool(Pool<NixSessionPoolInner>);
 impl NixSessionPool {
-	pub async fn new(flake: OsString, nix_args: Vec<OsString>) -> Result<Self> {
+	pub async fn new(flake: OsString, nix_args: Vec<OsString>, nix_system: String) -> Result<Self> {
 		let inner = tokio::task::block_in_place(|| {
 			r2d2::Builder::<NixSessionPoolInner>::new()
 				.min_idle(Some(0))
-				.build(NixSessionPoolInner { flake, nix_args })
+				.build(NixSessionPoolInner {
+					flake,
+					nix_args,
+					nix_system,
+				})
 		})?;
 		Ok(Self(inner))
 	}
@@ -25,6 +30,7 @@
 pub(crate) struct NixSessionPoolInner {
 	flake: OsString,
 	nix_args: Vec<OsString>,
+	pub(crate) nix_system: String,
 }
 
 impl r2d2::ManageConnection for NixSessionPoolInner {
@@ -38,6 +44,7 @@
 		Ok(futures::executor::block_on(NixSessionInner::new(
 			self.flake.as_os_str(),
 			self.nix_args.iter().map(OsString::as_os_str),
+			self.nix_system.clone(),
 		))?)
 	}
 
modifiedcrates/nix-eval/src/session.rsdiffbeforeafterboth
--- a/crates/nix-eval/src/session.rs
+++ b/crates/nix-eval/src/session.rs
@@ -206,6 +206,8 @@
 
 	next_id: u32,
 	pub(crate) free_list: Vec<u32>,
+
+	pub nix_system: String,
 }
 
 /// Discover inter-message repl delimiter
@@ -222,6 +224,7 @@
 	pub(crate) async fn new(
 		flake: &OsStr,
 		extra_args: impl IntoIterator<Item = &OsStr>,
+		nix_system: String,
 	) -> Result<Self> {
 		let mut cmd = Command::new("nix");
 		cmd.arg("repl")
@@ -280,6 +283,8 @@
 
 			next_id: 0,
 			free_list: vec![],
+
+			nix_system,
 		};
 		res.train().await?;
 		Ok(res)