tests: Add 'with-derivation-substitute' and use it.
[jackhill/guix/guix.git] / guix / store.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
e87f0591 2;;; Copyright © 2012, 2013, 2014, 2015 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)
82058eff 20 #:use-module (guix utils)
d8eea3d2 21 #:use-module (guix config)
0f41c26f 22 #:use-module (guix serialization)
e87f0591 23 #:use-module (guix monads)
a9d2a105 24 #:autoload (guix base32) (bytevector->base32-string)
77d3cf08
LC
25 #:use-module (rnrs bytevectors)
26 #:use-module (rnrs io ports)
27 #:use-module (srfi srfi-1)
28 #:use-module (srfi srfi-9)
bf8e7fc5 29 #:use-module (srfi srfi-9 gnu)
77d3cf08 30 #:use-module (srfi srfi-26)
e87088c9
LC
31 #:use-module (srfi srfi-34)
32 #:use-module (srfi srfi-35)
26bbbb95 33 #:use-module (srfi srfi-39)
77d3cf08 34 #:use-module (ice-9 match)
e3d74106 35 #:use-module (ice-9 regex)
3f1e6939 36 #:use-module (ice-9 vlist)
6bfec3ed 37 #:use-module (ice-9 popen)
9fd72fb1 38 #:export (%daemon-socket-file
a9d2a105 39 %gc-roots-directory
9fd72fb1
LC
40
41 nix-server?
77d3cf08
LC
42 nix-server-major-version
43 nix-server-minor-version
44 nix-server-socket
45
e87088c9 46 &nix-error nix-error?
ef86c39f
LC
47 &nix-connection-error nix-connection-error?
48 nix-connection-error-file
49 nix-connection-error-code
e87088c9
LC
50 &nix-protocol-error nix-protocol-error?
51 nix-protocol-error-message
52 nix-protocol-error-status
53
26bbbb95
LC
54 hash-algo
55
77d3cf08 56 open-connection
3abaf0c4 57 close-connection
ce4a4829 58 with-store
77d3cf08 59 set-build-options
31ef99a8 60 valid-path?
82058eff 61 query-path-hash
11e7a6cf 62 hash-part->path
77d3cf08
LC
63 add-text-to-store
64 add-to-store
26bbbb95 65 build-derivations
3259877d 66 add-temp-root
34811f02 67 add-indirect-root
a9d2a105
LC
68 add-permanent-root
69 remove-permanent-root
26bbbb95 70
0f3d2504
LC
71 substitutable?
72 substitutable-path
73 substitutable-deriver
74 substitutable-references
75 substitutable-download-size
76 substitutable-nar-size
77 has-substitutes?
78 substitutable-paths
79 substitutable-path-info
80
fae31edc 81 references
3f1e6939 82 requisites
fae31edc 83 referrers
50add477 84 topologically-sorted
fae31edc
LC
85 valid-derivers
86 query-derivation-outputs
3259877d
LC
87 live-paths
88 dead-paths
89 collect-garbage
90 delete-paths
526382ff
LC
91 import-paths
92 export-paths
3259877d 93
dcee50c1
LC
94 current-build-output-port
95
6bfec3ed
LC
96 register-path
97
e87f0591
LC
98 %store-monad
99 store-bind
100 store-return
101 store-lift
023d9892 102 store-lower
e87f0591
LC
103 run-with-store
104 %guile-for-build
105 text-file
106 interned-file
107
26bbbb95
LC
108 %store-prefix
109 store-path?
9336e5b5 110 direct-store-path?
e3d74106 111 derivation-path?
2c6ab6cc 112 store-path-package-name
eddd4077
LC
113 store-path-hash-part
114 log-file))
77d3cf08 115
63193ebf 116(define %protocol-version #x10c)
77d3cf08 117
d66b704b
LC
118(define %worker-magic-1 #x6e697863) ; "nixc"
119(define %worker-magic-2 #x6478696f) ; "dxio"
77d3cf08
LC
120
121(define (protocol-major magic)
122 (logand magic #xff00))
123(define (protocol-minor magic)
124 (logand magic #x00ff))
125
126(define-syntax define-enumerate-type
127 (syntax-rules ()
128 ((_ name->int (name id) ...)
129 (define-syntax name->int
130 (syntax-rules (name ...)
131 ((_ name) id) ...)))))
132
133(define-enumerate-type operation-id
134 ;; operation numbers from worker-protocol.hh
135 (quit 0)
136 (valid-path? 1)
137 (has-substitutes? 3)
138 (query-path-hash 4)
139 (query-references 5)
140 (query-referrers 6)
141 (add-to-store 7)
142 (add-text-to-store 8)
143 (build-derivations 9)
144 (ensure-path 10)
145 (add-temp-root 11)
146 (add-indirect-root 12)
147 (sync-with-gc 13)
148 (find-roots 14)
149 (export-path 16)
150 (query-deriver 18)
151 (set-options 19)
152 (collect-garbage 20)
63193ebf 153 ;;(query-substitutable-path-info 21) ; obsolete as of #x10c
77d3cf08 154 (query-derivation-outputs 22)
63193ebf 155 (query-all-valid-paths 23)
77d3cf08
LC
156 (query-failed-paths 24)
157 (clear-failed-paths 25)
158 (query-path-info 26)
159 (import-paths 27)
63193ebf
LC
160 (query-derivation-output-names 28)
161 (query-path-from-hash-part 29)
162 (query-substitutable-path-infos 30)
163 (query-valid-paths 31)
fae31edc
LC
164 (query-substitutable-paths 32)
165 (query-valid-derivers 33))
77d3cf08
LC
166
167(define-enumerate-type hash-algo
168 ;; hash.hh
169 (md5 1)
170 (sha1 2)
171 (sha256 3))
172
3259877d
LC
173(define-enumerate-type gc-action
174 ;; store-api.hh
175 (return-live 0)
176 (return-dead 1)
177 (delete-dead 2)
178 (delete-specific 3))
179
77d3cf08 180(define %default-socket-path
80d0447c 181 (string-append %state-directory "/daemon-socket/socket"))
77d3cf08 182
9fd72fb1
LC
183(define %daemon-socket-file
184 ;; File name of the socket the daemon listens too.
185 (make-parameter (or (getenv "GUIX_DAEMON_SOCKET")
186 %default-socket-path)))
187
188
77d3cf08 189\f
0f3d2504
LC
190;; Information about a substitutable store path.
191(define-record-type <substitutable>
192 (substitutable path deriver refs dl-size nar-size)
193 substitutable?
194 (path substitutable-path)
195 (deriver substitutable-deriver)
196 (refs substitutable-references)
197 (dl-size substitutable-download-size)
198 (nar-size substitutable-nar-size))
199
200(define (read-substitutable-path-list p)
201 (let loop ((len (read-int p))
202 (result '()))
203 (if (zero? len)
204 (reverse result)
205 (let ((path (read-store-path p))
206 (deriver (read-store-path p))
207 (refs (read-store-path-list p))
208 (dl-size (read-long-long p))
209 (nar-size (read-long-long p)))
210 (loop (- len 1)
211 (cons (substitutable path deriver refs dl-size nar-size)
212 result))))))
213
77d3cf08 214(define-syntax write-arg
6c20d1d0 215 (syntax-rules (integer boolean file string string-list string-pairs
3259877d 216 store-path store-path-list base16)
77d3cf08
LC
217 ((_ integer arg p)
218 (write-int arg p))
219 ((_ boolean arg p)
220 (write-int (if arg 1 0) p))
221 ((_ file arg p)
222 (write-file arg p))
223 ((_ string arg p)
224 (write-string arg p))
225 ((_ string-list arg p)
82058eff 226 (write-string-list arg p))
6c20d1d0
LC
227 ((_ string-pairs arg p)
228 (write-string-pairs arg p))
3259877d
LC
229 ((_ store-path arg p)
230 (write-store-path arg p))
231 ((_ store-path-list arg p)
232 (write-store-path-list arg p))
82058eff
LC
233 ((_ base16 arg p)
234 (write-string (bytevector->base16-string arg) p))))
77d3cf08
LC
235
236(define-syntax read-arg
0f3d2504
LC
237 (syntax-rules (integer boolean string store-path store-path-list
238 substitutable-path-list base16)
77d3cf08
LC
239 ((_ integer p)
240 (read-int p))
241 ((_ boolean p)
242 (not (zero? (read-int p))))
243 ((_ string p)
244 (read-string p))
245 ((_ store-path p)
82058eff 246 (read-store-path p))
3259877d
LC
247 ((_ store-path-list p)
248 (read-store-path-list p))
0f3d2504
LC
249 ((_ substitutable-path-list p)
250 (read-substitutable-path-list p))
251 ((_ base16 p)
82058eff 252 (base16-string->bytevector (read-string p)))))
77d3cf08
LC
253
254\f
255;; remote-store.cc
256
257(define-record-type <nix-server>
2c3f47ee 258 (%make-nix-server socket major minor
bdcf35a6 259 ats-cache atts-cache)
77d3cf08
LC
260 nix-server?
261 (socket nix-server-socket)
262 (major nix-server-major-version)
2c3f47ee
LC
263 (minor nix-server-minor-version)
264
265 ;; Caches. We keep them per-connection, because store paths build
266 ;; during the session are temporary GC roots kept for the duration of
267 ;; the session.
bdcf35a6
LC
268 (ats-cache nix-server-add-to-store-cache)
269 (atts-cache nix-server-add-text-to-store-cache))
77d3cf08 270
bf8e7fc5
LC
271(set-record-type-printer! <nix-server>
272 (lambda (obj port)
273 (format port "#<build-daemon ~a.~a ~a>"
274 (nix-server-major-version obj)
275 (nix-server-minor-version obj)
276 (number->string (object-address obj)
277 16))))
278
e87088c9
LC
279(define-condition-type &nix-error &error
280 nix-error?)
281
ef86c39f
LC
282(define-condition-type &nix-connection-error &nix-error
283 nix-connection-error?
284 (file nix-connection-error-file)
285 (errno nix-connection-error-code))
286
e87088c9
LC
287(define-condition-type &nix-protocol-error &nix-error
288 nix-protocol-error?
289 (message nix-protocol-error-message)
290 (status nix-protocol-error-status))
291
9fd72fb1 292(define* (open-connection #:optional (file (%daemon-socket-file))
e36a7172 293 #:key (reserve-space? #t))
e531ac2a
LC
294 "Connect to the daemon over the Unix-domain socket at FILE. When
295RESERVE-SPACE? is true, instruct it to reserve a little bit of extra
296space on the file system so that the garbage collector can still
297operate, should the disk become full. Return a server object."
77d3cf08
LC
298 (let ((s (with-fluids ((%default-port-encoding #f))
299 ;; This trick allows use of the `scm_c_read' optimization.
300 (socket PF_UNIX SOCK_STREAM 0)))
301 (a (make-socket-address PF_UNIX file)))
df1fab58 302
ef86c39f
LC
303 (catch 'system-error
304 (cut connect s a)
305 (lambda args
306 ;; Translate the error to something user-friendly.
307 (let ((errno (system-error-errno args)))
308 (raise (condition (&nix-connection-error
309 (file file)
310 (errno errno)))))))
311
77d3cf08
LC
312 (write-int %worker-magic-1 s)
313 (let ((r (read-int s)))
314 (and (eqv? r %worker-magic-2)
315 (let ((v (read-int s)))
316 (and (eqv? (protocol-major %protocol-version)
317 (protocol-major v))
318 (begin
319 (write-int %protocol-version s)
e36a7172
LC
320 (if (>= (protocol-minor v) 11)
321 (write-int (if reserve-space? 1 0) s))
77d3cf08
LC
322 (let ((s (%make-nix-server s
323 (protocol-major v)
2c3f47ee 324 (protocol-minor v)
fce2394e
LC
325 (make-hash-table 100)
326 (make-hash-table 100))))
34fcbe3a
LC
327 (let loop ((done? (process-stderr s)))
328 (or done? (process-stderr s)))
77d3cf08
LC
329 s))))))))
330
3abaf0c4
LC
331(define (close-connection server)
332 "Close the connection to SERVER."
333 (close (nix-server-socket server)))
334
ce4a4829
LC
335(define-syntax-rule (with-store store exp ...)
336 "Bind STORE to an open connection to the store and evaluate EXPs;
337automatically close the store when the dynamic extent of EXP is left."
338 (let ((store (open-connection)))
339 (dynamic-wind
340 (const #f)
341 (lambda ()
342 exp ...)
343 (lambda ()
344 (false-if-exception (close-connection store))))))
345
dcee50c1
LC
346(define current-build-output-port
347 ;; The port where build output is sent.
348 (make-parameter (current-error-port)))
349
526382ff
LC
350(define* (dump-port in out
351 #:optional len
352 #:key (buffer-size 16384))
353 "Read LEN bytes from IN (or as much as possible if LEN is #f) and write it
354to OUT, using chunks of BUFFER-SIZE bytes."
355 (define buffer
356 (make-bytevector buffer-size))
357
358 (let loop ((total 0)
359 (bytes (get-bytevector-n! in buffer 0
360 (if len
361 (min len buffer-size)
362 buffer-size))))
363 (or (eof-object? bytes)
364 (and len (= total len))
365 (let ((total (+ total bytes)))
366 (put-bytevector out buffer 0 bytes)
367 (loop total
368 (get-bytevector-n! in buffer 0
369 (if len
370 (min (- len total) buffer-size)
371 buffer-size)))))))
372
d28869af
LC
373(define %newlines
374 ;; Newline characters triggering a flush of 'current-build-output-port'.
375 ;; Unlike Guile's _IOLBF, we flush upon #\return so that progress reports
376 ;; that use that trick are correctly displayed.
377 (char-set #\newline #\return))
378
526382ff 379(define* (process-stderr server #:optional user-port)
dcee50c1
LC
380 "Read standard output and standard error from SERVER, writing it to
381CURRENT-BUILD-OUTPUT-PORT. Return #t when SERVER is done sending data, and
382#f otherwise; in the latter case, the caller should call `process-stderr'
bbdb3ffa
LC
383again until #t is returned or an error is raised.
384
385Since the build process's output cannot be assumed to be UTF-8, we
386conservatively consider it to be Latin-1, thereby avoiding possible
387encoding conversion errors."
77d3cf08
LC
388 (define p
389 (nix-server-socket server))
390
391 ;; magic cookies from worker-protocol.hh
5674a3fd
LC
392 (define %stderr-next #x6f6c6d67) ; "olmg", build log
393 (define %stderr-read #x64617461) ; "data", data needed from source
394 (define %stderr-write #x64617416) ; "dat\x16", data for sink
395 (define %stderr-last #x616c7473) ; "alts", we're done
396 (define %stderr-error #x63787470) ; "cxtp", error reporting
77d3cf08
LC
397
398 (let ((k (read-int p)))
399 (cond ((= k %stderr-write)
526382ff
LC
400 ;; Write a byte stream to USER-PORT.
401 (let* ((len (read-int p))
402 (m (modulo len 8)))
403 (dump-port p user-port len)
404 (unless (zero? m)
405 ;; Consume padding, as for strings.
406 (get-bytevector-n p (- 8 m))))
dcee50c1 407 #f)
77d3cf08 408 ((= k %stderr-read)
526382ff 409 ;; Read a byte stream from USER-PORT.
5895f244
LC
410 ;; Note: Avoid 'get-bytevector-n' to work around
411 ;; <http://bugs.gnu.org/17591> in Guile up to 2.0.11.
526382ff 412 (let* ((max-len (read-int p))
5895f244
LC
413 (data (make-bytevector max-len))
414 (len (get-bytevector-n! user-port data 0 max-len)))
526382ff 415 (write-int len p)
5895f244 416 (put-bytevector p data 0 len)
526382ff 417 (write-padding len p)
dcee50c1 418 #f))
77d3cf08 419 ((= k %stderr-next)
526382ff 420 ;; Log a string.
bbdb3ffa 421 (let ((s (read-latin1-string p)))
dcee50c1 422 (display s (current-build-output-port))
d28869af
LC
423 (when (string-any %newlines s)
424 (flush-output-port (current-build-output-port)))
dcee50c1 425 #f))
77d3cf08 426 ((= k %stderr-error)
526382ff 427 ;; Report an error.
bbdb3ffa 428 (let ((error (read-latin1-string p))
0ff3e3aa
LC
429 ;; Currently the daemon fails to send a status code for early
430 ;; errors like DB schema version mismatches, so check for EOF.
431 (status (if (and (>= (nix-server-minor-version server) 8)
432 (not (eof-object? (lookahead-u8 p))))
77d3cf08
LC
433 (read-int p)
434 1)))
e87088c9
LC
435 (raise (condition (&nix-protocol-error
436 (message error)
437 (status status))))))
77d3cf08 438 ((= k %stderr-last)
dcee50c1 439 ;; The daemon is done (see `stopWork' in `nix-worker.cc'.)
77d3cf08
LC
440 #t)
441 (else
e87088c9
LC
442 (raise (condition (&nix-protocol-error
443 (message "invalid error code")
444 (status k))))))))
77d3cf08
LC
445
446(define* (set-build-options server
c3eb878f 447 #:key keep-failed? keep-going? fallback?
77d3cf08 448 (verbosity 0)
8b47758f 449 (max-build-jobs 1)
6c20d1d0 450 timeout
77d3cf08
LC
451 (max-silent-time 3600)
452 (use-build-hook? #t)
453 (build-verbosity 0)
454 (log-type 0)
e036c31b 455 (print-build-trace #t)
8b47758f 456 (build-cores (current-processor-count))
63193ebf
LC
457 (use-substitutes? #t)
458 (binary-caches '())) ; client "untrusted" cache URLs
77d3cf08
LC
459 ;; Must be called after `open-connection'.
460
461 (define socket
462 (nix-server-socket server))
463
464 (let-syntax ((send (syntax-rules ()
e036c31b
LC
465 ((_ (type option) ...)
466 (begin
467 (write-arg type option socket)
468 ...)))))
469 (write-int (operation-id set-options) socket)
470 (send (boolean keep-failed?) (boolean keep-going?)
c3eb878f 471 (boolean fallback?) (integer verbosity)
e036c31b 472 (integer max-build-jobs) (integer max-silent-time))
371e87d2
LC
473 (when (>= (nix-server-minor-version server) 2)
474 (send (boolean use-build-hook?)))
475 (when (>= (nix-server-minor-version server) 4)
476 (send (integer build-verbosity) (integer log-type)
477 (boolean print-build-trace)))
478 (when (>= (nix-server-minor-version server) 6)
479 (send (integer build-cores)))
480 (when (>= (nix-server-minor-version server) 10)
481 (send (boolean use-substitutes?)))
482 (when (>= (nix-server-minor-version server) 12)
6c20d1d0
LC
483 (let ((pairs (if timeout
484 `(("build-timeout" . ,(number->string timeout))
485 ,@binary-caches)
486 binary-caches)))
487 (send (string-pairs pairs))))
dcee50c1
LC
488 (let loop ((done? (process-stderr server)))
489 (or done? (process-stderr server)))))
77d3cf08 490
fd060fd3 491(define-syntax operation
77d3cf08 492 (syntax-rules ()
fd060fd3 493 "Define a client-side RPC stub for the given operation."
3259877d 494 ((_ (name (type arg) ...) docstring return ...)
fd060fd3 495 (lambda (server arg ...)
77d3cf08
LC
496 docstring
497 (let ((s (nix-server-socket server)))
498 (write-int (operation-id name) s)
499 (write-arg type arg s)
500 ...
dcee50c1
LC
501 ;; Loop until the server is done sending error output.
502 (let loop ((done? (process-stderr server)))
503 (or done? (loop (process-stderr server))))
3259877d 504 (values (read-arg return s) ...))))))
77d3cf08 505
fd060fd3
LC
506(define-syntax-rule (define-operation (name args ...)
507 docstring return ...)
508 (define name
509 (operation (name args ...) docstring return ...)))
510
31ef99a8
LC
511(define-operation (valid-path? (string path))
512 "Return #t when PATH is a valid store path."
513 boolean)
514
63193ebf 515(define-operation (query-path-hash (store-path path))
82058eff
LC
516 "Return the SHA256 hash of PATH as a bytevector."
517 base16)
518
11e7a6cf
LC
519(define hash-part->path
520 (let ((query-path-from-hash-part
521 (operation (query-path-from-hash-part (string hash))
522 #f
523 store-path)))
524 (lambda (server hash-part)
525 "Return the store path whose hash part is HASH-PART (a nix-base32
526string). Raise an error if no such path exists."
527 ;; This RPC is primarily used by Hydra to reply to HTTP GETs of
528 ;; /HASH.narinfo.
529 (query-path-from-hash-part server hash-part))))
530
fd060fd3
LC
531(define add-text-to-store
532 ;; A memoizing version of `add-to-store', to avoid repeated RPCs with
533 ;; the very same arguments during a given session.
534 (let ((add-text-to-store
535 (operation (add-text-to-store (string name) (string text)
536 (string-list references))
537 #f
538 store-path)))
cfbf9160 539 (lambda* (server name text #:optional (references '()))
bdcf35a6
LC
540 "Add TEXT under file NAME in the store, and return its store path.
541REFERENCES is the list of store paths referred to by the resulting store
542path."
fce2394e 543 (let ((args `(,text ,name ,references))
bdcf35a6
LC
544 (cache (nix-server-add-text-to-store-cache server)))
545 (or (hash-ref cache args)
fd060fd3 546 (let ((path (add-text-to-store server name text references)))
bdcf35a6
LC
547 (hash-set! cache args path)
548 path))))))
549
fd060fd3 550(define add-to-store
a7b6ffee
LC
551 ;; A memoizing version of `add-to-store'. This is important because
552 ;; `add-to-store' leads to huge data transfers to the server, and
553 ;; because it's often called many times with the very same argument.
fd060fd3
LC
554 (let ((add-to-store (operation (add-to-store (string basename)
555 (boolean fixed?) ; obsolete, must be #t
556 (boolean recursive?)
557 (string hash-algo)
558 (file file-name))
559 #f
560 store-path)))
a9ebd9ef
LC
561 (lambda (server basename recursive? hash-algo file-name)
562 "Add the contents of FILE-NAME under BASENAME to the store. When
563RECURSIVE? is true and FILE-NAME designates a directory, the contents of
564FILE-NAME are added recursively; if FILE-NAME designates a flat file and
565RECURSIVE? is true, its contents are added, and its permission bits are
566kept. HASH-ALGO must be a string such as \"sha256\"."
2c3f47ee 567 (let* ((st (stat file-name #f))
fce2394e 568 (args `(,st ,basename ,recursive? ,hash-algo))
2c3f47ee 569 (cache (nix-server-add-to-store-cache server)))
a7b6ffee 570 (or (and st (hash-ref cache args))
a9ebd9ef 571 (let ((path (add-to-store server basename #t recursive?
a7b6ffee
LC
572 hash-algo file-name)))
573 (hash-set! cache args path)
574 path))))))
575
77d3cf08 576(define-operation (build-derivations (string-list derivations))
dcee50c1
LC
577 "Build DERIVATIONS, and return when the worker is done building them.
578Return #t on success."
77d3cf08 579 boolean)
26bbbb95 580
d3648e01
LC
581(define-operation (add-temp-root (store-path path))
582 "Make PATH a temporary root for the duration of the current session.
583Return #t."
584 boolean)
585
34811f02 586(define-operation (add-indirect-root (string file-name))
a9d2a105
LC
587 "Make the symlink FILE-NAME an indirect root for the garbage collector:
588whatever store item FILE-NAME points to will not be collected. Return #t on
589success.
590
591FILE-NAME can be anywhere on the file system, but it must be an absolute file
592name--it is the caller's responsibility to ensure that it is an absolute file
593name."
34811f02
LC
594 boolean)
595
a9d2a105
LC
596(define %gc-roots-directory
597 ;; The place where garbage collector roots (symlinks) are kept.
598 (string-append %state-directory "/gcroots"))
599
600(define (add-permanent-root target)
601 "Add a garbage collector root pointing to TARGET, an element of the store,
602preventing TARGET from even being collected. This can also be used if TARGET
603does not exist yet.
604
605Raise an error if the caller does not have write access to the GC root
606directory."
607 (let* ((root (string-append %gc-roots-directory "/" (basename target))))
608 (catch 'system-error
609 (lambda ()
610 (symlink target root))
611 (lambda args
612 ;; If ROOT already exists, this is fine; otherwise, re-throw.
613 (unless (= EEXIST (system-error-errno args))
614 (apply throw args))))))
615
616(define (remove-permanent-root target)
617 "Remove the permanent garbage collector root pointing to TARGET. Raise an
618error if there is no such root."
619 (delete-file (string-append %gc-roots-directory "/" (basename target))))
620
fae31edc
LC
621(define references
622 (operation (query-references (store-path path))
623 "Return the list of references of PATH."
624 store-path-list))
625
3f1e6939
LC
626(define* (fold-path store proc seed path
627 #:optional (relatives (cut references store <>)))
628 "Call PROC for each of the RELATIVES of PATH, exactly once, and return the
629result formed from the successive calls to PROC, the first of which is passed
630SEED."
631 (let loop ((paths (list path))
632 (result seed)
633 (seen vlist-null))
634 (match paths
635 ((path rest ...)
636 (if (vhash-assoc path seen)
637 (loop rest result seen)
638 (let ((seen (vhash-cons path #t seen))
639 (rest (append rest (relatives path)))
640 (result (proc path result)))
641 (loop rest result seen))))
642 (()
643 result))))
644
645(define (requisites store path)
646 "Return the requisites of PATH, including PATH---i.e., its closure (all its
647references, recursively)."
648 (fold-path store cons '() path))
649
50add477
LC
650(define (topologically-sorted store paths)
651 "Return a list containing PATHS and all their references sorted in
652topological order."
653 (define (traverse)
654 ;; Do a simple depth-first traversal of all of PATHS.
655 (let loop ((paths paths)
656 (visited vlist-null)
657 (result '()))
658 (define (visit n)
659 (vhash-cons n #t visited))
660
661 (define (visited? n)
662 (vhash-assoc n visited))
663
664 (match paths
665 ((head tail ...)
666 (if (visited? head)
667 (loop tail visited result)
668 (call-with-values
669 (lambda ()
670 (loop (references store head)
671 (visit head)
672 result))
673 (lambda (visited result)
674 (loop tail
675 visited
676 (cons head result))))))
677 (()
678 (values visited result)))))
679
680 (call-with-values traverse
681 (lambda (_ result)
682 (reverse result))))
683
fae31edc
LC
684(define referrers
685 (operation (query-referrers (store-path path))
686 "Return the list of path that refer to PATH."
687 store-path-list))
688
689(define valid-derivers
690 (operation (query-valid-derivers (store-path path))
691 "Return the list of valid \"derivers\" of PATH---i.e., all the
692.drv present in the store that have PATH among their outputs."
693 store-path-list))
694
695(define query-derivation-outputs ; avoid name clash with `derivation-outputs'
696 (operation (query-derivation-outputs (store-path path))
697 "Return the list of outputs of PATH, a .drv file."
698 store-path-list))
699
0f3d2504
LC
700(define-operation (has-substitutes? (store-path path))
701 "Return #t if binary substitutes are available for PATH, and #f otherwise."
702 boolean)
703
704(define substitutable-paths
705 (operation (query-substitutable-paths (store-path-list paths))
706 "Return the subset of PATHS that is substitutable."
707 store-path-list))
708
709(define substitutable-path-info
f65cf81a 710 (operation (query-substitutable-path-infos (store-path-list paths))
0f3d2504
LC
711 "Return information about the subset of PATHS that is
712substitutable. For each substitutable path, a `substitutable?' object is
713returned."
714 substitutable-path-list))
715
3259877d
LC
716(define (run-gc server action to-delete min-freed)
717 "Perform the garbage-collector operation ACTION, one of the
718`gc-action' values. When ACTION is `delete-specific', the TO-DELETE is
719the list of store paths to delete. IGNORE-LIVENESS? should always be
720#f. MIN-FREED is the minimum amount of disk space to be freed, in
721bytes, before the GC can stop. Return the list of store paths delete,
722and the number of bytes freed."
723 (let ((s (nix-server-socket server)))
724 (write-int (operation-id collect-garbage) s)
725 (write-int action s)
726 (write-store-path-list to-delete s)
727 (write-arg boolean #f s) ; ignore-liveness?
728 (write-long-long min-freed s)
729 (write-int 0 s) ; obsolete
730 (when (>= (nix-server-minor-version server) 5)
731 ;; Obsolete `use-atime' and `max-atime' parameters.
732 (write-int 0 s)
733 (write-int 0 s))
734
735 ;; Loop until the server is done sending error output.
736 (let loop ((done? (process-stderr server)))
737 (or done? (loop (process-stderr server))))
738
739 (let ((paths (read-store-path-list s))
740 (freed (read-long-long s))
741 (obsolete (read-long-long s)))
000c59b6
LC
742 (unless (null? paths)
743 ;; To be on the safe side, completely invalidate both caches.
744 ;; Otherwise we could end up returning store paths that are no longer
745 ;; valid.
746 (hash-clear! (nix-server-add-to-store-cache server))
747 (hash-clear! (nix-server-add-text-to-store-cache server)))
748
3259877d
LC
749 (values paths freed))))
750
751(define-syntax-rule (%long-long-max)
752 ;; Maximum unsigned 64-bit integer.
753 (- (expt 2 64) 1))
754
755(define (live-paths server)
756 "Return the list of live store paths---i.e., store paths still
757referenced, and thus not subject to being garbage-collected."
758 (run-gc server (gc-action return-live) '() (%long-long-max)))
759
760(define (dead-paths server)
761 "Return the list of dead store paths---i.e., store paths no longer
762referenced, and thus subject to being garbage-collected."
763 (run-gc server (gc-action return-dead) '() (%long-long-max)))
764
765(define* (collect-garbage server #:optional (min-freed (%long-long-max)))
766 "Collect garbage from the store at SERVER. If MIN-FREED is non-zero,
767then collect at least MIN-FREED bytes. Return the paths that were
768collected, and the number of bytes freed."
769 (run-gc server (gc-action delete-dead) '() min-freed))
770
771(define* (delete-paths server paths #:optional (min-freed (%long-long-max)))
772 "Delete PATHS from the store at SERVER, if they are no longer
773referenced. If MIN-FREED is non-zero, then stop after at least
774MIN-FREED bytes have been collected. Return the paths that were
775collected, and the number of bytes freed."
776 (run-gc server (gc-action delete-specific) paths min-freed))
777
526382ff
LC
778(define (import-paths server port)
779 "Import the set of store paths read from PORT into SERVER's store. An error
780is raised if the set of paths read from PORT is not signed (as per
781'export-path #:sign? #t'.) Return the list of store paths imported."
782 (let ((s (nix-server-socket server)))
783 (write-int (operation-id import-paths) s)
784 (let loop ((done? (process-stderr server port)))
785 (or done? (loop (process-stderr server port))))
786 (read-store-path-list s)))
787
788(define* (export-path server path port #:key (sign? #t))
789 "Export PATH to PORT. When SIGN? is true, sign it."
790 (let ((s (nix-server-socket server)))
791 (write-int (operation-id export-path) s)
792 (write-store-path path s)
793 (write-arg boolean sign? s)
794 (let loop ((done? (process-stderr server port)))
795 (or done? (loop (process-stderr server port))))
796 (= 1 (read-int s))))
797
5b3d863f 798(define* (export-paths server paths port #:key (sign? #t) recursive?)
99fbddf9 799 "Export the store paths listed in PATHS to PORT, in topological order,
5b3d863f
LC
800signing them if SIGN? is true. When RECURSIVE? is true, export the closure of
801PATHS---i.e., PATHS and all their dependencies."
cafb92d8 802 (define ordered
5b3d863f
LC
803 (let ((sorted (topologically-sorted server paths)))
804 ;; When RECURSIVE? is #f, filter out the references of PATHS.
805 (if recursive?
806 sorted
807 (filter (cut member <> paths) sorted))))
cafb92d8 808
1d506993
LC
809 (let loop ((paths ordered))
810 (match paths
811 (()
812 (write-int 0 port))
813 ((head tail ...)
814 (write-int 1 port)
815 (and (export-path server head port #:sign? sign?)
816 (loop tail))))))
526382ff 817
6bfec3ed 818(define* (register-path path
689142cd
LC
819 #:key (references '()) deriver prefix
820 state-directory)
6bfec3ed 821 "Register PATH as a valid store file, with REFERENCES as its list of
bb31e0a3
LC
822references, and DERIVER as its deriver (.drv that led to it.) If PREFIX is
823not #f, it must be the name of the directory containing the new store to
689142cd
LC
824initialize; if STATE-DIRECTORY is not #f, it must be a string containing the
825absolute file name to the state directory of the store being initialized.
826Return #t on success.
6bfec3ed
LC
827
828Use with care as it directly modifies the store! This is primarily meant to
829be used internally by the daemon's build hook."
830 ;; Currently this is implemented by calling out to the fine C++ blob.
831 (catch 'system-error
832 (lambda ()
e901ef29 833 (let ((pipe (apply open-pipe* OPEN_WRITE %guix-register-program
689142cd
LC
834 `(,@(if prefix
835 `("--prefix" ,prefix)
836 '())
837 ,@(if state-directory
838 `("--state-directory" ,state-directory)
839 '())))))
6bfec3ed
LC
840 (and pipe
841 (begin
842 (format pipe "~a~%~a~%~a~%"
843 path (or deriver "") (length references))
844 (for-each (cut format pipe "~a~%" <>) references)
845 (zero? (close-pipe pipe))))))
846 (lambda args
847 ;; Failed to run %GUIX-REGISTER-PROGRAM.
848 #f)))
849
26bbbb95 850\f
e87f0591
LC
851;;;
852;;; Store monad.
853;;;
854
4e190c28
LC
855(define-syntax-rule (define-alias new old)
856 (define-syntax new (identifier-syntax old)))
e87f0591 857
4e190c28
LC
858;; The store monad allows us to (1) build sequences of operations in the
859;; store, and (2) make the store an implicit part of the execution context,
860;; rather than a parameter of every single function.
861(define-alias %store-monad %state-monad)
862(define-alias store-return state-return)
863(define-alias store-bind state-bind)
e87f0591 864
5808dcc2
LC
865(define (preserve-documentation original proc)
866 "Return PROC with documentation taken from ORIGINAL."
867 (set-object-property! proc 'documentation
868 (procedure-property original 'documentation))
869 proc)
870
e87f0591
LC
871(define (store-lift proc)
872 "Lift PROC, a procedure whose first argument is a connection to the store,
873in the store monad."
5808dcc2
LC
874 (preserve-documentation proc
875 (lambda args
876 (lambda (store)
877 (values (apply proc store args) store)))))
e87f0591 878
023d9892
LC
879(define (store-lower proc)
880 "Lower PROC, a monadic procedure in %STORE-MONAD, to a \"normal\" procedure
881taking the store as its first argument."
5808dcc2
LC
882 (preserve-documentation proc
883 (lambda (store . args)
884 (run-with-store store (apply proc args)))))
023d9892 885
e87f0591
LC
886;;
887;; Store monad operators.
888;;
889
890(define* (text-file name text)
891 "Return as a monadic value the absolute file name in the store of the file
892containing TEXT, a string."
893 (lambda (store)
4e190c28
LC
894 (values (add-text-to-store store name text '())
895 store)))
e87f0591
LC
896
897(define* (interned-file file #:optional name
898 #:key (recursive? #t))
899 "Return the name of FILE once interned in the store. Use NAME as its store
900name, or the basename of FILE if NAME is omitted.
901
902When RECURSIVE? is true, the contents of FILE are added recursively; if FILE
903designates a flat file and RECURSIVE? is true, its contents are added, and its
904permission bits are kept."
905 (lambda (store)
4e190c28
LC
906 (values (add-to-store store (or name (basename file))
907 recursive? "sha256" file)
908 store)))
e87f0591
LC
909
910(define %guile-for-build
911 ;; The derivation of the Guile to be used within the build environment,
912 ;; when using 'gexp->derivation' and co.
913 (make-parameter #f))
914
915(define* (run-with-store store mval
916 #:key
917 (guile-for-build (%guile-for-build))
918 (system (%current-system)))
919 "Run MVAL, a monadic value in the store monad, in STORE, an open store
3698f524 920connection, and return the result."
e87f0591
LC
921 (parameterize ((%guile-for-build guile-for-build)
922 (%current-system system))
3698f524
LC
923 (call-with-values (lambda ()
924 (run-with-state mval store))
925 (lambda (result store)
926 ;; Discard the state.
927 result))))
e87f0591
LC
928
929\f
26bbbb95
LC
930;;;
931;;; Store paths.
932;;;
933
934(define %store-prefix
935 ;; Absolute path to the Nix store.
1d6816f9 936 (make-parameter %store-directory))
26bbbb95 937
f39bd08a
LC
938(define (store-path? path)
939 "Return #t if PATH is a store path."
940 ;; This is a lightweight check, compared to using a regexp, but this has to
941 ;; be fast as it's called often in `derivation', for instance.
942 ;; `isStorePath' in Nix does something similar.
943 (string-prefix? (%store-prefix) path))
26bbbb95 944
9336e5b5
LC
945(define (direct-store-path? path)
946 "Return #t if PATH is a store path, and not a sub-directory of a store path.
947This predicate is sometimes needed because files *under* a store path are not
948valid inputs."
949 (and (store-path? path)
eee21271 950 (not (string=? path (%store-prefix)))
9336e5b5
LC
951 (let ((len (+ 1 (string-length (%store-prefix)))))
952 (not (string-index (substring path len) #\/)))))
953
26bbbb95
LC
954(define (derivation-path? path)
955 "Return #t if PATH is a derivation path."
956 (and (store-path? path) (string-suffix? ".drv" path)))
e3d74106 957
5c0f1845
LC
958(define store-regexp*
959 ;; The substituter makes repeated calls to 'store-path-hash-part', hence
960 ;; this optimization.
961 (memoize
962 (lambda (store)
963 "Return a regexp matching a file in STORE."
964 (make-regexp (string-append "^" (regexp-quote store)
965 "/([0-9a-df-np-sv-z]{32})-([^/]+)$")))))
966
e3d74106
LC
967(define (store-path-package-name path)
968 "Return the package name part of PATH, a file name in the store."
5c0f1845
LC
969 (let ((path-rx (store-regexp* (%store-prefix))))
970 (and=> (regexp-exec path-rx path)
971 (cut match:substring <> 2))))
2c6ab6cc
LC
972
973(define (store-path-hash-part path)
974 "Return the hash part of PATH as a base32 string, or #f if PATH is not a
975syntactically valid store path."
5c0f1845 976 (let ((path-rx (store-regexp* (%store-prefix))))
2c6ab6cc
LC
977 (and=> (regexp-exec path-rx path)
978 (cut match:substring <> 1))))
eddd4077
LC
979
980(define (log-file store file)
981 "Return the build log file for FILE, or #f if none could be found. FILE
982must be an absolute store file name, or a derivation file name."
eddd4077 983 (cond ((derivation-path? file)
021a201f 984 (let* ((base (basename file))
80d0447c 985 (log (string-append (dirname %state-directory) ; XXX
f5768afa 986 "/log/guix/drvs/"
021a201f
LC
987 (string-take base 2) "/"
988 (string-drop base 2)))
989 (log.bz2 (string-append log ".bz2")))
990 (cond ((file-exists? log.bz2) log.bz2)
991 ((file-exists? log) log)
992 (else #f))))
eddd4077
LC
993 (else
994 (match (valid-derivers store file)
995 ((derivers ...)
996 ;; Return the first that works.
997 (any (cut log-file store <>) derivers))
998 (_ #f)))))