snix_build/build/source/target/x86_64-unknown-linux-gnu/debug/build/snix-build-b6f2bf38866f1fc5/out/snix.build.v1.rs
1// This file is @generated by prost-build.
2/// A BuildRequest describes the request of something to be run on the builder.
3/// It is distinct from an actual \[Build\] that has already happened, or might be
4/// currently ongoing.
5///
6/// A BuildRequest can be seen as a more normalized version of a Derivation
7/// (parsed from A-Term), "writing out" some of the Nix-internal details about
8/// how e.g. environment variables in the build are set.
9///
10/// Nix has some impurities when building a Derivation, for example the --cores option
11/// ends up as an environment variable in the build, that's not part of the ATerm.
12///
13/// As of now, we serialize this into the BuildRequest, so builders can stay dumb.
14/// This might change in the future.
15///
16/// There's also a big difference when it comes to how inputs are modelled:
17///
18/// * Nix only uses store path (strings) to describe the inputs.
19/// As store paths can be input-addressed, a certain store path can contain
20/// different contents (as not all store paths are binary reproducible).
21/// This requires that for every input-addressed input, the builder has access
22/// to either the input's deriver (and needs to build it) or else a trusted
23/// source for the built input.
24/// to upload input-addressed paths, requiring the trusted users concept.
25/// * snix-build records a list of snix.castore.v1.Node as inputs.
26/// These map from the store path base name to their contents, relieving the
27/// builder from having to "trust" any input-addressed paths, contrary to Nix.
28///
29/// While this approach gives a better hermeticity, it has one downside:
30/// A BuildRequest can only be sent once the contents of all its inputs are known.
31///
32/// As of now, we're okay to accept this, but it prevents uploading an
33/// entirely-non-IFD subgraph of BuildRequests eagerly.
34///
35/// FUTUREWORK: We might be introducing another way to refer to inputs, to
36/// support "send all BuildRequest for a nixpkgs eval to a remote builder and put
37/// the laptop to sleep" usecases later.
38#[derive(Clone, PartialEq, ::prost::Message)]
39pub struct BuildRequest {
40 /// The list of all root nodes that should be visible in `inputs_dir` at the
41 /// time of the build.
42 /// As all references are content-addressed, no additional signatures are
43 /// needed to substitute / make these available in the build environment.
44 /// Inputs MUST be sorted by their names.
45 #[prost(message, repeated, tag = "1")]
46 pub inputs: ::prost::alloc::vec::Vec<::snix_castore::proto::Entry>,
47 /// The command (and its args) executed as the build script.
48 /// In the case of a Nix derivation, this is usually
49 /// \["/path/to/some-bash/bin/bash", "-e", "/path/to/some/builder.sh"\].
50 #[prost(string, repeated, tag = "2")]
51 pub command_args: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
52 /// The working dir of the command, relative to the build root.
53 /// "build", in the case of Nix.
54 /// This MUST be a clean relative path, without any ".", "..", or superfluous
55 /// slashes.
56 #[prost(string, tag = "3")]
57 pub working_dir: ::prost::alloc::string::String,
58 /// A list of "scratch" paths, relative to the build root.
59 /// These will be write-able during the build.
60 /// \[build, nix/store\] in the case of Nix.
61 /// These MUST be clean relative paths, without any ".", "..", or superfluous
62 /// slashes, and sorted.
63 #[prost(string, repeated, tag = "4")]
64 pub scratch_paths: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
65 /// The path where the castore input nodes will be located at,
66 /// "nix/store" in case of Nix.
67 /// Builds might also write into here (Nix builds do that).
68 /// This MUST be a clean relative path, without any ".", "..", or superfluous
69 /// slashes.
70 #[prost(string, tag = "5")]
71 pub inputs_dir: ::prost::alloc::string::String,
72 /// The list of output paths the build is expected to produce,
73 /// relative to the root.
74 /// If the path is not produced, the build is considered to have failed.
75 /// These MUST be clean relative paths, without any ".", "..", or superfluous
76 /// slashes, and sorted.
77 #[prost(string, repeated, tag = "6")]
78 pub outputs: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
79 /// The list of environment variables and their values that should be set
80 /// inside the build environment.
81 /// This includes both environment vars set inside the derivation, as well as
82 /// more "ephemeral" ones like NIX_BUILD_CORES, controlled by the `--cores`
83 /// CLI option of `nix-build`.
84 /// For now, we consume this as an option when turning a Derivation into a BuildRequest,
85 /// similar to how Nix has a `--cores` option.
86 /// We don't want to bleed these very nix-specific sandbox impl details into
87 /// (dumber) builders if we don't have to.
88 /// Environment variables are sorted by their keys.
89 #[prost(message, repeated, tag = "7")]
90 pub environment_vars: ::prost::alloc::vec::Vec<build_request::EnvVar>,
91 /// A set of constraints that need to be satisfied on a build host before a
92 /// Build can be started.
93 #[prost(message, optional, tag = "8")]
94 pub constraints: ::core::option::Option<build_request::BuildConstraints>,
95 /// Additional (small) files and their contents that should be placed into the
96 /// build environment, but outside inputs_dir.
97 /// Used for passAsFile and structuredAttrs in Nix.
98 #[prost(message, repeated, tag = "9")]
99 pub additional_files: ::prost::alloc::vec::Vec<build_request::AdditionalFile>,
100 /// If this is an non-empty list, all paths in `outputs` are scanned for these.
101 /// For Nix, `refscan_needles` would be populated with the nixbase32 hash parts of
102 /// every input store path and output store path. The latter is necessary to scan
103 /// for references between multi-output derivations.
104 #[prost(string, repeated, tag = "10")]
105 pub refscan_needles: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
106}
107/// Nested message and enum types in `BuildRequest`.
108pub mod build_request {
109 #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
110 pub struct EnvVar {
111 /// name of the environment variable. Must not contain = or \0.
112 #[prost(string, tag = "1")]
113 pub key: ::prost::alloc::string::String,
114 /// value of the environment variable. Must not contain \0.
115 #[prost(bytes = "bytes", tag = "2")]
116 pub value: ::prost::bytes::Bytes,
117 }
118 /// BuildConstraints represents certain conditions that must be fulfilled
119 /// inside the build environment to be able to build this.
120 /// Constraints can be things like required architecture and minimum amount of memory.
121 /// The required input paths are *not* represented in here, because it
122 /// wouldn't be hermetic enough - see the comment around inputs too.
123 #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
124 pub struct BuildConstraints {
125 /// The system that's needed to execute the build.
126 /// Must not be empty.
127 #[prost(string, tag = "1")]
128 pub system: ::prost::alloc::string::String,
129 /// The amount of memory required to be available for the build, in bytes.
130 #[prost(uint64, tag = "2")]
131 pub min_memory: u64,
132 /// A list of (absolute) paths that need to be available in the build
133 /// environment, like `/dev/kvm`.
134 /// This is distinct from the castore nodes in inputs.
135 /// TODO: check if these should be individual constraints instead.
136 /// These MUST be clean absolute paths, without any ".", "..", or superfluous
137 /// slashes, and sorted.
138 #[prost(string, repeated, tag = "3")]
139 pub available_ro_paths: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
140 /// Whether the build should be able to access the network,
141 #[prost(bool, tag = "4")]
142 pub network_access: bool,
143 /// Whether to provide a /bin/sh inside the build environment, usually a static bash.
144 #[prost(bool, tag = "5")]
145 pub provide_bin_sh: bool,
146 }
147 #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
148 pub struct AdditionalFile {
149 #[prost(string, tag = "1")]
150 pub path: ::prost::alloc::string::String,
151 #[prost(bytes = "bytes", tag = "2")]
152 pub contents: ::prost::bytes::Bytes,
153 }
154}
155/// A BuildResponse is (one possible) outcome of executing a \[BuildRequest\].
156#[derive(Clone, PartialEq, ::prost::Message)]
157pub struct BuildResponse {
158 /// The outputs that were produced after successfully building.
159 /// They are provided in the same order as specified in the \[BuildRequest\].
160 #[prost(message, repeated, tag = "1")]
161 pub outputs: ::prost::alloc::vec::Vec<build_response::Output>,
162}
163/// Nested message and enum types in `BuildResponse`.
164pub mod build_response {
165 #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
166 pub struct Output {
167 /// Output entry produced by the build. It may not contain a name,
168 /// as not all OS paths can be represented as castore paths.
169 /// The path this was ingested from can be looked up in the original build request.
170 #[prost(message, optional, tag = "1")]
171 pub output: ::core::option::Option<::snix_castore::proto::Entry>,
172 /// Indexes into the found \[BuildRequest::refscan_needles\] in this output.
173 #[prost(uint64, repeated, tag = "2")]
174 pub needles: ::prost::alloc::vec::Vec<u64>,
175 }
176}
177/// Generated client implementations.
178pub mod build_service_client {
179 #![allow(
180 unused_variables,
181 dead_code,
182 missing_docs,
183 clippy::wildcard_imports,
184 clippy::let_unit_value,
185 )]
186 use tonic::codegen::*;
187 use tonic::codegen::http::Uri;
188 #[derive(Debug, Clone)]
189 pub struct BuildServiceClient<T> {
190 inner: tonic::client::Grpc<T>,
191 }
192 impl BuildServiceClient<tonic::transport::Channel> {
193 /// Attempt to create a new client by connecting to a given endpoint.
194 pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
195 where
196 D: TryInto<tonic::transport::Endpoint>,
197 D::Error: Into<StdError>,
198 {
199 let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
200 Ok(Self::new(conn))
201 }
202 }
203 impl<T> BuildServiceClient<T>
204 where
205 T: tonic::client::GrpcService<tonic::body::Body>,
206 T::Error: Into<StdError>,
207 T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
208 <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
209 {
210 pub fn new(inner: T) -> Self {
211 let inner = tonic::client::Grpc::new(inner);
212 Self { inner }
213 }
214 pub fn with_origin(inner: T, origin: Uri) -> Self {
215 let inner = tonic::client::Grpc::with_origin(inner, origin);
216 Self { inner }
217 }
218 pub fn with_interceptor<F>(
219 inner: T,
220 interceptor: F,
221 ) -> BuildServiceClient<InterceptedService<T, F>>
222 where
223 F: tonic::service::Interceptor,
224 T::ResponseBody: Default,
225 T: tonic::codegen::Service<
226 http::Request<tonic::body::Body>,
227 Response = http::Response<
228 <T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody,
229 >,
230 >,
231 <T as tonic::codegen::Service<
232 http::Request<tonic::body::Body>,
233 >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
234 {
235 BuildServiceClient::new(InterceptedService::new(inner, interceptor))
236 }
237 /// Compress requests with the given encoding.
238 ///
239 /// This requires the server to support it otherwise it might respond with an
240 /// error.
241 #[must_use]
242 pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
243 self.inner = self.inner.send_compressed(encoding);
244 self
245 }
246 /// Enable decompressing responses.
247 #[must_use]
248 pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
249 self.inner = self.inner.accept_compressed(encoding);
250 self
251 }
252 /// Limits the maximum size of a decoded message.
253 ///
254 /// Default: `4MB`
255 #[must_use]
256 pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
257 self.inner = self.inner.max_decoding_message_size(limit);
258 self
259 }
260 /// Limits the maximum size of an encoded message.
261 ///
262 /// Default: `usize::MAX`
263 #[must_use]
264 pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
265 self.inner = self.inner.max_encoding_message_size(limit);
266 self
267 }
268 pub async fn do_build(
269 &mut self,
270 request: impl tonic::IntoRequest<super::BuildRequest>,
271 ) -> std::result::Result<tonic::Response<super::BuildResponse>, tonic::Status> {
272 self.inner
273 .ready()
274 .await
275 .map_err(|e| {
276 tonic::Status::unknown(
277 format!("Service was not ready: {}", e.into()),
278 )
279 })?;
280 let codec = tonic_prost::ProstCodec::default();
281 let path = http::uri::PathAndQuery::from_static(
282 "/snix.build.v1.BuildService/DoBuild",
283 );
284 let mut req = request.into_request();
285 req.extensions_mut()
286 .insert(GrpcMethod::new("snix.build.v1.BuildService", "DoBuild"));
287 self.inner.unary(req, path, codec).await
288 }
289 }
290}
291/// Generated server implementations.
292pub mod build_service_server {
293 #![allow(
294 unused_variables,
295 dead_code,
296 missing_docs,
297 clippy::wildcard_imports,
298 clippy::let_unit_value,
299 )]
300 use tonic::codegen::*;
301 /// Generated trait containing gRPC methods that should be implemented for use with BuildServiceServer.
302 #[async_trait]
303 pub trait BuildService: std::marker::Send + std::marker::Sync + 'static {
304 async fn do_build(
305 &self,
306 request: tonic::Request<super::BuildRequest>,
307 ) -> std::result::Result<tonic::Response<super::BuildResponse>, tonic::Status>;
308 }
309 #[derive(Debug)]
310 pub struct BuildServiceServer<T> {
311 inner: Arc<T>,
312 accept_compression_encodings: EnabledCompressionEncodings,
313 send_compression_encodings: EnabledCompressionEncodings,
314 max_decoding_message_size: Option<usize>,
315 max_encoding_message_size: Option<usize>,
316 }
317 impl<T> BuildServiceServer<T> {
318 pub fn new(inner: T) -> Self {
319 Self::from_arc(Arc::new(inner))
320 }
321 pub fn from_arc(inner: Arc<T>) -> Self {
322 Self {
323 inner,
324 accept_compression_encodings: Default::default(),
325 send_compression_encodings: Default::default(),
326 max_decoding_message_size: None,
327 max_encoding_message_size: None,
328 }
329 }
330 pub fn with_interceptor<F>(
331 inner: T,
332 interceptor: F,
333 ) -> InterceptedService<Self, F>
334 where
335 F: tonic::service::Interceptor,
336 {
337 InterceptedService::new(Self::new(inner), interceptor)
338 }
339 /// Enable decompressing requests with the given encoding.
340 #[must_use]
341 pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
342 self.accept_compression_encodings.enable(encoding);
343 self
344 }
345 /// Compress responses with the given encoding, if the client supports it.
346 #[must_use]
347 pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
348 self.send_compression_encodings.enable(encoding);
349 self
350 }
351 /// Limits the maximum size of a decoded message.
352 ///
353 /// Default: `4MB`
354 #[must_use]
355 pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
356 self.max_decoding_message_size = Some(limit);
357 self
358 }
359 /// Limits the maximum size of an encoded message.
360 ///
361 /// Default: `usize::MAX`
362 #[must_use]
363 pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
364 self.max_encoding_message_size = Some(limit);
365 self
366 }
367 }
368 impl<T, B> tonic::codegen::Service<http::Request<B>> for BuildServiceServer<T>
369 where
370 T: BuildService,
371 B: Body + std::marker::Send + 'static,
372 B::Error: Into<StdError> + std::marker::Send + 'static,
373 {
374 type Response = http::Response<tonic::body::Body>;
375 type Error = std::convert::Infallible;
376 type Future = BoxFuture<Self::Response, Self::Error>;
377 fn poll_ready(
378 &mut self,
379 _cx: &mut Context<'_>,
380 ) -> Poll<std::result::Result<(), Self::Error>> {
381 Poll::Ready(Ok(()))
382 }
383 fn call(&mut self, req: http::Request<B>) -> Self::Future {
384 match req.uri().path() {
385 "/snix.build.v1.BuildService/DoBuild" => {
386 #[allow(non_camel_case_types)]
387 struct DoBuildSvc<T: BuildService>(pub Arc<T>);
388 impl<
389 T: BuildService,
390 > tonic::server::UnaryService<super::BuildRequest>
391 for DoBuildSvc<T> {
392 type Response = super::BuildResponse;
393 type Future = BoxFuture<
394 tonic::Response<Self::Response>,
395 tonic::Status,
396 >;
397 fn call(
398 &mut self,
399 request: tonic::Request<super::BuildRequest>,
400 ) -> Self::Future {
401 let inner = Arc::clone(&self.0);
402 let fut = async move {
403 <T as BuildService>::do_build(&inner, request).await
404 };
405 Box::pin(fut)
406 }
407 }
408 let accept_compression_encodings = self.accept_compression_encodings;
409 let send_compression_encodings = self.send_compression_encodings;
410 let max_decoding_message_size = self.max_decoding_message_size;
411 let max_encoding_message_size = self.max_encoding_message_size;
412 let inner = self.inner.clone();
413 let fut = async move {
414 let method = DoBuildSvc(inner);
415 let codec = tonic_prost::ProstCodec::default();
416 let mut grpc = tonic::server::Grpc::new(codec)
417 .apply_compression_config(
418 accept_compression_encodings,
419 send_compression_encodings,
420 )
421 .apply_max_message_size_config(
422 max_decoding_message_size,
423 max_encoding_message_size,
424 );
425 let res = grpc.unary(method, req).await;
426 Ok(res)
427 };
428 Box::pin(fut)
429 }
430 _ => {
431 Box::pin(async move {
432 let mut response = http::Response::new(
433 tonic::body::Body::default(),
434 );
435 let headers = response.headers_mut();
436 headers
437 .insert(
438 tonic::Status::GRPC_STATUS,
439 (tonic::Code::Unimplemented as i32).into(),
440 );
441 headers
442 .insert(
443 http::header::CONTENT_TYPE,
444 tonic::metadata::GRPC_CONTENT_TYPE,
445 );
446 Ok(response)
447 })
448 }
449 }
450 }
451 }
452 impl<T> Clone for BuildServiceServer<T> {
453 fn clone(&self) -> Self {
454 let inner = self.inner.clone();
455 Self {
456 inner,
457 accept_compression_encodings: self.accept_compression_encodings,
458 send_compression_encodings: self.send_compression_encodings,
459 max_decoding_message_size: self.max_decoding_message_size,
460 max_encoding_message_size: self.max_encoding_message_size,
461 }
462 }
463 }
464 /// Generated gRPC service name
465 pub const SERVICE_NAME: &str = "snix.build.v1.BuildService";
466 impl<T> tonic::server::NamedService for BuildServiceServer<T> {
467 const NAME: &'static str = SERVICE_NAME;
468 }
469}