refactor(tvix/build): use stricter BuildRequest type

Change-Id: Ifadd190e10ec22570ab3ccb4df54f64ae5ef0a44
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12674
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
Marijan Petričević 2024-10-19 19:04:22 -05:00
parent 1248fc0a9a
commit 2225b52cb5
12 changed files with 221 additions and 175 deletions

View file

@ -35,7 +35,7 @@ use tvix_castore::{Node, PathComponent};
///
/// As of now, we're okay to accept this, but it prevents uploading an
/// entirely-non-IFD subgraph of BuildRequests eagerly.
#[derive(Debug, Clone, PartialEq)]
#[derive(Default, Debug, Clone, PartialEq)]
pub struct BuildRequest {
/// The list of all root nodes that should be visible in `inputs_dir` at the
/// time of the build.

View file

@ -2,7 +2,8 @@ use tonic::async_trait;
use tracing::instrument;
use super::BuildService;
use crate::proto::{Build, BuildRequest};
use crate::buildservice::BuildRequest;
use crate::proto;
#[derive(Default)]
pub struct DummyBuildService {}
@ -10,7 +11,7 @@ pub struct DummyBuildService {}
#[async_trait]
impl BuildService for DummyBuildService {
#[instrument(skip(self), ret, err)]
async fn do_build(&self, _request: BuildRequest) -> std::io::Result<Build> {
async fn do_build(&self, _request: BuildRequest) -> std::io::Result<proto::Build> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"builds are not supported with DummyBuildService",

View file

@ -1,6 +1,7 @@
use tonic::{async_trait, transport::Channel};
use crate::proto::{build_service_client::BuildServiceClient, Build, BuildRequest};
use crate::buildservice::BuildRequest;
use crate::proto::{self, build_service_client::BuildServiceClient};
use super::BuildService;
@ -17,10 +18,10 @@ impl GRPCBuildService {
#[async_trait]
impl BuildService for GRPCBuildService {
async fn do_build(&self, request: BuildRequest) -> std::io::Result<Build> {
async fn do_build(&self, request: BuildRequest) -> std::io::Result<proto::Build> {
let mut client = self.client.clone();
client
.do_build(request)
.do_build(Into::<proto::BuildRequest>::into(request))
.await
.map(|resp| resp.into_inner())
.map_err(std::io::Error::other)

View file

@ -1,6 +1,6 @@
use tonic::async_trait;
use crate::proto::{self, Build};
use crate::proto;
pub mod build_request;
pub use crate::buildservice::build_request::*;
@ -17,5 +17,5 @@ pub use from_addr::from_addr;
#[async_trait]
pub trait BuildService: Send + Sync {
/// TODO: document
async fn do_build(&self, request: proto::BuildRequest) -> std::io::Result<Build>;
async fn do_build(&self, request: BuildRequest) -> std::io::Result<proto::Build>;
}

View file

@ -10,15 +10,15 @@ use tvix_castore::{
fs::fuse::FuseDaemon,
import::fs::ingest_path,
refscan::{ReferencePattern, ReferenceScanner},
Node, PathComponent,
};
use uuid::Uuid;
use crate::buildservice::BuildRequest;
use crate::{
oci::{get_host_output_paths, make_bundle, make_spec},
proto::{build::OutputNeedles, Build, BuildRequest},
proto::{self, build::OutputNeedles},
};
use std::{collections::BTreeMap, ffi::OsStr, path::PathBuf, process::Stdio};
use std::{ffi::OsStr, path::PathBuf, process::Stdio};
use super::BuildService;
@ -95,7 +95,7 @@ where
DS: DirectoryService + Clone + 'static,
{
#[instrument(skip_all, err)]
async fn do_build(&self, request: BuildRequest) -> std::io::Result<Build> {
async fn do_build(&self, request: BuildRequest) -> std::io::Result<proto::Build> {
let _permit = self.concurrent_builds.acquire().await.unwrap();
let bundle_name = Uuid::new_v4();
@ -128,26 +128,20 @@ where
.map_err(std::io::Error::other)?;
// assemble a BTreeMap of Nodes to pass into TvixStoreFs.
let root_nodes: BTreeMap<PathComponent, Node> =
BTreeMap::from_iter(request.inputs.iter().map(|input| {
// We know from validation this is Some.
input.clone().try_into_name_and_node().unwrap()
}));
let patterns = ReferencePattern::new(request.refscan_needles.clone());
// NOTE: impl Drop for FuseDaemon unmounts, so if the call is cancelled, umount.
let _fuse_daemon = tokio::task::spawn_blocking({
let blob_service = self.blob_service.clone();
let directory_service = self.directory_service.clone();
debug!(inputs=?root_nodes.keys(), "got inputs");
let dest = bundle_path.join("inputs");
let root_nodes = Box::new(request.inputs.clone());
move || {
let fs = tvix_castore::fs::TvixStoreFs::new(
blob_service,
directory_service,
Box::new(root_nodes),
root_nodes,
true,
false,
);
@ -223,7 +217,7 @@ where
Ok::<_, std::io::Error>((
tvix_castore::proto::Node::from_name_and_node(
PathBuf::from(output_path)
output_path
.file_name()
.and_then(|s| s.to_str())
.map(|s| s.to_string())
@ -240,8 +234,8 @@ where
.into_iter()
.unzip();
Ok(Build {
build_request: Some(request.clone()),
Ok(proto::Build {
build_request: Some(request.into()),
outputs,
outputs_needles,
})