git.delta.rocks / fleet / refs/heads / push-kyumtlkprzyo

difftreelog

source

remowt/crates/remowt-endpoints/src/nix_daemon.rs1.6 KiBsourcehistory
1use std::process::Stdio;2use std::sync::Arc;34use bifrostlink::Config;5use bifrostlink::declarative::endpoints;6use remowt_link_shared::iroh_tunnel::{TunnelAddr, TunnelDialer};7use serde::{Deserialize, Serialize};8use std::result::Result;9use tokio::io::{self, AsyncWriteExt as _};10use tokio::process::Command;1112#[derive(Clone)]13pub struct NixDaemon {14	dialer: Arc<TunnelDialer>,15}1617impl NixDaemon {18	pub fn new(dialer: Arc<TunnelDialer>) -> Self {19		Self { dialer }20	}21}2223#[derive(Serialize, Deserialize, Debug, thiserror::Error)]24pub enum Error {25	#[error("nix daemon unavailable: {0}")]26	DaemonUnavailable(String),27	#[error("tunnel socket unavailable: {0}")]28	Tunnel(String),29}3031#[endpoints(ns = 4)]32impl NixDaemon {33	#[endpoints(id = 2)]34	async fn serve_store(&self, store: String, tunnel: TunnelAddr) -> Result<(), Error> {35		let mut child = Command::new("nix-daemon")36			.arg("--stdio")37			.arg("--store")38			.arg(&store)39			.stdin(Stdio::piped())40			.stdout(Stdio::piped())41			.spawn()42			.map_err(|e| Error::DaemonUnavailable(e.to_string()))?;43		let tunnel = self44			.dialer45			.connect_tunnel(&tunnel)46			.await47			.map_err(|e| Error::Tunnel(e.to_string()))?;48		let mut stdin = child.stdin.take().expect("piped");49		let mut stdout = child.stdout.take().expect("piped");50		tokio::spawn(async move {51			let (mut tr, mut tw) = io::split(tunnel);52			let to_child = async {53				let _ = io::copy(&mut tr, &mut stdin).await;54				let _ = stdin.shutdown().await;55			};56			let from_child = async {57				let _ = io::copy(&mut stdout, &mut tw).await;58				let _ = tw.shutdown().await;59			};60			tokio::join!(to_child, from_child);61			let _ = child.wait().await;62		});63		Ok(())64	}65}