feat(tvix/build): add CLI entrypoint
This starts a BuildService as a separate process, currently defaulting to the DummyBuildService. Change-Id: Ic206f00831641d3ffebaa44883b7dc053700b9ca Reviewed-on: https://cl.tvl.fyi/c/depot/+/10631 Autosubmit: flokli <flokli@flokli.de> Reviewed-by: raitobezarius <tvl@lahfa.xyz> Tested-by: BuildkiteCI
This commit is contained in:
parent
170e0cdfad
commit
f0a750bcb7
4 changed files with 160 additions and 0 deletions
3
tvix/Cargo.lock
generated
3
tvix/Cargo.lock
generated
|
@ -3283,16 +3283,19 @@ name = "tvix-build"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"clap",
|
||||
"itertools 0.12.0",
|
||||
"prost 0.12.1",
|
||||
"prost-build",
|
||||
"test-case",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-listener",
|
||||
"tonic 0.10.2",
|
||||
"tonic-build",
|
||||
"tonic-reflection",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tvix-castore",
|
||||
"url",
|
||||
]
|
||||
|
|
|
@ -10214,6 +10214,13 @@ rec {
|
|||
crateName = "tvix-build";
|
||||
version = "0.1.0";
|
||||
edition = "2021";
|
||||
crateBin = [
|
||||
{
|
||||
name = "tvix-build";
|
||||
path = "src/bin/tvix-build.rs";
|
||||
requiredFeatures = [ ];
|
||||
}
|
||||
];
|
||||
# We can't filter paths with references in Nix 2.4
|
||||
# See https://github.com/NixOS/nix/issues/5410
|
||||
src =
|
||||
|
@ -10225,6 +10232,11 @@ rec {
|
|||
name = "bytes";
|
||||
packageId = "bytes";
|
||||
}
|
||||
{
|
||||
name = "clap";
|
||||
packageId = "clap";
|
||||
features = [ "derive" "env" ];
|
||||
}
|
||||
{
|
||||
name = "itertools";
|
||||
packageId = "itertools 0.12.0";
|
||||
|
@ -10241,6 +10253,11 @@ rec {
|
|||
name = "tokio";
|
||||
packageId = "tokio";
|
||||
}
|
||||
{
|
||||
name = "tokio-listener";
|
||||
packageId = "tokio-listener";
|
||||
features = [ "tonic010" ];
|
||||
}
|
||||
{
|
||||
name = "tonic";
|
||||
packageId = "tonic 0.10.2";
|
||||
|
@ -10255,6 +10272,11 @@ rec {
|
|||
name = "tracing";
|
||||
packageId = "tracing";
|
||||
}
|
||||
{
|
||||
name = "tracing-subscriber";
|
||||
packageId = "tracing-subscriber";
|
||||
features = [ "json" ];
|
||||
}
|
||||
{
|
||||
name = "tvix-castore";
|
||||
packageId = "tvix-castore";
|
||||
|
|
|
@ -5,13 +5,16 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
bytes = "1.4.0"
|
||||
clap = { version = "4.0", features = ["derive", "env"] }
|
||||
itertools = "0.12.0"
|
||||
prost = "0.12.1"
|
||||
thiserror = "1.0.56"
|
||||
tokio = { version = "1.32.0" }
|
||||
tokio-listener = { version = "0.2.2", features = [ "tonic010" ] }
|
||||
tonic = { version = "0.10.2", features = ["tls", "tls-roots"] }
|
||||
tvix-castore = { path = "../castore" }
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = { version = "0.3.16", features = ["json"] }
|
||||
url = "2.4.0"
|
||||
|
||||
[dependencies.tonic-reflection]
|
||||
|
|
132
tvix/build/src/bin/tvix-build.rs
Normal file
132
tvix/build/src/bin/tvix-build.rs
Normal file
|
@ -0,0 +1,132 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use clap::Parser;
|
||||
use clap::Subcommand;
|
||||
use tokio_listener::Listener;
|
||||
use tokio_listener::SystemOptions;
|
||||
use tokio_listener::UserOptions;
|
||||
use tonic::{self, transport::Server};
|
||||
use tracing::{info, Level};
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tvix_build::{
|
||||
buildservice,
|
||||
proto::{build_service_server::BuildServiceServer, GRPCBuildServiceWrapper},
|
||||
};
|
||||
use tvix_castore::blobservice;
|
||||
use tvix_castore::directoryservice;
|
||||
|
||||
#[cfg(feature = "tonic-reflection")]
|
||||
use tvix_build::proto::FILE_DESCRIPTOR_SET;
|
||||
#[cfg(feature = "tonic-reflection")]
|
||||
use tvix_castore::proto::FILE_DESCRIPTOR_SET as CASTORE_FILE_DESCRIPTOR_SET;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Cli {
|
||||
/// Whether to log in JSON
|
||||
#[arg(long)]
|
||||
json: bool,
|
||||
|
||||
#[arg(long)]
|
||||
log_level: Option<Level>,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Runs the tvix-build daemon.
|
||||
Daemon {
|
||||
#[arg(long, short = 'l')]
|
||||
listen_address: Option<String>,
|
||||
|
||||
#[arg(long, env, default_value = "grpc+http://[::1]:8000")]
|
||||
blob_service_addr: String,
|
||||
|
||||
#[arg(long, env, default_value = "grpc+http://[::1]:8000")]
|
||||
directory_service_addr: String,
|
||||
|
||||
#[arg(long, env, default_value = "dummy://")]
|
||||
build_service_addr: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
// configure log settings
|
||||
let level = cli.log_level.unwrap_or(Level::INFO);
|
||||
|
||||
let subscriber = tracing_subscriber::registry()
|
||||
.with(
|
||||
cli.json.then_some(
|
||||
tracing_subscriber::fmt::Layer::new()
|
||||
.with_writer(std::io::stderr.with_max_level(level))
|
||||
.json(),
|
||||
),
|
||||
)
|
||||
.with(
|
||||
(!cli.json).then_some(
|
||||
tracing_subscriber::fmt::Layer::new()
|
||||
.with_writer(std::io::stderr.with_max_level(level))
|
||||
.pretty(),
|
||||
),
|
||||
);
|
||||
|
||||
tracing::subscriber::set_global_default(subscriber).expect("Unable to set global subscriber");
|
||||
|
||||
match cli.command {
|
||||
Commands::Daemon {
|
||||
listen_address,
|
||||
blob_service_addr,
|
||||
directory_service_addr,
|
||||
build_service_addr,
|
||||
} => {
|
||||
// initialize stores
|
||||
let blob_service = blobservice::from_addr(&blob_service_addr).await?;
|
||||
let directory_service = directoryservice::from_addr(&directory_service_addr).await?;
|
||||
|
||||
let build_service = buildservice::from_addr(
|
||||
&build_service_addr,
|
||||
Arc::from(blob_service),
|
||||
Arc::from(directory_service),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let listen_address = listen_address
|
||||
.unwrap_or_else(|| "[::]:8000".to_string())
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
let mut server = Server::builder();
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut router = server.add_service(BuildServiceServer::new(
|
||||
GRPCBuildServiceWrapper::new(build_service),
|
||||
));
|
||||
|
||||
#[cfg(feature = "tonic-reflection")]
|
||||
{
|
||||
let reflection_svc = tonic_reflection::server::Builder::configure()
|
||||
.register_encoded_file_descriptor_set(CASTORE_FILE_DESCRIPTOR_SET)
|
||||
.register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET)
|
||||
.build()?;
|
||||
router = router.add_service(reflection_svc);
|
||||
}
|
||||
|
||||
info!(listen_address=%listen_address, "listening");
|
||||
|
||||
let listener = Listener::bind(
|
||||
&listen_address,
|
||||
&SystemOptions::default(),
|
||||
&UserOptions::default(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
router.serve_with_incoming(listener).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue