snix/third_party/nix/src/proto/worker.proto
Griffin Smith 74a8c3d359 fix(tvix): Chunk the AddTextToStore request
Rather than sending the entire AddTextToStore request along in a single
message, send it in a stream of chunks using the same metadata-first
approach we've been using for the other store gRPC requests. This fixes
a bug where certain builds could send more data than the maximum gRPC
request size (4194304 bytes, it would appear), resulting in a
RESOURCE_EXHAUSTED error.

The initial chunk size, which is currently constant but should be made
dynamic at some point in the future, has been chosen based on the IPC
bandwidth delay product for tazjin's desktop, rounded up.

Change-Id: I6f0232cdbc98653484816b39855126873fc59a03
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1835
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Reviewed-by: kanepyork <rikingcoding@gmail.com>
2020-08-29 14:29:45 +00:00

374 lines
9.6 KiB
Protocol Buffer

syntax = "proto3";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
package nix.proto;
// Service representing a worker used for building and interfacing
// with the Nix store.
service WorkerService {
// Validates whether the supplied path is a valid store path.
rpc IsValidPath(StorePath) returns (IsValidPathResponse);
// Checks whether any substitutes exist for the given path.
rpc HasSubstitutes(StorePath) returns (HasSubstitutesResponse);
// Query referrers for a given path.
rpc QueryReferrers(StorePath) returns (StorePaths);
// Add a path to the store. The first stream request
// should be a message indicating metadata, the rest should be file
// chunks.
rpc AddToStore(stream AddToStoreRequest) returns (StorePath);
// Adds the supplied string to the store, as a text file.
rpc AddTextToStore(stream AddTextToStoreRequest) returns (StorePath);
// Build the specified derivations in one of the specified build
// modes, defaulting to a normal build.
rpc BuildPaths(BuildPathsRequest) returns (stream BuildEvent);
// TODO: What does this do?
rpc EnsurePath(StorePath) returns (google.protobuf.Empty);
// TODO: What does this do?
// TODO(grfn): This should not actually take a StorePath, as it's not a
// StorePath
rpc AddTempRoot(StorePath) returns (google.protobuf.Empty);
// TODO: What does this do?
rpc AddIndirectRoot(StorePath) returns (google.protobuf.Empty);
// TODO: What does this do?
rpc SyncWithGC(google.protobuf.Empty) returns (google.protobuf.Empty);
// TODO: What does this do?
rpc FindRoots(google.protobuf.Empty) returns (FindRootsResponse);
// TODO: What does this do?
rpc SetOptions(SetOptionsRequest) returns (google.protobuf.Empty);
// Ask the store to perform a garbage collection, based on the
// specified parameters. See `GCAction` for the possible actions.
rpc CollectGarbage(CollectGarbageRequest) returns (CollectGarbageResponse);
// TODO: What does this do?
rpc QuerySubstitutablePathInfos(StorePaths) returns (SubstitutablePathInfos);
// TODO: What does this do?
rpc QueryDerivationOutputs(StorePath) returns (StorePaths);
// Query all valid paths in the store
rpc QueryAllValidPaths(google.protobuf.Empty) returns (StorePaths);
// TODO: What does this do?
rpc QueryPathInfo(StorePath) returns (PathInfo);
// Query the output names of the given derivation
rpc QueryDerivationOutputNames(StorePath) returns (DerivationOutputNames);
// TODO: What is a HashPart?
rpc QueryPathFromHashPart(HashPart) returns (StorePath);
// Query which of the given paths is valid.
rpc QueryValidPaths(StorePaths) returns (StorePaths);
// Query which of the given paths have substitutes.
rpc QuerySubstitutablePaths(StorePaths) returns (StorePaths);
// Return all currently valid derivations that have the given store path as an
// output.
rpc QueryValidDerivers(StorePath) returns (StorePaths);
// Optimise the disk space usage of the Nix store by hard-linking files
// with the same contents.
rpc OptimiseStore(google.protobuf.Empty) returns (google.protobuf.Empty);
// Check the integrity of the Nix store
rpc VerifyStore(VerifyStoreRequest) returns (VerifyStoreResponse);
// Build a single non-materialized derivation (i.e. not from an
// on-disk .drv file).
rpc BuildDerivation(BuildDerivationRequest) returns (stream BuildEvent);
// Add signatures to the specified store path. The signatures are not
// verified.
rpc AddSignatures(AddSignaturesRequest) returns (google.protobuf.Empty);
// TODO: What does this do?
rpc NarFromPath(StorePath) returns (StorePath);
// Upload & add a NAR to the daemon's Nix store.
rpc AddToStoreNar(stream AddToStoreNarRequest)
returns (google.protobuf.Empty);
// Given a set of paths that are to be built, return the set of
// derivations that will be built, and the set of output paths that
// will be substituted.
rpc QueryMissing(StorePaths) returns (QueryMissingResponse);
// Return the build log of the specified store path, if available
rpc GetBuildLog(StorePath) returns (BuildLog);
}
enum HashType {
UNKNOWN = 0;
MD5 = 1; // TODO(tazjin): still needed?
SHA1 = 2;
SHA256 = 3;
SHA512 = 4;
}
enum BuildMode {
Normal = 0;
Repair = 1;
Check = 2;
}
enum GCAction {
// Return the set of paths reachable from (i.e. in the closure of)
// the roots.
ReturnLive = 0;
// Return the set of paths not reachable from the roots.
ReturnDead = 1;
// Actually delete the latter set.
DeleteDead = 2;
// Delete the paths listed in `pathsToDelete', insofar as they are
// not reachable.
DeleteSpecific = 3;
}
enum BuildStatus {
Built = 0;
Substituted = 1;
AlreadyValid = 2;
PermanentFailure = 3;
InputRejected = 4;
OutputRejected = 5;
TransientFailure = 6; // possibly transient
CachedFailure = 7; // no longer used
TimedOut = 8;
MiscFailure = 9;
DependencyFailed = 10;
LogLimitExceeded = 11;
NotDeterministic = 12;
};
// Generic type for any RPC call that just reads or returns a single
// store path.
message StorePath {
string path = 1;
}
// Generic type for any RPC call that just reads or returns a list of
// store paths.
message StorePaths {
repeated string paths = 1;
}
message Signatures {
repeated string sigs = 1;
}
// Represents the outcome of a build for a single store path.
message BuildResult {
StorePath path = 1;
BuildStatus status = 2;
string msg = 3;
}
// Represents an event occuring during a build.
message BuildEvent {
message LogLine {
string line = 1;
StorePath path = 2;
}
oneof result_type {
// Build for a store path has finished
BuildResult result = 1;
// A line of build log output was produced
LogLine build_log = 2;
// Build for a store path has started
StorePath building_path = 3;
}
}
message IsValidPathResponse {
bool is_valid = 1;
}
message HasSubstitutesResponse {
bool has_substitutes = 1;
}
message AddToStoreRequest {
message Metadata {
bool fixed = 1;
bool recursive = 2; // TODO(tazjin): what is this? "obsolete" comment?
HashType hash_type = 3;
string base_name = 4;
}
oneof add_oneof {
Metadata meta = 1;
bytes data = 3;
}
}
message AddTextToStoreRequest {
message Metadata {
string name = 1;
repeated string references = 2;
uint64 size = 3;
}
oneof add_oneof {
Metadata meta = 4;
bytes data = 5;
}
}
message BuildPathsRequest {
repeated string drvs = 1;
BuildMode mode = 2;
}
message FindRootsResponse {
map<string, StorePaths> roots = 1;
}
message SetOptionsRequest {
bool keep_failed = 1;
bool keep_going = 2;
bool try_fallback = 3;
uint32 max_build_jobs = 4;
uint32 verbose_build =
5; // TODO(tazjin): Maybe this should be bool, unclear.
uint32 build_cores = 6; // TODO(tazjin): Difference from max_build_jobs?
bool use_substitutes = 7;
map<string, string> overrides = 8; // TODO(tazjin): better name?
}
message CollectGarbageRequest {
// GC action that should be performed.
GCAction action = 1;
// For `DeleteSpecific', the paths to delete.
repeated string paths_to_delete = 2;
// If `ignore_liveness' is set, then reachability from the roots is
// ignored (dangerous!). However, the paths must still be
// unreferenced *within* the store (i.e., there can be no other
// store paths that depend on them).
bool ignore_liveness = 3;
// Stop after at least `max_freed' bytes have been freed.
uint64 max_freed = 4;
}
message CollectGarbageResponse {
// Depending on the action, the GC roots, or the paths that would be
// or have been deleted.
repeated string deleted_paths = 1;
// For `ReturnDead', `DeleteDead' and `DeleteSpecific', the number
// of bytes that would be or was freed.
uint64 bytes_freed = 2;
}
message PathInfo {
StorePath path = 10;
bool is_valid = 9;
StorePath deriver = 1;
bytes nar_hash = 2;
repeated string references = 3;
google.protobuf.Timestamp registration_time = 4;
uint64 download_size = 11;
uint64 nar_size = 5;
// Whether the path is ultimately trusted, that is, it's a derivation
// output that was built locally.
bool ultimate = 6;
repeated string sigs = 7;
// If non-empty, an assertion that the path is content-addressed
string ca = 8;
// Only used for AddToStoreNarRequest
bool repair = 12;
bool check_sigs = 13;
}
message SubstitutablePathInfos {
repeated PathInfo path_infos = 1;
}
message DerivationOutputNames {
repeated string names = 1;
}
message HashPart {
string hash_part = 1;
}
message VerifyStoreRequest {
bool check_contents = 1;
bool repair = 2;
// TODO(grfn): Remove double-negative
bool dont_check_sigs = 3;
}
message VerifyStoreResponse {
// True if errors remain (???)
bool errors = 1;
}
message Derivation {
message DerivationOutput {
StorePath path = 1;
string hash_algo = 2;
bytes hash = 3;
}
map<string, DerivationOutput> outputs = 1;
StorePaths input_sources = 2;
string platform = 3;
StorePath builder = 4;
repeated string args = 5;
map<string, string> env = 6;
}
message BuildDerivationRequest {
// Only used for informational purposes.
StorePath drv_path = 1;
Derivation derivation = 2;
BuildMode build_mode = 3;
}
message AddSignaturesRequest {
StorePath path = 1;
Signatures sigs = 2;
}
message AddToStoreNarRequest {
oneof add_oneof {
PathInfo path_info = 1;
bytes data = 2;
}
}
message QueryMissingResponse {
repeated string will_build = 1;
repeated string will_substitute = 2;
repeated string unknown = 3;
uint64 download_size = 4;
uint64 nar_size = 5;
}
message BuildLog {
string build_log = 1;
}