Skip to main content

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}