1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
|
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 NAR (I think?) 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(AddTextToStoreRequest) returns (StorePath);
// Build the specified derivations in one of the specified build
// modes, defaulting to a normal build.
rpc BuildPaths(BuildPathsRequest) returns (google.protobuf.Empty);
// TODO: What does this do?
rpc EnsurePath(StorePath) returns (google.protobuf.Empty);
// TODO: What does this do?
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 (BuildDerivationResponse);
// Add signatures to the specified store path. The signatures are not
// verified.
rpc AddSignatures(Signatures) 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);
}
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;
}
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;
}
message Chunk {
bytes content = 1;
bool final = 2;
}
oneof add_oneof {
Metadata meta = 1;
Chunk chunk = 2;
}
}
message AddTextToStoreRequest {
string name = 1;
string content = 2;
repeated string references = 3;
}
message BuildPathsRequest {
repeated string drvs = 1;
BuildMode mode = 2;
}
message FindRootsResponse {
map<string, string> 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 deriver = 1;
string nar_hash = 2;
repeated string references = 3;
google.protobuf.Timestamp registration_time = 4;
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;
}
message SubstitutablePathInfos {
repeated PathInfo path_infos = 1;
}
message DerivationOutputNames {
repeated string names = 1;
}
message HashPart {
string hash_part = 1;
}
message VerifyStoreRequest {
bool repair = 1;
// TODO(grfn): Remove double-negative
bool dont_check_sigs = 2;
}
message VerifyStoreResponse {
// True if errors remain (???)
bool errors = 1;
}
message BuildDerivationRequest {
// Only used for informational purposes.
StorePath drv_path = 1;
BuildMode build_mode = 2;
}
message BuildDerivationResponse {
BuildStatus status = 1;
string error_message = 2;
}
message AddToStoreNarRequest {
oneof add_oneoff {
PathInfo path_info = 1;
bytes chunk = 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;
}
|