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