f3fdb02e6b
Change-Id: I6f2ad235e00b8a08a8ec061f0a822881a2d83bca
177 lines
7.4 KiB
Protocol Buffer
177 lines
7.4 KiB
Protocol Buffer
// SPDX-License-Identifier: MIT
|
|
// Copyright © 2022 The Tvix Authors
|
|
|
|
syntax = "proto3";
|
|
|
|
package tvix.build.v1;
|
|
|
|
import "castore/protos/castore.proto";
|
|
|
|
option go_package = "code.tvl.fyi/tvix/build-go;buildv1";
|
|
|
|
// A BuildRequest describes the request of something to be run on the builder.
|
|
// It is distinct from an actual [Build] that has already happened, or might be
|
|
// currently ongoing.
|
|
//
|
|
// A BuildRequest can be seen as a more normalized version of a Derivation
|
|
// (parsed from A-Term), "writing out" some of the Nix-internal details about
|
|
// how e.g. environment variables in the build are set.
|
|
//
|
|
// Nix has some impurities when building a Derivation, for example the --cores option
|
|
// ends up as an environment variable in the build, that's not part of the ATerm.
|
|
//
|
|
// As of now, we serialize this into the BuildRequest, so builders can stay dumb.
|
|
// This might change in the future.
|
|
//
|
|
// There's also a big difference when it comes to how inputs are modelled:
|
|
// - Nix only uses store path (strings) to describe the inputs.
|
|
// As store paths can be input-addressed, a certain store path can contain
|
|
// different contents (as not all store paths are binary reproducible).
|
|
// This requires that for every input-addressed input, the builder has access
|
|
// to either the input's deriver (and needs to build it) or else a trusted
|
|
// source for the built input.
|
|
// to upload input-addressed paths, requiring the trusted users concept.
|
|
// - tvix-build records a list of tvix.castore.v1.Node as inputs.
|
|
// These map from the store path base name to their contents, relieving the
|
|
// builder from having to "trust" any input-addressed paths, contrary to Nix.
|
|
//
|
|
// While this approach gives a better hermeticity, it has one downside:
|
|
// A BuildRequest can only be sent once the contents of all its inputs are known.
|
|
//
|
|
// As of now, we're okay to accept this, but it prevents uploading an
|
|
// entirely-non-IFD subgraph of BuildRequests eagerly.
|
|
//
|
|
// FUTUREWORK: We might be introducing another way to refer to inputs, to
|
|
// support "send all BuildRequest for a nixpkgs eval to a remote builder and put
|
|
// the laptop to sleep" usecases later.
|
|
message BuildRequest {
|
|
// The list of all root nodes that should be visible in `inputs_dir` at the
|
|
// time of the build.
|
|
// As all references are content-addressed, no additional signatures are
|
|
// needed to substitute / make these available in the build environment.
|
|
// Inputs MUST be sorted by their names.
|
|
repeated tvix.castore.v1.Node inputs = 1;
|
|
|
|
// The command (and its args) executed as the build script.
|
|
// In the case of a Nix derivation, this is usually
|
|
// ["/path/to/some-bash/bin/bash", "-e", "/path/to/some/builder.sh"].
|
|
repeated string command_args = 2;
|
|
|
|
// The working dir of the command, relative to the build root.
|
|
// "build", in the case of Nix.
|
|
// This MUST be a clean relative path, without any ".", "..", or superfluous
|
|
// slashes.
|
|
string working_dir = 3;
|
|
|
|
// A list of "scratch" paths, relative to the build root.
|
|
// These will be write-able during the build.
|
|
// [build, nix/store] in the case of Nix.
|
|
// These MUST be clean relative paths, without any ".", "..", or superfluous
|
|
// slashes, and sorted.
|
|
repeated string scratch_paths = 4;
|
|
|
|
// The path where the castore input nodes will be located at,
|
|
// "nix/store" in case of Nix.
|
|
// Builds might also write into here (Nix builds do that).
|
|
// This MUST be a clean relative path, without any ".", "..", or superfluous
|
|
// slashes.
|
|
string inputs_dir = 5;
|
|
|
|
// The list of output paths the build is expected to produce,
|
|
// relative to the root.
|
|
// If the path is not produced, the build is considered to have failed.
|
|
// These MUST be clean relative paths, without any ".", "..", or superfluous
|
|
// slashes, and sorted.
|
|
repeated string outputs = 6;
|
|
|
|
// The list of environment variables and their values that should be set
|
|
// inside the build environment.
|
|
// This includes both environment vars set inside the derivation, as well as
|
|
// more "ephemeral" ones like NIX_BUILD_CORES, controlled by the `--cores`
|
|
// CLI option of `nix-build`.
|
|
// For now, we consume this as an option when turning a Derivation into a BuildRequest,
|
|
// similar to how Nix has a `--cores` option.
|
|
// We don't want to bleed these very nix-specific sandbox impl details into
|
|
// (dumber) builders if we don't have to.
|
|
// Environment variables are sorted by their keys.
|
|
repeated EnvVar environment_vars = 7;
|
|
|
|
message EnvVar {
|
|
// name of the environment variable. Must not contain =.
|
|
string key = 1;
|
|
bytes value = 2;
|
|
}
|
|
|
|
// A set of constraints that need to be satisfied on a build host before a
|
|
// Build can be started.
|
|
BuildConstraints constraints = 8;
|
|
|
|
// BuildConstraints represents certain conditions that must be fulfilled
|
|
// inside the build environment to be able to build this.
|
|
// Constraints can be things like required architecture and minimum amount of memory.
|
|
// The required input paths are *not* represented in here, because it
|
|
// wouldn't be hermetic enough - see the comment around inputs too.
|
|
message BuildConstraints {
|
|
// The system that's needed to execute the build.
|
|
// Must not be empty.
|
|
string system = 1;
|
|
|
|
// The amount of memory required to be available for the build, in bytes.
|
|
uint64 min_memory = 2;
|
|
|
|
// A list of (absolute) paths that need to be available in the build
|
|
// environment, like `/dev/kvm`.
|
|
// This is distinct from the castore nodes in inputs.
|
|
// TODO: check if these should be individual constraints instead.
|
|
// These MUST be clean absolute paths, without any ".", "..", or superfluous
|
|
// slashes, and sorted.
|
|
repeated string available_ro_paths = 3;
|
|
|
|
// Whether the build should be able to access the network,
|
|
bool network_access = 4;
|
|
|
|
// Whether to provide a /bin/sh inside the build environment, usually a static bash.
|
|
bool provide_bin_sh = 5;
|
|
}
|
|
|
|
// Additional (small) files and their contents that should be placed into the
|
|
// build environment, but outside inputs_dir.
|
|
// Used for passAsFile and structuredAttrs in Nix.
|
|
repeated AdditionalFile additional_files = 9;
|
|
|
|
message AdditionalFile {
|
|
string path = 1;
|
|
bytes contents = 2;
|
|
}
|
|
|
|
// If this is an non-empty list, all paths in `outputs` are scanned for these.
|
|
// For Nix, `refscan_needles` would be populated with the nixbase32 hash parts of
|
|
// every input store path and output store path. The latter is necessary to scan
|
|
// for references between multi-output derivations.
|
|
repeated string refscan_needles = 10;
|
|
|
|
// TODO: allow describing something like "preferLocal", to influence composition?
|
|
}
|
|
|
|
// A Build is (one possible) outcome of executing a [BuildRequest].
|
|
message Build {
|
|
// The orginal build request producing the build.
|
|
BuildRequest build_request = 1; // <- TODO: define hashing scheme for BuildRequest, refer to it by hash?
|
|
|
|
// The outputs that were produced after successfully building.
|
|
// They are sorted by their names.
|
|
repeated tvix.castore.v1.Node outputs = 2;
|
|
|
|
message OutputNeedles {
|
|
// The numbers are indexing into `refscan_needles` originally specified in the BuildRequest.
|
|
repeated uint64 needles = 1;
|
|
}
|
|
|
|
// Contains the same number of elements as the `outputs` field.
|
|
repeated OutputNeedles outputs_needles = 3;
|
|
|
|
// TODO: where did this run, how long, logs, …
|
|
}
|
|
|
|
/// TODO: check remarkable notes on constraints again
|
|
/// TODO: https://github.com/adisbladis/go-nix/commit/603df5db86ab97ba29f6f94d74f4e51642c56834
|