daemon: Implement signed archive import/export.
[jackhill/guix/guix.git] / guix / store.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
34fcbe3a 2;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
77d3cf08 3;;;
233e7676 4;;; This file is part of GNU Guix.
77d3cf08 5;;;
233e7676 6;;; GNU Guix is free software; you can redistribute it and/or modify it
77d3cf08
LC
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
233e7676 11;;; GNU Guix is distributed in the hope that it will be useful, but
77d3cf08
LC
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
233e7676 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
77d3cf08
LC
18
19(define-module (guix store)
0f41c26f 20 #:use-module (guix nar)
82058eff 21 #:use-module (guix utils)
d8eea3d2 22 #:use-module (guix config)
0f41c26f 23 #:use-module (guix serialization)
77d3cf08
LC
24 #:use-module (rnrs bytevectors)
25 #:use-module (rnrs io ports)
26 #:use-module (srfi srfi-1)
27 #:use-module (srfi srfi-9)
bf8e7fc5 28 #:use-module (srfi srfi-9 gnu)
77d3cf08 29 #:use-module (srfi srfi-26)
e87088c9
LC
30 #:use-module (srfi srfi-34)
31 #:use-module (srfi srfi-35)
26bbbb95 32 #:use-module (srfi srfi-39)
77d3cf08 33 #:use-module (ice-9 match)
e3d74106 34 #:use-module (ice-9 regex)
3f1e6939 35 #:use-module (ice-9 vlist)
9fd72fb1
LC
36 #:export (%daemon-socket-file
37
38 nix-server?
77d3cf08
LC
39 nix-server-major-version
40 nix-server-minor-version
41 nix-server-socket
42
e87088c9 43 &nix-error nix-error?
ef86c39f
LC
44 &nix-connection-error nix-connection-error?
45 nix-connection-error-file
46 nix-connection-error-code
e87088c9
LC
47 &nix-protocol-error nix-protocol-error?
48 nix-protocol-error-message
49 nix-protocol-error-status
50
26bbbb95
LC
51 hash-algo
52
77d3cf08 53 open-connection
3abaf0c4 54 close-connection
77d3cf08 55 set-build-options
31ef99a8 56 valid-path?
82058eff 57 query-path-hash
77d3cf08
LC
58 add-text-to-store
59 add-to-store
26bbbb95 60 build-derivations
3259877d 61 add-temp-root
34811f02 62 add-indirect-root
26bbbb95 63
0f3d2504
LC
64 substitutable?
65 substitutable-path
66 substitutable-deriver
67 substitutable-references
68 substitutable-download-size
69 substitutable-nar-size
70 has-substitutes?
71 substitutable-paths
72 substitutable-path-info
73
fae31edc 74 references
3f1e6939 75 requisites
fae31edc
LC
76 referrers
77 valid-derivers
78 query-derivation-outputs
3259877d
LC
79 live-paths
80 dead-paths
81 collect-garbage
82 delete-paths
526382ff
LC
83 import-paths
84 export-paths
3259877d 85
dcee50c1
LC
86 current-build-output-port
87
26bbbb95
LC
88 %store-prefix
89 store-path?
9336e5b5 90 direct-store-path?
e3d74106 91 derivation-path?
2c6ab6cc 92 store-path-package-name
eddd4077
LC
93 store-path-hash-part
94 log-file))
77d3cf08 95
63193ebf 96(define %protocol-version #x10c)
77d3cf08
LC
97
98(define %worker-magic-1 #x6e697863)
99(define %worker-magic-2 #x6478696f)
100
101(define (protocol-major magic)
102 (logand magic #xff00))
103(define (protocol-minor magic)
104 (logand magic #x00ff))
105
106(define-syntax define-enumerate-type
107 (syntax-rules ()
108 ((_ name->int (name id) ...)
109 (define-syntax name->int
110 (syntax-rules (name ...)
111 ((_ name) id) ...)))))
112
113(define-enumerate-type operation-id
114 ;; operation numbers from worker-protocol.hh
115 (quit 0)
116 (valid-path? 1)
117 (has-substitutes? 3)
118 (query-path-hash 4)
119 (query-references 5)
120 (query-referrers 6)
121 (add-to-store 7)
122 (add-text-to-store 8)
123 (build-derivations 9)
124 (ensure-path 10)
125 (add-temp-root 11)
126 (add-indirect-root 12)
127 (sync-with-gc 13)
128 (find-roots 14)
129 (export-path 16)
130 (query-deriver 18)
131 (set-options 19)
132 (collect-garbage 20)
63193ebf 133 ;;(query-substitutable-path-info 21) ; obsolete as of #x10c
77d3cf08 134 (query-derivation-outputs 22)
63193ebf 135 (query-all-valid-paths 23)
77d3cf08
LC
136 (query-failed-paths 24)
137 (clear-failed-paths 25)
138 (query-path-info 26)
139 (import-paths 27)
63193ebf
LC
140 (query-derivation-output-names 28)
141 (query-path-from-hash-part 29)
142 (query-substitutable-path-infos 30)
143 (query-valid-paths 31)
fae31edc
LC
144 (query-substitutable-paths 32)
145 (query-valid-derivers 33))
77d3cf08
LC
146
147(define-enumerate-type hash-algo
148 ;; hash.hh
149 (md5 1)
150 (sha1 2)
151 (sha256 3))
152
3259877d
LC
153(define-enumerate-type gc-action
154 ;; store-api.hh
155 (return-live 0)
156 (return-dead 1)
157 (delete-dead 2)
158 (delete-specific 3))
159
77d3cf08 160(define %default-socket-path
d8eea3d2
LC
161 (string-append (or (getenv "NIX_STATE_DIR") %state-directory)
162 "/daemon-socket/socket"))
77d3cf08 163
9fd72fb1
LC
164(define %daemon-socket-file
165 ;; File name of the socket the daemon listens too.
166 (make-parameter (or (getenv "GUIX_DAEMON_SOCKET")
167 %default-socket-path)))
168
169
77d3cf08 170\f
0f3d2504
LC
171;; Information about a substitutable store path.
172(define-record-type <substitutable>
173 (substitutable path deriver refs dl-size nar-size)
174 substitutable?
175 (path substitutable-path)
176 (deriver substitutable-deriver)
177 (refs substitutable-references)
178 (dl-size substitutable-download-size)
179 (nar-size substitutable-nar-size))
180
181(define (read-substitutable-path-list p)
182 (let loop ((len (read-int p))
183 (result '()))
184 (if (zero? len)
185 (reverse result)
186 (let ((path (read-store-path p))
187 (deriver (read-store-path p))
188 (refs (read-store-path-list p))
189 (dl-size (read-long-long p))
190 (nar-size (read-long-long p)))
191 (loop (- len 1)
192 (cons (substitutable path deriver refs dl-size nar-size)
193 result))))))
194
77d3cf08 195(define-syntax write-arg
3259877d
LC
196 (syntax-rules (integer boolean file string string-list
197 store-path store-path-list base16)
77d3cf08
LC
198 ((_ integer arg p)
199 (write-int arg p))
200 ((_ boolean arg p)
201 (write-int (if arg 1 0) p))
202 ((_ file arg p)
203 (write-file arg p))
204 ((_ string arg p)
205 (write-string arg p))
206 ((_ string-list arg p)
82058eff 207 (write-string-list arg p))
3259877d
LC
208 ((_ store-path arg p)
209 (write-store-path arg p))
210 ((_ store-path-list arg p)
211 (write-store-path-list arg p))
82058eff
LC
212 ((_ base16 arg p)
213 (write-string (bytevector->base16-string arg) p))))
77d3cf08
LC
214
215(define-syntax read-arg
0f3d2504
LC
216 (syntax-rules (integer boolean string store-path store-path-list
217 substitutable-path-list base16)
77d3cf08
LC
218 ((_ integer p)
219 (read-int p))
220 ((_ boolean p)
221 (not (zero? (read-int p))))
222 ((_ string p)
223 (read-string p))
224 ((_ store-path p)
82058eff 225 (read-store-path p))
3259877d
LC
226 ((_ store-path-list p)
227 (read-store-path-list p))
0f3d2504
LC
228 ((_ substitutable-path-list p)
229 (read-substitutable-path-list p))
230 ((_ base16 p)
82058eff 231 (base16-string->bytevector (read-string p)))))
77d3cf08
LC
232
233\f
234;; remote-store.cc
235
236(define-record-type <nix-server>
2c3f47ee 237 (%make-nix-server socket major minor
bdcf35a6 238 ats-cache atts-cache)
77d3cf08
LC
239 nix-server?
240 (socket nix-server-socket)
241 (major nix-server-major-version)
2c3f47ee
LC
242 (minor nix-server-minor-version)
243
244 ;; Caches. We keep them per-connection, because store paths build
245 ;; during the session are temporary GC roots kept for the duration of
246 ;; the session.
bdcf35a6
LC
247 (ats-cache nix-server-add-to-store-cache)
248 (atts-cache nix-server-add-text-to-store-cache))
77d3cf08 249
bf8e7fc5
LC
250(set-record-type-printer! <nix-server>
251 (lambda (obj port)
252 (format port "#<build-daemon ~a.~a ~a>"
253 (nix-server-major-version obj)
254 (nix-server-minor-version obj)
255 (number->string (object-address obj)
256 16))))
257
e87088c9
LC
258(define-condition-type &nix-error &error
259 nix-error?)
260
ef86c39f
LC
261(define-condition-type &nix-connection-error &nix-error
262 nix-connection-error?
263 (file nix-connection-error-file)
264 (errno nix-connection-error-code))
265
e87088c9
LC
266(define-condition-type &nix-protocol-error &nix-error
267 nix-protocol-error?
268 (message nix-protocol-error-message)
269 (status nix-protocol-error-status))
270
9fd72fb1 271(define* (open-connection #:optional (file (%daemon-socket-file))
e36a7172 272 #:key (reserve-space? #t))
e531ac2a
LC
273 "Connect to the daemon over the Unix-domain socket at FILE. When
274RESERVE-SPACE? is true, instruct it to reserve a little bit of extra
275space on the file system so that the garbage collector can still
276operate, should the disk become full. Return a server object."
77d3cf08
LC
277 (let ((s (with-fluids ((%default-port-encoding #f))
278 ;; This trick allows use of the `scm_c_read' optimization.
279 (socket PF_UNIX SOCK_STREAM 0)))
280 (a (make-socket-address PF_UNIX file)))
df1fab58 281
8c95b27c
LC
282 (catch 'system-error
283 (lambda ()
284 ;; Enlarge the receive buffer.
285 (setsockopt s SOL_SOCKET SO_RCVBUF (* 12 1024)))
286 (lambda args
287 ;; On the Hurd, the pflocal server's implementation of `socket_setopt'
288 ;; always returns ENOPROTOOPT. Ignore it.
289 (unless (= (system-error-errno args) ENOPROTOOPT)
290 (apply throw args))))
df1fab58 291
ef86c39f
LC
292 (catch 'system-error
293 (cut connect s a)
294 (lambda args
295 ;; Translate the error to something user-friendly.
296 (let ((errno (system-error-errno args)))
297 (raise (condition (&nix-connection-error
298 (file file)
299 (errno errno)))))))
300
77d3cf08
LC
301 (write-int %worker-magic-1 s)
302 (let ((r (read-int s)))
303 (and (eqv? r %worker-magic-2)
304 (let ((v (read-int s)))
305 (and (eqv? (protocol-major %protocol-version)
306 (protocol-major v))
307 (begin
308 (write-int %protocol-version s)
e36a7172
LC
309 (if (>= (protocol-minor v) 11)
310 (write-int (if reserve-space? 1 0) s))
77d3cf08
LC
311 (let ((s (%make-nix-server s
312 (protocol-major v)
2c3f47ee 313 (protocol-minor v)
fce2394e
LC
314 (make-hash-table 100)
315 (make-hash-table 100))))
34fcbe3a
LC
316 (let loop ((done? (process-stderr s)))
317 (or done? (process-stderr s)))
77d3cf08
LC
318 s))))))))
319
3abaf0c4
LC
320(define (close-connection server)
321 "Close the connection to SERVER."
322 (close (nix-server-socket server)))
323
dcee50c1
LC
324(define current-build-output-port
325 ;; The port where build output is sent.
326 (make-parameter (current-error-port)))
327
526382ff
LC
328(define* (dump-port in out
329 #:optional len
330 #:key (buffer-size 16384))
331 "Read LEN bytes from IN (or as much as possible if LEN is #f) and write it
332to OUT, using chunks of BUFFER-SIZE bytes."
333 (define buffer
334 (make-bytevector buffer-size))
335
336 (let loop ((total 0)
337 (bytes (get-bytevector-n! in buffer 0
338 (if len
339 (min len buffer-size)
340 buffer-size))))
341 (or (eof-object? bytes)
342 (and len (= total len))
343 (let ((total (+ total bytes)))
344 (put-bytevector out buffer 0 bytes)
345 (loop total
346 (get-bytevector-n! in buffer 0
347 (if len
348 (min (- len total) buffer-size)
349 buffer-size)))))))
350
351(define* (process-stderr server #:optional user-port)
dcee50c1
LC
352 "Read standard output and standard error from SERVER, writing it to
353CURRENT-BUILD-OUTPUT-PORT. Return #t when SERVER is done sending data, and
354#f otherwise; in the latter case, the caller should call `process-stderr'
bbdb3ffa
LC
355again until #t is returned or an error is raised.
356
357Since the build process's output cannot be assumed to be UTF-8, we
358conservatively consider it to be Latin-1, thereby avoiding possible
359encoding conversion errors."
77d3cf08
LC
360 (define p
361 (nix-server-socket server))
362
363 ;; magic cookies from worker-protocol.hh
364 (define %stderr-next #x6f6c6d67)
365 (define %stderr-read #x64617461) ; data needed from source
366 (define %stderr-write #x64617416) ; data for sink
367 (define %stderr-last #x616c7473)
368 (define %stderr-error #x63787470)
369
370 (let ((k (read-int p)))
371 (cond ((= k %stderr-write)
526382ff
LC
372 ;; Write a byte stream to USER-PORT.
373 (let* ((len (read-int p))
374 (m (modulo len 8)))
375 (dump-port p user-port len)
376 (unless (zero? m)
377 ;; Consume padding, as for strings.
378 (get-bytevector-n p (- 8 m))))
dcee50c1 379 #f)
77d3cf08 380 ((= k %stderr-read)
526382ff
LC
381 ;; Read a byte stream from USER-PORT.
382 (let* ((max-len (read-int p))
383 (data (get-bytevector-n user-port max-len))
384 (len (bytevector-length data)))
385 (write-int len p)
386 (put-bytevector p data)
387 (write-padding len p)
dcee50c1 388 #f))
77d3cf08 389 ((= k %stderr-next)
526382ff 390 ;; Log a string.
bbdb3ffa 391 (let ((s (read-latin1-string p)))
dcee50c1
LC
392 (display s (current-build-output-port))
393 #f))
77d3cf08 394 ((= k %stderr-error)
526382ff 395 ;; Report an error.
bbdb3ffa 396 (let ((error (read-latin1-string p))
0ff3e3aa
LC
397 ;; Currently the daemon fails to send a status code for early
398 ;; errors like DB schema version mismatches, so check for EOF.
399 (status (if (and (>= (nix-server-minor-version server) 8)
400 (not (eof-object? (lookahead-u8 p))))
77d3cf08
LC
401 (read-int p)
402 1)))
e87088c9
LC
403 (raise (condition (&nix-protocol-error
404 (message error)
405 (status status))))))
77d3cf08 406 ((= k %stderr-last)
dcee50c1 407 ;; The daemon is done (see `stopWork' in `nix-worker.cc'.)
77d3cf08
LC
408 #t)
409 (else
e87088c9
LC
410 (raise (condition (&nix-protocol-error
411 (message "invalid error code")
412 (status k))))))))
77d3cf08
LC
413
414(define* (set-build-options server
c3eb878f 415 #:key keep-failed? keep-going? fallback?
77d3cf08
LC
416 (verbosity 0)
417 (max-build-jobs (current-processor-count))
418 (max-silent-time 3600)
419 (use-build-hook? #t)
420 (build-verbosity 0)
421 (log-type 0)
e036c31b
LC
422 (print-build-trace #t)
423 (build-cores 1)
63193ebf
LC
424 (use-substitutes? #t)
425 (binary-caches '())) ; client "untrusted" cache URLs
77d3cf08
LC
426 ;; Must be called after `open-connection'.
427
428 (define socket
429 (nix-server-socket server))
430
431 (let-syntax ((send (syntax-rules ()
e036c31b
LC
432 ((_ (type option) ...)
433 (begin
434 (write-arg type option socket)
435 ...)))))
436 (write-int (operation-id set-options) socket)
437 (send (boolean keep-failed?) (boolean keep-going?)
c3eb878f 438 (boolean fallback?) (integer verbosity)
e036c31b 439 (integer max-build-jobs) (integer max-silent-time))
77d3cf08 440 (if (>= (nix-server-minor-version server) 2)
e036c31b 441 (send (boolean use-build-hook?)))
77d3cf08 442 (if (>= (nix-server-minor-version server) 4)
e036c31b
LC
443 (send (integer build-verbosity) (integer log-type)
444 (boolean print-build-trace)))
445 (if (>= (nix-server-minor-version server) 6)
446 (send (integer build-cores)))
447 (if (>= (nix-server-minor-version server) 10)
448 (send (boolean use-substitutes?)))
63193ebf
LC
449 (if (>= (nix-server-minor-version server) 12)
450 (send (string-list (fold-right (lambda (pair result)
451 (match pair
452 ((h . t)
453 (cons* h t result))))
454 '()
455 binary-caches))))
dcee50c1
LC
456 (let loop ((done? (process-stderr server)))
457 (or done? (process-stderr server)))))
77d3cf08 458
fd060fd3 459(define-syntax operation
77d3cf08 460 (syntax-rules ()
fd060fd3 461 "Define a client-side RPC stub for the given operation."
3259877d 462 ((_ (name (type arg) ...) docstring return ...)
fd060fd3 463 (lambda (server arg ...)
77d3cf08
LC
464 docstring
465 (let ((s (nix-server-socket server)))
466 (write-int (operation-id name) s)
467 (write-arg type arg s)
468 ...
dcee50c1
LC
469 ;; Loop until the server is done sending error output.
470 (let loop ((done? (process-stderr server)))
471 (or done? (loop (process-stderr server))))
3259877d 472 (values (read-arg return s) ...))))))
77d3cf08 473
fd060fd3
LC
474(define-syntax-rule (define-operation (name args ...)
475 docstring return ...)
476 (define name
477 (operation (name args ...) docstring return ...)))
478
31ef99a8
LC
479(define-operation (valid-path? (string path))
480 "Return #t when PATH is a valid store path."
481 boolean)
482
63193ebf 483(define-operation (query-path-hash (store-path path))
82058eff
LC
484 "Return the SHA256 hash of PATH as a bytevector."
485 base16)
486
fd060fd3
LC
487(define add-text-to-store
488 ;; A memoizing version of `add-to-store', to avoid repeated RPCs with
489 ;; the very same arguments during a given session.
490 (let ((add-text-to-store
491 (operation (add-text-to-store (string name) (string text)
492 (string-list references))
493 #f
494 store-path)))
cfbf9160 495 (lambda* (server name text #:optional (references '()))
bdcf35a6
LC
496 "Add TEXT under file NAME in the store, and return its store path.
497REFERENCES is the list of store paths referred to by the resulting store
498path."
fce2394e 499 (let ((args `(,text ,name ,references))
bdcf35a6
LC
500 (cache (nix-server-add-text-to-store-cache server)))
501 (or (hash-ref cache args)
fd060fd3 502 (let ((path (add-text-to-store server name text references)))
bdcf35a6
LC
503 (hash-set! cache args path)
504 path))))))
505
fd060fd3 506(define add-to-store
a7b6ffee
LC
507 ;; A memoizing version of `add-to-store'. This is important because
508 ;; `add-to-store' leads to huge data transfers to the server, and
509 ;; because it's often called many times with the very same argument.
fd060fd3
LC
510 (let ((add-to-store (operation (add-to-store (string basename)
511 (boolean fixed?) ; obsolete, must be #t
512 (boolean recursive?)
513 (string hash-algo)
514 (file file-name))
515 #f
516 store-path)))
a9ebd9ef
LC
517 (lambda (server basename recursive? hash-algo file-name)
518 "Add the contents of FILE-NAME under BASENAME to the store. When
519RECURSIVE? is true and FILE-NAME designates a directory, the contents of
520FILE-NAME are added recursively; if FILE-NAME designates a flat file and
521RECURSIVE? is true, its contents are added, and its permission bits are
522kept. HASH-ALGO must be a string such as \"sha256\"."
2c3f47ee 523 (let* ((st (stat file-name #f))
fce2394e 524 (args `(,st ,basename ,recursive? ,hash-algo))
2c3f47ee 525 (cache (nix-server-add-to-store-cache server)))
a7b6ffee 526 (or (and st (hash-ref cache args))
a9ebd9ef 527 (let ((path (add-to-store server basename #t recursive?
a7b6ffee
LC
528 hash-algo file-name)))
529 (hash-set! cache args path)
530 path))))))
531
77d3cf08 532(define-operation (build-derivations (string-list derivations))
dcee50c1
LC
533 "Build DERIVATIONS, and return when the worker is done building them.
534Return #t on success."
77d3cf08 535 boolean)
26bbbb95 536
d3648e01
LC
537(define-operation (add-temp-root (store-path path))
538 "Make PATH a temporary root for the duration of the current session.
539Return #t."
540 boolean)
541
34811f02
LC
542(define-operation (add-indirect-root (string file-name))
543 "Make FILE-NAME an indirect root for the garbage collector; FILE-NAME
544can be anywhere on the file system, but it must be an absolute file
545name--it is the caller's responsibility to ensure that it is an absolute
546file name. Return #t on success."
547 boolean)
548
fae31edc
LC
549(define references
550 (operation (query-references (store-path path))
551 "Return the list of references of PATH."
552 store-path-list))
553
3f1e6939
LC
554(define* (fold-path store proc seed path
555 #:optional (relatives (cut references store <>)))
556 "Call PROC for each of the RELATIVES of PATH, exactly once, and return the
557result formed from the successive calls to PROC, the first of which is passed
558SEED."
559 (let loop ((paths (list path))
560 (result seed)
561 (seen vlist-null))
562 (match paths
563 ((path rest ...)
564 (if (vhash-assoc path seen)
565 (loop rest result seen)
566 (let ((seen (vhash-cons path #t seen))
567 (rest (append rest (relatives path)))
568 (result (proc path result)))
569 (loop rest result seen))))
570 (()
571 result))))
572
573(define (requisites store path)
574 "Return the requisites of PATH, including PATH---i.e., its closure (all its
575references, recursively)."
576 (fold-path store cons '() path))
577
fae31edc
LC
578(define referrers
579 (operation (query-referrers (store-path path))
580 "Return the list of path that refer to PATH."
581 store-path-list))
582
583(define valid-derivers
584 (operation (query-valid-derivers (store-path path))
585 "Return the list of valid \"derivers\" of PATH---i.e., all the
586.drv present in the store that have PATH among their outputs."
587 store-path-list))
588
589(define query-derivation-outputs ; avoid name clash with `derivation-outputs'
590 (operation (query-derivation-outputs (store-path path))
591 "Return the list of outputs of PATH, a .drv file."
592 store-path-list))
593
0f3d2504
LC
594(define-operation (has-substitutes? (store-path path))
595 "Return #t if binary substitutes are available for PATH, and #f otherwise."
596 boolean)
597
598(define substitutable-paths
599 (operation (query-substitutable-paths (store-path-list paths))
600 "Return the subset of PATHS that is substitutable."
601 store-path-list))
602
603(define substitutable-path-info
f65cf81a 604 (operation (query-substitutable-path-infos (store-path-list paths))
0f3d2504
LC
605 "Return information about the subset of PATHS that is
606substitutable. For each substitutable path, a `substitutable?' object is
607returned."
608 substitutable-path-list))
609
3259877d
LC
610(define (run-gc server action to-delete min-freed)
611 "Perform the garbage-collector operation ACTION, one of the
612`gc-action' values. When ACTION is `delete-specific', the TO-DELETE is
613the list of store paths to delete. IGNORE-LIVENESS? should always be
614#f. MIN-FREED is the minimum amount of disk space to be freed, in
615bytes, before the GC can stop. Return the list of store paths delete,
616and the number of bytes freed."
617 (let ((s (nix-server-socket server)))
618 (write-int (operation-id collect-garbage) s)
619 (write-int action s)
620 (write-store-path-list to-delete s)
621 (write-arg boolean #f s) ; ignore-liveness?
622 (write-long-long min-freed s)
623 (write-int 0 s) ; obsolete
624 (when (>= (nix-server-minor-version server) 5)
625 ;; Obsolete `use-atime' and `max-atime' parameters.
626 (write-int 0 s)
627 (write-int 0 s))
628
629 ;; Loop until the server is done sending error output.
630 (let loop ((done? (process-stderr server)))
631 (or done? (loop (process-stderr server))))
632
633 (let ((paths (read-store-path-list s))
634 (freed (read-long-long s))
635 (obsolete (read-long-long s)))
636 (values paths freed))))
637
638(define-syntax-rule (%long-long-max)
639 ;; Maximum unsigned 64-bit integer.
640 (- (expt 2 64) 1))
641
642(define (live-paths server)
643 "Return the list of live store paths---i.e., store paths still
644referenced, and thus not subject to being garbage-collected."
645 (run-gc server (gc-action return-live) '() (%long-long-max)))
646
647(define (dead-paths server)
648 "Return the list of dead store paths---i.e., store paths no longer
649referenced, and thus subject to being garbage-collected."
650 (run-gc server (gc-action return-dead) '() (%long-long-max)))
651
652(define* (collect-garbage server #:optional (min-freed (%long-long-max)))
653 "Collect garbage from the store at SERVER. If MIN-FREED is non-zero,
654then collect at least MIN-FREED bytes. Return the paths that were
655collected, and the number of bytes freed."
656 (run-gc server (gc-action delete-dead) '() min-freed))
657
658(define* (delete-paths server paths #:optional (min-freed (%long-long-max)))
659 "Delete PATHS from the store at SERVER, if they are no longer
660referenced. If MIN-FREED is non-zero, then stop after at least
661MIN-FREED bytes have been collected. Return the paths that were
662collected, and the number of bytes freed."
663 (run-gc server (gc-action delete-specific) paths min-freed))
664
526382ff
LC
665(define (import-paths server port)
666 "Import the set of store paths read from PORT into SERVER's store. An error
667is raised if the set of paths read from PORT is not signed (as per
668'export-path #:sign? #t'.) Return the list of store paths imported."
669 (let ((s (nix-server-socket server)))
670 (write-int (operation-id import-paths) s)
671 (let loop ((done? (process-stderr server port)))
672 (or done? (loop (process-stderr server port))))
673 (read-store-path-list s)))
674
675(define* (export-path server path port #:key (sign? #t))
676 "Export PATH to PORT. When SIGN? is true, sign it."
677 (let ((s (nix-server-socket server)))
678 (write-int (operation-id export-path) s)
679 (write-store-path path s)
680 (write-arg boolean sign? s)
681 (let loop ((done? (process-stderr server port)))
682 (or done? (loop (process-stderr server port))))
683 (= 1 (read-int s))))
684
685(define* (export-paths server paths port #:key (sign? #t))
686 "Export the store paths listed in PATHS to PORT, signing them if SIGN?
687is true."
688 (let ((s (nix-server-socket server)))
689 (let loop ((paths paths))
690 (match paths
691 (()
692 (write-int 0 port))
693 ((head tail ...)
694 (write-int 1 port)
695 (and (export-path server head port #:sign? sign?)
696 (loop tail)))))))
697
26bbbb95
LC
698\f
699;;;
700;;; Store paths.
701;;;
702
703(define %store-prefix
704 ;; Absolute path to the Nix store.
cd3ded43 705 (make-parameter (or (and=> (getenv "NIX_STORE_DIR") canonicalize-path)
d8eea3d2 706 %store-directory)))
26bbbb95 707
f39bd08a
LC
708(define (store-path? path)
709 "Return #t if PATH is a store path."
710 ;; This is a lightweight check, compared to using a regexp, but this has to
711 ;; be fast as it's called often in `derivation', for instance.
712 ;; `isStorePath' in Nix does something similar.
713 (string-prefix? (%store-prefix) path))
26bbbb95 714
9336e5b5
LC
715(define (direct-store-path? path)
716 "Return #t if PATH is a store path, and not a sub-directory of a store path.
717This predicate is sometimes needed because files *under* a store path are not
718valid inputs."
719 (and (store-path? path)
720 (let ((len (+ 1 (string-length (%store-prefix)))))
721 (not (string-index (substring path len) #\/)))))
722
26bbbb95
LC
723(define (derivation-path? path)
724 "Return #t if PATH is a derivation path."
725 (and (store-path? path) (string-suffix? ".drv" path)))
e3d74106 726
5c0f1845
LC
727(define store-regexp*
728 ;; The substituter makes repeated calls to 'store-path-hash-part', hence
729 ;; this optimization.
730 (memoize
731 (lambda (store)
732 "Return a regexp matching a file in STORE."
733 (make-regexp (string-append "^" (regexp-quote store)
734 "/([0-9a-df-np-sv-z]{32})-([^/]+)$")))))
735
e3d74106
LC
736(define (store-path-package-name path)
737 "Return the package name part of PATH, a file name in the store."
5c0f1845
LC
738 (let ((path-rx (store-regexp* (%store-prefix))))
739 (and=> (regexp-exec path-rx path)
740 (cut match:substring <> 2))))
2c6ab6cc
LC
741
742(define (store-path-hash-part path)
743 "Return the hash part of PATH as a base32 string, or #f if PATH is not a
744syntactically valid store path."
5c0f1845 745 (let ((path-rx (store-regexp* (%store-prefix))))
2c6ab6cc
LC
746 (and=> (regexp-exec path-rx path)
747 (cut match:substring <> 1))))
eddd4077
LC
748
749(define (log-file store file)
750 "Return the build log file for FILE, or #f if none could be found. FILE
751must be an absolute store file name, or a derivation file name."
752 (define state-dir ; XXX: factorize
753 (or (getenv "NIX_STATE_DIR") %state-directory))
754
755 (cond ((derivation-path? file)
756 (let* ((base (basename file))
757 (log (string-append (dirname state-dir) ; XXX: ditto
758 "/log/nix/drvs/"
759 (string-take base 2) "/"
760 (string-drop base 2) ".bz2")))
761 (and (file-exists? log) log)))
762 (else
763 (match (valid-derivers store file)
764 ((derivers ...)
765 ;; Return the first that works.
766 (any (cut log-file store <>) derivers))
767 (_ #f)))))