Use 'mlambda' instead of 'memoize'.
[jackhill/guix/guix.git] / guix / store.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
deac976d 2;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 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)
f9704f17 22 #:use-module (guix memoization)
0f41c26f 23 #:use-module (guix serialization)
e87f0591 24 #:use-module (guix monads)
a9d2a105 25 #:autoload (guix base32) (bytevector->base32-string)
b0a6a971 26 #:autoload (guix build syscalls) (terminal-columns)
77d3cf08 27 #:use-module (rnrs bytevectors)
2535635f 28 #:use-module (ice-9 binary-ports)
77d3cf08
LC
29 #:use-module (srfi srfi-1)
30 #:use-module (srfi srfi-9)
bf8e7fc5 31 #:use-module (srfi srfi-9 gnu)
6581ec9a 32 #:use-module (srfi srfi-11)
77d3cf08 33 #:use-module (srfi srfi-26)
e87088c9
LC
34 #:use-module (srfi srfi-34)
35 #:use-module (srfi srfi-35)
26bbbb95 36 #:use-module (srfi srfi-39)
77d3cf08 37 #:use-module (ice-9 match)
e3d74106 38 #:use-module (ice-9 regex)
3f1e6939 39 #:use-module (ice-9 vlist)
6bfec3ed 40 #:use-module (ice-9 popen)
9fd72fb1 41 #:export (%daemon-socket-file
a9d2a105 42 %gc-roots-directory
f8a8e0fe 43 %default-substitute-urls
9fd72fb1
LC
44
45 nix-server?
77d3cf08
LC
46 nix-server-major-version
47 nix-server-minor-version
48 nix-server-socket
49
e87088c9 50 &nix-error nix-error?
ef86c39f
LC
51 &nix-connection-error nix-connection-error?
52 nix-connection-error-file
53 nix-connection-error-code
e87088c9
LC
54 &nix-protocol-error nix-protocol-error?
55 nix-protocol-error-message
56 nix-protocol-error-status
57
26bbbb95 58 hash-algo
07e70f48 59 build-mode
26bbbb95 60
77d3cf08 61 open-connection
3abaf0c4 62 close-connection
ce4a4829 63 with-store
77d3cf08 64 set-build-options
4f740b67 65 set-build-options*
31ef99a8 66 valid-path?
82058eff 67 query-path-hash
11e7a6cf 68 hash-part->path
533d1768 69 query-path-info
77d3cf08
LC
70 add-text-to-store
71 add-to-store
abac874b
LC
72 build-things
73 build
16748d80
LC
74 query-failed-paths
75 clear-failed-paths
3259877d 76 add-temp-root
34811f02 77 add-indirect-root
a9d2a105
LC
78 add-permanent-root
79 remove-permanent-root
26bbbb95 80
0f3d2504
LC
81 substitutable?
82 substitutable-path
83 substitutable-deriver
84 substitutable-references
85 substitutable-download-size
86 substitutable-nar-size
87 has-substitutes?
88 substitutable-paths
89 substitutable-path-info
90
533d1768
DT
91 path-info?
92 path-info-deriver
93 path-info-hash
94 path-info-references
95 path-info-registration-time
96 path-info-nar-size
97
f9aefa2d 98 built-in-builders
fae31edc 99 references
6581ec9a 100 references/substitutes
e74f64b9 101 references*
3f1e6939 102 requisites
fae31edc 103 referrers
e3fd0ce6 104 optimize-store
c63d9403 105 verify-store
50add477 106 topologically-sorted
fae31edc
LC
107 valid-derivers
108 query-derivation-outputs
3259877d
LC
109 live-paths
110 dead-paths
111 collect-garbage
112 delete-paths
526382ff
LC
113 import-paths
114 export-paths
3259877d 115
dcee50c1
LC
116 current-build-output-port
117
6bfec3ed
LC
118 register-path
119
e87f0591
LC
120 %store-monad
121 store-bind
122 store-return
123 store-lift
023d9892 124 store-lower
e87f0591
LC
125 run-with-store
126 %guile-for-build
98a7b528
LC
127 current-system
128 set-current-system
e87f0591
LC
129 text-file
130 interned-file
131
26bbbb95
LC
132 %store-prefix
133 store-path?
9336e5b5 134 direct-store-path?
e3d74106 135 derivation-path?
2c6ab6cc 136 store-path-package-name
eddd4077 137 store-path-hash-part
cdb5b075 138 direct-store-path
eddd4077 139 log-file))
77d3cf08 140
deac976d 141(define %protocol-version #x161)
77d3cf08 142
d66b704b
LC
143(define %worker-magic-1 #x6e697863) ; "nixc"
144(define %worker-magic-2 #x6478696f) ; "dxio"
77d3cf08
LC
145
146(define (protocol-major magic)
147 (logand magic #xff00))
148(define (protocol-minor magic)
149 (logand magic #x00ff))
150
151(define-syntax define-enumerate-type
152 (syntax-rules ()
153 ((_ name->int (name id) ...)
154 (define-syntax name->int
155 (syntax-rules (name ...)
156 ((_ name) id) ...)))))
157
158(define-enumerate-type operation-id
159 ;; operation numbers from worker-protocol.hh
160 (quit 0)
161 (valid-path? 1)
162 (has-substitutes? 3)
163 (query-path-hash 4)
164 (query-references 5)
165 (query-referrers 6)
166 (add-to-store 7)
167 (add-text-to-store 8)
abac874b 168 (build-things 9)
77d3cf08
LC
169 (ensure-path 10)
170 (add-temp-root 11)
171 (add-indirect-root 12)
172 (sync-with-gc 13)
173 (find-roots 14)
174 (export-path 16)
175 (query-deriver 18)
176 (set-options 19)
177 (collect-garbage 20)
63193ebf 178 ;;(query-substitutable-path-info 21) ; obsolete as of #x10c
77d3cf08 179 (query-derivation-outputs 22)
63193ebf 180 (query-all-valid-paths 23)
77d3cf08
LC
181 (query-failed-paths 24)
182 (clear-failed-paths 25)
183 (query-path-info 26)
184 (import-paths 27)
63193ebf
LC
185 (query-derivation-output-names 28)
186 (query-path-from-hash-part 29)
187 (query-substitutable-path-infos 30)
188 (query-valid-paths 31)
fae31edc 189 (query-substitutable-paths 32)
e3fd0ce6 190 (query-valid-derivers 33)
c63d9403 191 (optimize-store 34)
f9aefa2d
LC
192 (verify-store 35)
193 (built-in-builders 80))
77d3cf08
LC
194
195(define-enumerate-type hash-algo
196 ;; hash.hh
197 (md5 1)
198 (sha1 2)
199 (sha256 3))
200
07e70f48
LC
201(define-enumerate-type build-mode
202 ;; store-api.hh
203 (normal 0)
204 (repair 1)
205 (check 2))
206
3259877d
LC
207(define-enumerate-type gc-action
208 ;; store-api.hh
209 (return-live 0)
210 (return-dead 1)
211 (delete-dead 2)
212 (delete-specific 3))
213
77d3cf08 214(define %default-socket-path
80d0447c 215 (string-append %state-directory "/daemon-socket/socket"))
77d3cf08 216
9fd72fb1
LC
217(define %daemon-socket-file
218 ;; File name of the socket the daemon listens too.
219 (make-parameter (or (getenv "GUIX_DAEMON_SOCKET")
220 %default-socket-path)))
221
222
77d3cf08 223\f
0f3d2504
LC
224;; Information about a substitutable store path.
225(define-record-type <substitutable>
226 (substitutable path deriver refs dl-size nar-size)
227 substitutable?
228 (path substitutable-path)
229 (deriver substitutable-deriver)
230 (refs substitutable-references)
231 (dl-size substitutable-download-size)
232 (nar-size substitutable-nar-size))
233
234(define (read-substitutable-path-list p)
235 (let loop ((len (read-int p))
236 (result '()))
237 (if (zero? len)
238 (reverse result)
239 (let ((path (read-store-path p))
240 (deriver (read-store-path p))
241 (refs (read-store-path-list p))
242 (dl-size (read-long-long p))
243 (nar-size (read-long-long p)))
244 (loop (- len 1)
245 (cons (substitutable path deriver refs dl-size nar-size)
246 result))))))
247
533d1768
DT
248;; Information about a store path.
249(define-record-type <path-info>
250 (path-info deriver hash references registration-time nar-size)
251 path-info?
22572d56 252 (deriver path-info-deriver) ;string | #f
533d1768
DT
253 (hash path-info-hash)
254 (references path-info-references)
255 (registration-time path-info-registration-time)
256 (nar-size path-info-nar-size))
257
258(define (read-path-info p)
22572d56
LC
259 (let ((deriver (match (read-store-path p)
260 ("" #f)
261 (x x)))
533d1768
DT
262 (hash (base16-string->bytevector (read-string p)))
263 (refs (read-store-path-list p))
264 (registration-time (read-int p))
265 (nar-size (read-long-long p)))
266 (path-info deriver hash refs registration-time nar-size)))
267
77d3cf08 268(define-syntax write-arg
1ec32f4a 269 (syntax-rules (integer boolean string string-list string-pairs
3259877d 270 store-path store-path-list base16)
77d3cf08
LC
271 ((_ integer arg p)
272 (write-int arg p))
273 ((_ boolean arg p)
274 (write-int (if arg 1 0) p))
77d3cf08
LC
275 ((_ string arg p)
276 (write-string arg p))
277 ((_ string-list arg p)
82058eff 278 (write-string-list arg p))
6c20d1d0
LC
279 ((_ string-pairs arg p)
280 (write-string-pairs arg p))
3259877d
LC
281 ((_ store-path arg p)
282 (write-store-path arg p))
283 ((_ store-path-list arg p)
284 (write-store-path-list arg p))
82058eff
LC
285 ((_ base16 arg p)
286 (write-string (bytevector->base16-string arg) p))))
77d3cf08
LC
287
288(define-syntax read-arg
f9aefa2d 289 (syntax-rules (integer boolean string store-path store-path-list string-list
533d1768 290 substitutable-path-list path-info base16)
77d3cf08
LC
291 ((_ integer p)
292 (read-int p))
293 ((_ boolean p)
294 (not (zero? (read-int p))))
295 ((_ string p)
296 (read-string p))
297 ((_ store-path p)
82058eff 298 (read-store-path p))
3259877d
LC
299 ((_ store-path-list p)
300 (read-store-path-list p))
f9aefa2d
LC
301 ((_ string-list p)
302 (read-string-list p))
0f3d2504
LC
303 ((_ substitutable-path-list p)
304 (read-substitutable-path-list p))
533d1768
DT
305 ((_ path-info p)
306 (read-path-info p))
0f3d2504 307 ((_ base16 p)
82058eff 308 (base16-string->bytevector (read-string p)))))
77d3cf08
LC
309
310\f
311;; remote-store.cc
312
313(define-record-type <nix-server>
2c3f47ee 314 (%make-nix-server socket major minor
bdcf35a6 315 ats-cache atts-cache)
77d3cf08
LC
316 nix-server?
317 (socket nix-server-socket)
318 (major nix-server-major-version)
2c3f47ee
LC
319 (minor nix-server-minor-version)
320
321 ;; Caches. We keep them per-connection, because store paths build
322 ;; during the session are temporary GC roots kept for the duration of
323 ;; the session.
bdcf35a6
LC
324 (ats-cache nix-server-add-to-store-cache)
325 (atts-cache nix-server-add-text-to-store-cache))
77d3cf08 326
bf8e7fc5
LC
327(set-record-type-printer! <nix-server>
328 (lambda (obj port)
329 (format port "#<build-daemon ~a.~a ~a>"
330 (nix-server-major-version obj)
331 (nix-server-minor-version obj)
332 (number->string (object-address obj)
333 16))))
334
e87088c9
LC
335(define-condition-type &nix-error &error
336 nix-error?)
337
ef86c39f
LC
338(define-condition-type &nix-connection-error &nix-error
339 nix-connection-error?
340 (file nix-connection-error-file)
341 (errno nix-connection-error-code))
342
e87088c9
LC
343(define-condition-type &nix-protocol-error &nix-error
344 nix-protocol-error?
345 (message nix-protocol-error-message)
346 (status nix-protocol-error-status))
347
6230d6f0
LC
348(define (open-unix-domain-socket file)
349 "Connect to the Unix-domain socket at FILE and return it. Raise a
350'&nix-connection-error' upon error."
77d3cf08
LC
351 (let ((s (with-fluids ((%default-port-encoding #f))
352 ;; This trick allows use of the `scm_c_read' optimization.
353 (socket PF_UNIX SOCK_STREAM 0)))
354 (a (make-socket-address PF_UNIX file)))
df1fab58 355
ef86c39f 356 (catch 'system-error
6230d6f0
LC
357 (lambda ()
358 (connect s a)
359 s)
ef86c39f
LC
360 (lambda args
361 ;; Translate the error to something user-friendly.
362 (let ((errno (system-error-errno args)))
363 (raise (condition (&nix-connection-error
364 (file file)
6230d6f0 365 (errno errno)))))))))
ef86c39f 366
6230d6f0
LC
367(define* (open-connection #:optional (file (%daemon-socket-file))
368 #:key port (reserve-space? #t) cpu-affinity)
369 "Connect to the daemon over the Unix-domain socket at FILE, or, if PORT is
370not #f, use it as the I/O port over which to communicate to a build daemon.
371
372When RESERVE-SPACE? is true, instruct it to reserve a little bit of extra
373space on the file system so that the garbage collector can still operate,
374should the disk become full. When CPU-AFFINITY is true, it must be an integer
375corresponding to an OS-level CPU number to which the daemon's worker process
376for this connection will be pinned. Return a server object."
13d5e8da
LC
377 (guard (c ((nar-error? c)
378 ;; One of the 'write-' or 'read-' calls below failed, but this is
379 ;; really a connection error.
380 (raise (condition
381 (&nix-connection-error (file (or port file))
382 (errno EPROTO))
383 (&message (message "build daemon handshake failed"))))))
384 (let ((port (or port (open-unix-domain-socket file))))
385 (write-int %worker-magic-1 port)
386 (let ((r (read-int port)))
387 (and (eqv? r %worker-magic-2)
388 (let ((v (read-int port)))
389 (and (eqv? (protocol-major %protocol-version)
390 (protocol-major v))
391 (begin
392 (write-int %protocol-version port)
393 (when (>= (protocol-minor v) 14)
394 (write-int (if cpu-affinity 1 0) port)
395 (when cpu-affinity
396 (write-int cpu-affinity port)))
397 (when (>= (protocol-minor v) 11)
398 (write-int (if reserve-space? 1 0) port))
399 (let ((conn (%make-nix-server port
400 (protocol-major v)
401 (protocol-minor v)
402 (make-hash-table 100)
403 (make-hash-table 100))))
404 (let loop ((done? (process-stderr conn)))
405 (or done? (process-stderr conn)))
406 conn)))))))))
77d3cf08 407
3abaf0c4
LC
408(define (close-connection server)
409 "Close the connection to SERVER."
410 (close (nix-server-socket server)))
411
ce4a4829
LC
412(define-syntax-rule (with-store store exp ...)
413 "Bind STORE to an open connection to the store and evaluate EXPs;
414automatically close the store when the dynamic extent of EXP is left."
415 (let ((store (open-connection)))
416 (dynamic-wind
417 (const #f)
418 (lambda ()
419 exp ...)
420 (lambda ()
421 (false-if-exception (close-connection store))))))
422
dcee50c1
LC
423(define current-build-output-port
424 ;; The port where build output is sent.
425 (make-parameter (current-error-port)))
426
526382ff
LC
427(define* (dump-port in out
428 #:optional len
429 #:key (buffer-size 16384))
430 "Read LEN bytes from IN (or as much as possible if LEN is #f) and write it
431to OUT, using chunks of BUFFER-SIZE bytes."
432 (define buffer
433 (make-bytevector buffer-size))
434
435 (let loop ((total 0)
436 (bytes (get-bytevector-n! in buffer 0
437 (if len
438 (min len buffer-size)
439 buffer-size))))
440 (or (eof-object? bytes)
441 (and len (= total len))
442 (let ((total (+ total bytes)))
443 (put-bytevector out buffer 0 bytes)
444 (loop total
445 (get-bytevector-n! in buffer 0
446 (if len
447 (min (- len total) buffer-size)
448 buffer-size)))))))
449
d28869af
LC
450(define %newlines
451 ;; Newline characters triggering a flush of 'current-build-output-port'.
452 ;; Unlike Guile's _IOLBF, we flush upon #\return so that progress reports
453 ;; that use that trick are correctly displayed.
454 (char-set #\newline #\return))
455
526382ff 456(define* (process-stderr server #:optional user-port)
dcee50c1
LC
457 "Read standard output and standard error from SERVER, writing it to
458CURRENT-BUILD-OUTPUT-PORT. Return #t when SERVER is done sending data, and
459#f otherwise; in the latter case, the caller should call `process-stderr'
bbdb3ffa
LC
460again until #t is returned or an error is raised.
461
462Since the build process's output cannot be assumed to be UTF-8, we
463conservatively consider it to be Latin-1, thereby avoiding possible
464encoding conversion errors."
77d3cf08
LC
465 (define p
466 (nix-server-socket server))
467
468 ;; magic cookies from worker-protocol.hh
5674a3fd
LC
469 (define %stderr-next #x6f6c6d67) ; "olmg", build log
470 (define %stderr-read #x64617461) ; "data", data needed from source
471 (define %stderr-write #x64617416) ; "dat\x16", data for sink
472 (define %stderr-last #x616c7473) ; "alts", we're done
473 (define %stderr-error #x63787470) ; "cxtp", error reporting
77d3cf08
LC
474
475 (let ((k (read-int p)))
476 (cond ((= k %stderr-write)
526382ff
LC
477 ;; Write a byte stream to USER-PORT.
478 (let* ((len (read-int p))
479 (m (modulo len 8)))
6374633b
LC
480 (dump-port p user-port len
481 #:buffer-size (if (<= len 16384) 16384 65536))
526382ff
LC
482 (unless (zero? m)
483 ;; Consume padding, as for strings.
484 (get-bytevector-n p (- 8 m))))
dcee50c1 485 #f)
77d3cf08 486 ((= k %stderr-read)
526382ff 487 ;; Read a byte stream from USER-PORT.
5895f244
LC
488 ;; Note: Avoid 'get-bytevector-n' to work around
489 ;; <http://bugs.gnu.org/17591> in Guile up to 2.0.11.
526382ff 490 (let* ((max-len (read-int p))
5895f244
LC
491 (data (make-bytevector max-len))
492 (len (get-bytevector-n! user-port data 0 max-len)))
526382ff 493 (write-int len p)
5895f244 494 (put-bytevector p data 0 len)
526382ff 495 (write-padding len p)
dcee50c1 496 #f))
77d3cf08 497 ((= k %stderr-next)
ce72c780
LC
498 ;; Log a string. Build logs are usually UTF-8-encoded, but they
499 ;; may also contain arbitrary byte sequences that should not cause
500 ;; this to fail. Thus, use the permissive
501 ;; 'read-maybe-utf8-string'.
502 (let ((s (read-maybe-utf8-string p)))
dcee50c1 503 (display s (current-build-output-port))
d28869af 504 (when (string-any %newlines s)
2535635f 505 (force-output (current-build-output-port)))
dcee50c1 506 #f))
77d3cf08 507 ((= k %stderr-error)
526382ff 508 ;; Report an error.
ce72c780 509 (let ((error (read-maybe-utf8-string p))
0ff3e3aa
LC
510 ;; Currently the daemon fails to send a status code for early
511 ;; errors like DB schema version mismatches, so check for EOF.
512 (status (if (and (>= (nix-server-minor-version server) 8)
513 (not (eof-object? (lookahead-u8 p))))
77d3cf08
LC
514 (read-int p)
515 1)))
e87088c9
LC
516 (raise (condition (&nix-protocol-error
517 (message error)
518 (status status))))))
77d3cf08 519 ((= k %stderr-last)
dcee50c1 520 ;; The daemon is done (see `stopWork' in `nix-worker.cc'.)
77d3cf08
LC
521 #t)
522 (else
e87088c9
LC
523 (raise (condition (&nix-protocol-error
524 (message "invalid error code")
525 (status k))))))))
77d3cf08 526
4d581220 527(define %default-substitute-urls
d70533cb
LC
528 ;; Default list of substituters. This is *not* the list baked in
529 ;; 'guix-daemon', but it is used by 'guix-service-type' and and a couple of
530 ;; clients ('guix build --log-file' uses it.)
df061d07
LC
531 (map (if (false-if-exception (resolve-interface '(gnutls)))
532 (cut string-append "https://" <>)
533 (cut string-append "http://" <>))
f82ce8f6 534 '("mirror.hydra.gnu.org")))
4d581220 535
77d3cf08 536(define* (set-build-options server
c3eb878f 537 #:key keep-failed? keep-going? fallback?
77d3cf08 538 (verbosity 0)
2fba87ac 539 rounds ;number of build rounds
deac976d 540 max-build-jobs
6c20d1d0 541 timeout
deac976d 542 max-silent-time
77d3cf08
LC
543 (use-build-hook? #t)
544 (build-verbosity 0)
545 (log-type 0)
e036c31b 546 (print-build-trace #t)
deac976d 547 build-cores
63193ebf 548 (use-substitutes? #t)
4d581220 549
fb4bf72b
LC
550 ;; Client-provided substitute URLs. If it is #f,
551 ;; the daemon's settings are used. Otherwise, it
552 ;; overrides the daemons settings; see 'guix
553 ;; substitute'.
b0a6a971
LC
554 (substitute-urls #f)
555
556 ;; Number of columns in the client's terminal.
38f50f49
LC
557 (terminal-columns (terminal-columns))
558
559 ;; Locale of the client.
560 (locale (false-if-exception (setlocale LC_ALL))))
77d3cf08
LC
561 ;; Must be called after `open-connection'.
562
563 (define socket
564 (nix-server-socket server))
565
566 (let-syntax ((send (syntax-rules ()
e036c31b
LC
567 ((_ (type option) ...)
568 (begin
569 (write-arg type option socket)
570 ...)))))
571 (write-int (operation-id set-options) socket)
572 (send (boolean keep-failed?) (boolean keep-going?)
deac976d
LC
573 (boolean fallback?) (integer verbosity))
574 (when (< (nix-server-minor-version server) #x61)
575 (let ((max-build-jobs (or max-build-jobs 1))
576 (max-silent-time (or max-silent-time 3600)))
577 (send (integer max-build-jobs) (integer max-silent-time))))
371e87d2
LC
578 (when (>= (nix-server-minor-version server) 2)
579 (send (boolean use-build-hook?)))
580 (when (>= (nix-server-minor-version server) 4)
581 (send (integer build-verbosity) (integer log-type)
582 (boolean print-build-trace)))
deac976d
LC
583 (when (and (>= (nix-server-minor-version server) 6)
584 (< (nix-server-minor-version server) #x61))
585 (let ((build-cores (or build-cores (current-processor-count))))
586 (send (integer build-cores))))
371e87d2
LC
587 (when (>= (nix-server-minor-version server) 10)
588 (send (boolean use-substitutes?)))
589 (when (>= (nix-server-minor-version server) 12)
41c45e78
LC
590 (let ((pairs `(,@(if timeout
591 `(("build-timeout" . ,(number->string timeout)))
592 '())
deac976d
LC
593 ,@(if max-silent-time
594 `(("build-max-silent-time"
595 . ,(number->string max-silent-time)))
596 '())
597 ,@(if max-build-jobs
598 `(("build-max-jobs"
599 . ,(number->string max-build-jobs)))
600 '())
601 ,@(if build-cores
602 `(("build-cores" . ,(number->string build-cores)))
603 '())
fb4bf72b
LC
604 ,@(if substitute-urls
605 `(("substitute-urls"
606 . ,(string-join substitute-urls)))
2fba87ac
LC
607 '())
608 ,@(if rounds
609 `(("build-repeat"
610 . ,(number->string (max 0 (1- rounds)))))
b0a6a971
LC
611 '())
612 ,@(if terminal-columns
613 `(("terminal-columns"
614 . ,(number->string terminal-columns)))
38f50f49
LC
615 '())
616 ,@(if locale
617 `(("locale" . ,locale))
fb4bf72b 618 '()))))
f401b1e9 619 (send (string-pairs pairs))))
dcee50c1
LC
620 (let loop ((done? (process-stderr server)))
621 (or done? (process-stderr server)))))
77d3cf08 622
fd060fd3 623(define-syntax operation
77d3cf08 624 (syntax-rules ()
fd060fd3 625 "Define a client-side RPC stub for the given operation."
3259877d 626 ((_ (name (type arg) ...) docstring return ...)
fd060fd3 627 (lambda (server arg ...)
77d3cf08
LC
628 docstring
629 (let ((s (nix-server-socket server)))
630 (write-int (operation-id name) s)
631 (write-arg type arg s)
632 ...
dcee50c1
LC
633 ;; Loop until the server is done sending error output.
634 (let loop ((done? (process-stderr server)))
635 (or done? (loop (process-stderr server))))
3259877d 636 (values (read-arg return s) ...))))))
77d3cf08 637
fd060fd3
LC
638(define-syntax-rule (define-operation (name args ...)
639 docstring return ...)
640 (define name
641 (operation (name args ...) docstring return ...)))
642
31ef99a8 643(define-operation (valid-path? (string path))
06b76acc
LC
644 "Return #t when PATH designates a valid store item and #f otherwise (an
645invalid item may exist on disk but still be invalid, for instance because it
646is the result of an aborted or failed build.)
647
648A '&nix-protocol-error' condition is raised if PATH is not prefixed by the
649store directory (/gnu/store)."
31ef99a8
LC
650 boolean)
651
63193ebf 652(define-operation (query-path-hash (store-path path))
aa8fff0c 653 "Return the SHA256 hash of the nar serialization of PATH as a bytevector."
82058eff
LC
654 base16)
655
11e7a6cf
LC
656(define hash-part->path
657 (let ((query-path-from-hash-part
658 (operation (query-path-from-hash-part (string hash))
659 #f
660 store-path)))
661 (lambda (server hash-part)
662 "Return the store path whose hash part is HASH-PART (a nix-base32
663string). Raise an error if no such path exists."
664 ;; This RPC is primarily used by Hydra to reply to HTTP GETs of
665 ;; /HASH.narinfo.
666 (query-path-from-hash-part server hash-part))))
667
533d1768
DT
668(define-operation (query-path-info (store-path path))
669 "Return the info (hash, references, etc.) for PATH."
670 path-info)
671
fd060fd3
LC
672(define add-text-to-store
673 ;; A memoizing version of `add-to-store', to avoid repeated RPCs with
674 ;; the very same arguments during a given session.
675 (let ((add-text-to-store
676 (operation (add-text-to-store (string name) (string text)
677 (string-list references))
678 #f
679 store-path)))
cfbf9160 680 (lambda* (server name text #:optional (references '()))
bdcf35a6
LC
681 "Add TEXT under file NAME in the store, and return its store path.
682REFERENCES is the list of store paths referred to by the resulting store
683path."
fce2394e 684 (let ((args `(,text ,name ,references))
bdcf35a6
LC
685 (cache (nix-server-add-text-to-store-cache server)))
686 (or (hash-ref cache args)
fd060fd3 687 (let ((path (add-text-to-store server name text references)))
bdcf35a6
LC
688 (hash-set! cache args path)
689 path))))))
690
1ec32f4a
LC
691(define true
692 ;; Define it once and for all since we use it as a default value for
693 ;; 'add-to-store' and want to make sure two default values are 'eq?' for the
694 ;; purposes or memoization.
695 (lambda (file stat)
696 #t))
697
fd060fd3 698(define add-to-store
a7b6ffee
LC
699 ;; A memoizing version of `add-to-store'. This is important because
700 ;; `add-to-store' leads to huge data transfers to the server, and
701 ;; because it's often called many times with the very same argument.
1ec32f4a
LC
702 (let ((add-to-store
703 (lambda* (server basename recursive? hash-algo file-name
704 #:key (select? true))
705 ;; We don't use the 'operation' macro so we can pass SELECT? to
706 ;; 'write-file'.
707 (let ((port (nix-server-socket server)))
708 (write-int (operation-id add-to-store) port)
709 (write-string basename port)
710 (write-int 1 port) ;obsolete, must be #t
711 (write-int (if recursive? 1 0) port)
712 (write-string hash-algo port)
713 (write-file file-name port #:select? select?)
714 (let loop ((done? (process-stderr server)))
715 (or done? (loop (process-stderr server))))
716 (read-store-path port)))))
717 (lambda* (server basename recursive? hash-algo file-name
718 #:key (select? true))
a9ebd9ef 719 "Add the contents of FILE-NAME under BASENAME to the store. When
69792b28
LC
720RECURSIVE? is false, FILE-NAME must designate a regular file--not a directory
721nor a symlink. When RECURSIVE? is true and FILE-NAME designates a directory,
722the contents of FILE-NAME are added recursively; if FILE-NAME designates a
723flat file and RECURSIVE? is true, its contents are added, and its permission
1ec32f4a
LC
724bits are kept. HASH-ALGO must be a string such as \"sha256\".
725
726When RECURSIVE? is true, call (SELECT? FILE STAT) for each directory entry,
727where FILE is the entry's absolute file name and STAT is the result of
728'lstat'; exclude entries for which SELECT? does not return true."
69792b28 729 (let* ((st (false-if-exception (lstat file-name)))
1ec32f4a 730 (args `(,st ,basename ,recursive? ,hash-algo ,select?))
2c3f47ee 731 (cache (nix-server-add-to-store-cache server)))
a7b6ffee 732 (or (and st (hash-ref cache args))
1ec32f4a
LC
733 (let ((path (add-to-store server basename recursive?
734 hash-algo file-name
735 #:select? select?)))
a7b6ffee
LC
736 (hash-set! cache args path)
737 path))))))
738
07e70f48
LC
739(define build-things
740 (let ((build (operation (build-things (string-list things)
741 (integer mode))
742 "Do it!"
2734cbb8
LC
743 boolean))
744 (build/old (operation (build-things (string-list things))
745 "Do it!"
746 boolean)))
07e70f48
LC
747 (lambda* (store things #:optional (mode (build-mode normal)))
748 "Build THINGS, a list of store items which may be either '.drv' files or
abac874b
LC
749outputs, and return when the worker is done building them. Elements of THINGS
750that are not derivations can only be substituted and not built locally.
dcee50c1 751Return #t on success."
2734cbb8
LC
752 (if (>= (nix-server-minor-version store) 15)
753 (build store things mode)
754 (if (= mode (build-mode normal))
755 (build/old store things)
756 (raise (condition (&nix-protocol-error
757 (message "unsupported build mode")
758 (status 1)))))))))
26bbbb95 759
d3648e01
LC
760(define-operation (add-temp-root (store-path path))
761 "Make PATH a temporary root for the duration of the current session.
762Return #t."
763 boolean)
764
34811f02 765(define-operation (add-indirect-root (string file-name))
a9d2a105
LC
766 "Make the symlink FILE-NAME an indirect root for the garbage collector:
767whatever store item FILE-NAME points to will not be collected. Return #t on
768success.
769
770FILE-NAME can be anywhere on the file system, but it must be an absolute file
771name--it is the caller's responsibility to ensure that it is an absolute file
772name."
34811f02
LC
773 boolean)
774
a9d2a105
LC
775(define %gc-roots-directory
776 ;; The place where garbage collector roots (symlinks) are kept.
777 (string-append %state-directory "/gcroots"))
778
779(define (add-permanent-root target)
780 "Add a garbage collector root pointing to TARGET, an element of the store,
781preventing TARGET from even being collected. This can also be used if TARGET
782does not exist yet.
783
784Raise an error if the caller does not have write access to the GC root
785directory."
786 (let* ((root (string-append %gc-roots-directory "/" (basename target))))
787 (catch 'system-error
788 (lambda ()
789 (symlink target root))
790 (lambda args
791 ;; If ROOT already exists, this is fine; otherwise, re-throw.
792 (unless (= EEXIST (system-error-errno args))
793 (apply throw args))))))
794
795(define (remove-permanent-root target)
796 "Remove the permanent garbage collector root pointing to TARGET. Raise an
797error if there is no such root."
798 (delete-file (string-append %gc-roots-directory "/" (basename target))))
799
fae31edc
LC
800(define references
801 (operation (query-references (store-path path))
802 "Return the list of references of PATH."
803 store-path-list))
804
f09aea1b
LC
805(define %reference-cache
806 ;; Brute-force cache mapping store items to their list of references.
807 ;; Caching matters because when building a profile in the presence of
808 ;; grafts, we keep calling 'graft-derivation', which in turn calls
809 ;; 'references/substitutes' many times with the same arguments. Ideally we
810 ;; would use a cache associated with the daemon connection instead (XXX).
811 (make-hash-table 100))
812
6581ec9a
LC
813(define (references/substitutes store items)
814 "Return the list of list of references of ITEMS; the result has the same
815length as ITEMS. Query substitute information for any item missing from the
816store at once. Raise a '&nix-protocol-error' exception if reference
817information for one of ITEMS is missing."
818 (let* ((local-refs (map (lambda (item)
f09aea1b
LC
819 (or (hash-ref %reference-cache item)
820 (guard (c ((nix-protocol-error? c) #f))
821 (references store item))))
6581ec9a
LC
822 items))
823 (missing (fold-right (lambda (item local-ref result)
824 (if local-ref
825 result
826 (cons item result)))
827 '()
828 items local-refs))
829
830 ;; Query all the substitutes at once to minimize the cost of
831 ;; launching 'guix substitute' and making HTTP requests.
832 (substs (substitutable-path-info store missing)))
833 (when (< (length substs) (length missing))
834 (raise (condition (&nix-protocol-error
835 (message "cannot determine \
836the list of references")
837 (status 1)))))
838
839 ;; Intersperse SUBSTS and LOCAL-REFS.
dd78e90a
LC
840 (let loop ((items items)
841 (local-refs local-refs)
6581ec9a 842 (result '()))
dd78e90a 843 (match items
6581ec9a 844 (()
f09aea1b
LC
845 (let ((result (reverse result)))
846 (for-each (cut hash-set! %reference-cache <> <>)
847 items result)
848 result))
dd78e90a
LC
849 ((item items ...)
850 (match local-refs
851 ((#f tail ...)
852 (loop items tail
853 (cons (any (lambda (subst)
854 (and (string=? (substitutable-path subst) item)
855 (substitutable-references subst)))
856 substs)
857 result)))
858 ((head tail ...)
859 (loop items tail
860 (cons head result)))))))))
6581ec9a 861
f6fee16e 862(define* (fold-path store proc seed paths
3f1e6939 863 #:optional (relatives (cut references store <>)))
f6fee16e 864 "Call PROC for each of the RELATIVES of PATHS, exactly once, and return the
3f1e6939
LC
865result formed from the successive calls to PROC, the first of which is passed
866SEED."
f6fee16e 867 (let loop ((paths paths)
3f1e6939
LC
868 (result seed)
869 (seen vlist-null))
870 (match paths
871 ((path rest ...)
872 (if (vhash-assoc path seen)
873 (loop rest result seen)
874 (let ((seen (vhash-cons path #t seen))
875 (rest (append rest (relatives path)))
876 (result (proc path result)))
877 (loop rest result seen))))
878 (()
879 result))))
880
f6fee16e
LC
881(define (requisites store paths)
882 "Return the requisites of PATHS, including PATHS---i.e., their closures (all
883its references, recursively)."
884 (fold-path store cons '() paths))
3f1e6939 885
50add477
LC
886(define (topologically-sorted store paths)
887 "Return a list containing PATHS and all their references sorted in
888topological order."
889 (define (traverse)
890 ;; Do a simple depth-first traversal of all of PATHS.
891 (let loop ((paths paths)
892 (visited vlist-null)
893 (result '()))
894 (define (visit n)
895 (vhash-cons n #t visited))
896
897 (define (visited? n)
898 (vhash-assoc n visited))
899
900 (match paths
901 ((head tail ...)
902 (if (visited? head)
903 (loop tail visited result)
904 (call-with-values
905 (lambda ()
906 (loop (references store head)
907 (visit head)
908 result))
909 (lambda (visited result)
910 (loop tail
911 visited
912 (cons head result))))))
913 (()
914 (values visited result)))))
915
916 (call-with-values traverse
917 (lambda (_ result)
918 (reverse result))))
919
fae31edc
LC
920(define referrers
921 (operation (query-referrers (store-path path))
922 "Return the list of path that refer to PATH."
923 store-path-list))
924
925(define valid-derivers
926 (operation (query-valid-derivers (store-path path))
927 "Return the list of valid \"derivers\" of PATH---i.e., all the
928.drv present in the store that have PATH among their outputs."
929 store-path-list))
930
931(define query-derivation-outputs ; avoid name clash with `derivation-outputs'
932 (operation (query-derivation-outputs (store-path path))
933 "Return the list of outputs of PATH, a .drv file."
934 store-path-list))
935
0f3d2504
LC
936(define-operation (has-substitutes? (store-path path))
937 "Return #t if binary substitutes are available for PATH, and #f otherwise."
938 boolean)
939
940(define substitutable-paths
941 (operation (query-substitutable-paths (store-path-list paths))
942 "Return the subset of PATHS that is substitutable."
943 store-path-list))
944
945(define substitutable-path-info
f65cf81a 946 (operation (query-substitutable-path-infos (store-path-list paths))
0f3d2504
LC
947 "Return information about the subset of PATHS that is
948substitutable. For each substitutable path, a `substitutable?' object is
dd78e90a
LC
949returned; thus, the resulting list can be shorter than PATHS. Furthermore,
950that there is no guarantee that the order of the resulting list matches the
951order of PATHS."
0f3d2504
LC
952 substitutable-path-list))
953
f9aefa2d
LC
954(define built-in-builders
955 (let ((builders (operation (built-in-builders)
956 "Return the built-in builders."
957 string-list)))
958 (lambda (store)
959 "Return the names of the supported built-in derivation builders
960supported by STORE."
961 ;; Check whether STORE's version supports this RPC and built-in
962 ;; derivation builders in general, which appeared in Guix > 0.11.0.
963 ;; Return the empty list if it doesn't. Note that this RPC does not
964 ;; exist in 'nix-daemon'.
965 (if (or (> (nix-server-major-version store) #x100)
966 (and (= (nix-server-major-version store) #x100)
967 (>= (nix-server-minor-version store) #x60)))
968 (builders store)
969 '()))))
970
e3fd0ce6
LC
971(define-operation (optimize-store)
972 "Optimize the store by hard-linking identical files (\"deduplication\".)
973Return #t on success."
974 ;; Note: the daemon in Guix <= 0.8.2 does not implement this RPC.
975 boolean)
976
c63d9403
LC
977(define verify-store
978 (let ((verify (operation (verify-store (boolean check-contents?)
979 (boolean repair?))
980 "Verify the store."
981 boolean)))
982 (lambda* (store #:key check-contents? repair?)
983 "Verify the integrity of the store and return false if errors remain,
984and true otherwise. When REPAIR? is true, repair any missing or altered store
985items by substituting them (this typically requires root privileges because it
986is not an atomic operation.) When CHECK-CONTENTS? is true, check the contents
987of store items; this can take a lot of time."
988 (not (verify store check-contents? repair?)))))
989
3259877d
LC
990(define (run-gc server action to-delete min-freed)
991 "Perform the garbage-collector operation ACTION, one of the
992`gc-action' values. When ACTION is `delete-specific', the TO-DELETE is
993the list of store paths to delete. IGNORE-LIVENESS? should always be
994#f. MIN-FREED is the minimum amount of disk space to be freed, in
995bytes, before the GC can stop. Return the list of store paths delete,
996and the number of bytes freed."
997 (let ((s (nix-server-socket server)))
998 (write-int (operation-id collect-garbage) s)
999 (write-int action s)
1000 (write-store-path-list to-delete s)
1001 (write-arg boolean #f s) ; ignore-liveness?
1002 (write-long-long min-freed s)
1003 (write-int 0 s) ; obsolete
1004 (when (>= (nix-server-minor-version server) 5)
1005 ;; Obsolete `use-atime' and `max-atime' parameters.
1006 (write-int 0 s)
1007 (write-int 0 s))
1008
1009 ;; Loop until the server is done sending error output.
1010 (let loop ((done? (process-stderr server)))
1011 (or done? (loop (process-stderr server))))
1012
1013 (let ((paths (read-store-path-list s))
1014 (freed (read-long-long s))
1015 (obsolete (read-long-long s)))
000c59b6
LC
1016 (unless (null? paths)
1017 ;; To be on the safe side, completely invalidate both caches.
1018 ;; Otherwise we could end up returning store paths that are no longer
1019 ;; valid.
1020 (hash-clear! (nix-server-add-to-store-cache server))
1021 (hash-clear! (nix-server-add-text-to-store-cache server)))
1022
3259877d
LC
1023 (values paths freed))))
1024
1025(define-syntax-rule (%long-long-max)
1026 ;; Maximum unsigned 64-bit integer.
1027 (- (expt 2 64) 1))
1028
1029(define (live-paths server)
1030 "Return the list of live store paths---i.e., store paths still
1031referenced, and thus not subject to being garbage-collected."
1032 (run-gc server (gc-action return-live) '() (%long-long-max)))
1033
1034(define (dead-paths server)
1035 "Return the list of dead store paths---i.e., store paths no longer
1036referenced, and thus subject to being garbage-collected."
1037 (run-gc server (gc-action return-dead) '() (%long-long-max)))
1038
1039(define* (collect-garbage server #:optional (min-freed (%long-long-max)))
1040 "Collect garbage from the store at SERVER. If MIN-FREED is non-zero,
1041then collect at least MIN-FREED bytes. Return the paths that were
1042collected, and the number of bytes freed."
1043 (run-gc server (gc-action delete-dead) '() min-freed))
1044
1045(define* (delete-paths server paths #:optional (min-freed (%long-long-max)))
1046 "Delete PATHS from the store at SERVER, if they are no longer
1047referenced. If MIN-FREED is non-zero, then stop after at least
1048MIN-FREED bytes have been collected. Return the paths that were
1049collected, and the number of bytes freed."
1050 (run-gc server (gc-action delete-specific) paths min-freed))
1051
526382ff
LC
1052(define (import-paths server port)
1053 "Import the set of store paths read from PORT into SERVER's store. An error
1054is raised if the set of paths read from PORT is not signed (as per
1055'export-path #:sign? #t'.) Return the list of store paths imported."
1056 (let ((s (nix-server-socket server)))
1057 (write-int (operation-id import-paths) s)
1058 (let loop ((done? (process-stderr server port)))
1059 (or done? (loop (process-stderr server port))))
1060 (read-store-path-list s)))
1061
1062(define* (export-path server path port #:key (sign? #t))
1063 "Export PATH to PORT. When SIGN? is true, sign it."
1064 (let ((s (nix-server-socket server)))
1065 (write-int (operation-id export-path) s)
1066 (write-store-path path s)
1067 (write-arg boolean sign? s)
1068 (let loop ((done? (process-stderr server port)))
1069 (or done? (loop (process-stderr server port))))
1070 (= 1 (read-int s))))
1071
5b3d863f 1072(define* (export-paths server paths port #:key (sign? #t) recursive?)
99fbddf9 1073 "Export the store paths listed in PATHS to PORT, in topological order,
5b3d863f
LC
1074signing them if SIGN? is true. When RECURSIVE? is true, export the closure of
1075PATHS---i.e., PATHS and all their dependencies."
cafb92d8 1076 (define ordered
5b3d863f
LC
1077 (let ((sorted (topologically-sorted server paths)))
1078 ;; When RECURSIVE? is #f, filter out the references of PATHS.
1079 (if recursive?
1080 sorted
1081 (filter (cut member <> paths) sorted))))
cafb92d8 1082
1d506993
LC
1083 (let loop ((paths ordered))
1084 (match paths
1085 (()
1086 (write-int 0 port))
1087 ((head tail ...)
1088 (write-int 1 port)
1089 (and (export-path server head port #:sign? sign?)
1090 (loop tail))))))
526382ff 1091
16748d80
LC
1092(define-operation (query-failed-paths)
1093 "Return the list of store items for which a build failure is cached.
1094
1095The result is always the empty list unless the daemon was started with
1096'--cache-failures'."
1097 store-path-list)
1098
1099(define-operation (clear-failed-paths (store-path-list items))
1100 "Remove ITEMS from the list of cached build failures.
1101
1102This makes sense only when the daemon was started with '--cache-failures'."
1103 boolean)
1104
6bfec3ed 1105(define* (register-path path
689142cd
LC
1106 #:key (references '()) deriver prefix
1107 state-directory)
6bfec3ed 1108 "Register PATH as a valid store file, with REFERENCES as its list of
bb31e0a3
LC
1109references, and DERIVER as its deriver (.drv that led to it.) If PREFIX is
1110not #f, it must be the name of the directory containing the new store to
689142cd
LC
1111initialize; if STATE-DIRECTORY is not #f, it must be a string containing the
1112absolute file name to the state directory of the store being initialized.
1113Return #t on success.
6bfec3ed
LC
1114
1115Use with care as it directly modifies the store! This is primarily meant to
1116be used internally by the daemon's build hook."
1117 ;; Currently this is implemented by calling out to the fine C++ blob.
95fa173e
LC
1118 (let ((pipe (apply open-pipe* OPEN_WRITE %guix-register-program
1119 `(,@(if prefix
1120 `("--prefix" ,prefix)
1121 '())
1122 ,@(if state-directory
1123 `("--state-directory" ,state-directory)
1124 '())))))
1125 (and pipe
1126 (begin
1127 (format pipe "~a~%~a~%~a~%"
1128 path (or deriver "") (length references))
1129 (for-each (cut format pipe "~a~%" <>) references)
1130 (zero? (close-pipe pipe))))))
6bfec3ed 1131
26bbbb95 1132\f
e87f0591
LC
1133;;;
1134;;; Store monad.
1135;;;
1136
4e190c28
LC
1137(define-syntax-rule (define-alias new old)
1138 (define-syntax new (identifier-syntax old)))
e87f0591 1139
4e190c28
LC
1140;; The store monad allows us to (1) build sequences of operations in the
1141;; store, and (2) make the store an implicit part of the execution context,
1142;; rather than a parameter of every single function.
1143(define-alias %store-monad %state-monad)
1144(define-alias store-return state-return)
1145(define-alias store-bind state-bind)
e87f0591 1146
5808dcc2
LC
1147(define (preserve-documentation original proc)
1148 "Return PROC with documentation taken from ORIGINAL."
1149 (set-object-property! proc 'documentation
1150 (procedure-property original 'documentation))
1151 proc)
1152
e87f0591
LC
1153(define (store-lift proc)
1154 "Lift PROC, a procedure whose first argument is a connection to the store,
1155in the store monad."
5808dcc2
LC
1156 (preserve-documentation proc
1157 (lambda args
1158 (lambda (store)
1159 (values (apply proc store args) store)))))
e87f0591 1160
023d9892
LC
1161(define (store-lower proc)
1162 "Lower PROC, a monadic procedure in %STORE-MONAD, to a \"normal\" procedure
1163taking the store as its first argument."
5808dcc2
LC
1164 (preserve-documentation proc
1165 (lambda (store . args)
1166 (run-with-store store (apply proc args)))))
023d9892 1167
e87f0591
LC
1168;;
1169;; Store monad operators.
1170;;
1171
ad372953
LC
1172(define* (text-file name text
1173 #:optional (references '()))
e87f0591 1174 "Return as a monadic value the absolute file name in the store of the file
ad372953
LC
1175containing TEXT, a string. REFERENCES is a list of store items that the
1176resulting text file refers to; it defaults to the empty list."
e87f0591 1177 (lambda (store)
ad372953 1178 (values (add-text-to-store store name text references)
4e190c28 1179 store)))
e87f0591
LC
1180
1181(define* (interned-file file #:optional name
1ec32f4a 1182 #:key (recursive? #t) (select? true))
e87f0591
LC
1183 "Return the name of FILE once interned in the store. Use NAME as its store
1184name, or the basename of FILE if NAME is omitted.
1185
1186When RECURSIVE? is true, the contents of FILE are added recursively; if FILE
1187designates a flat file and RECURSIVE? is true, its contents are added, and its
1ec32f4a
LC
1188permission bits are kept.
1189
1190When RECURSIVE? is true, call (SELECT? FILE STAT) for each directory entry,
1191where FILE is the entry's absolute file name and STAT is the result of
1192'lstat'; exclude entries for which SELECT? does not return true."
e87f0591 1193 (lambda (store)
4e190c28 1194 (values (add-to-store store (or name (basename file))
1ec32f4a
LC
1195 recursive? "sha256" file
1196 #:select? select?)
4e190c28 1197 store)))
e87f0591 1198
abac874b
LC
1199(define build
1200 ;; Monadic variant of 'build-things'.
1201 (store-lift build-things))
1202
4f740b67
AK
1203(define set-build-options*
1204 (store-lift set-build-options))
1205
e74f64b9
LC
1206(define references*
1207 (store-lift references))
1208
98a7b528
LC
1209(define-inlinable (current-system)
1210 ;; Consult the %CURRENT-SYSTEM fluid at bind time. This is equivalent to
1211 ;; (lift0 %current-system %store-monad), but inlinable, thus avoiding
1212 ;; closure allocation in some cases.
1213 (lambda (state)
1214 (values (%current-system) state)))
1215
1216(define-inlinable (set-current-system system)
1217 ;; Set the %CURRENT-SYSTEM fluid at bind time.
1218 (lambda (state)
1219 (values (%current-system system) state)))
1220
e87f0591
LC
1221(define %guile-for-build
1222 ;; The derivation of the Guile to be used within the build environment,
1223 ;; when using 'gexp->derivation' and co.
1224 (make-parameter #f))
1225
1226(define* (run-with-store store mval
1227 #:key
1228 (guile-for-build (%guile-for-build))
1229 (system (%current-system)))
1230 "Run MVAL, a monadic value in the store monad, in STORE, an open store
3698f524 1231connection, and return the result."
a8afb9ae
LC
1232 ;; Initialize the dynamic bindings here to avoid bad surprises. The
1233 ;; difficulty lies in the fact that dynamic bindings are resolved at
1234 ;; bind-time and not at call time, which can be disconcerting.
e87f0591 1235 (parameterize ((%guile-for-build guile-for-build)
a8afb9ae
LC
1236 (%current-system system)
1237 (%current-target-system #f))
3698f524
LC
1238 (call-with-values (lambda ()
1239 (run-with-state mval store))
1240 (lambda (result store)
1241 ;; Discard the state.
1242 result))))
e87f0591
LC
1243
1244\f
26bbbb95
LC
1245;;;
1246;;; Store paths.
1247;;;
1248
1249(define %store-prefix
1250 ;; Absolute path to the Nix store.
1d6816f9 1251 (make-parameter %store-directory))
26bbbb95 1252
f39bd08a
LC
1253(define (store-path? path)
1254 "Return #t if PATH is a store path."
1255 ;; This is a lightweight check, compared to using a regexp, but this has to
1256 ;; be fast as it's called often in `derivation', for instance.
1257 ;; `isStorePath' in Nix does something similar.
1258 (string-prefix? (%store-prefix) path))
26bbbb95 1259
9336e5b5
LC
1260(define (direct-store-path? path)
1261 "Return #t if PATH is a store path, and not a sub-directory of a store path.
1262This predicate is sometimes needed because files *under* a store path are not
1263valid inputs."
1264 (and (store-path? path)
eee21271 1265 (not (string=? path (%store-prefix)))
9336e5b5
LC
1266 (let ((len (+ 1 (string-length (%store-prefix)))))
1267 (not (string-index (substring path len) #\/)))))
1268
cdb5b075
CS
1269(define (direct-store-path path)
1270 "Return the direct store path part of PATH, stripping components after
1271'/gnu/store/xxxx-foo'."
1272 (let ((prefix-length (+ (string-length (%store-prefix)) 35)))
1273 (if (> (string-length path) prefix-length)
1274 (let ((slash (string-index path #\/ prefix-length)))
1275 (if slash (string-take path slash) path))
1276 path)))
1277
26bbbb95
LC
1278(define (derivation-path? path)
1279 "Return #t if PATH is a derivation path."
1280 (and (store-path? path) (string-suffix? ".drv" path)))
e3d74106 1281
5c0f1845
LC
1282(define store-regexp*
1283 ;; The substituter makes repeated calls to 'store-path-hash-part', hence
1284 ;; this optimization.
55b2d921
LC
1285 (mlambda (store)
1286 "Return a regexp matching a file in STORE."
1287 (make-regexp (string-append "^" (regexp-quote store)
1288 "/([0-9a-df-np-sv-z]{32})-([^/]+)$"))))
5c0f1845 1289
e3d74106
LC
1290(define (store-path-package-name path)
1291 "Return the package name part of PATH, a file name in the store."
5c0f1845
LC
1292 (let ((path-rx (store-regexp* (%store-prefix))))
1293 (and=> (regexp-exec path-rx path)
1294 (cut match:substring <> 2))))
2c6ab6cc
LC
1295
1296(define (store-path-hash-part path)
1297 "Return the hash part of PATH as a base32 string, or #f if PATH is not a
1298syntactically valid store path."
5c0f1845 1299 (let ((path-rx (store-regexp* (%store-prefix))))
2c6ab6cc
LC
1300 (and=> (regexp-exec path-rx path)
1301 (cut match:substring <> 1))))
eddd4077
LC
1302
1303(define (log-file store file)
1304 "Return the build log file for FILE, or #f if none could be found. FILE
1305must be an absolute store file name, or a derivation file name."
eddd4077 1306 (cond ((derivation-path? file)
021a201f 1307 (let* ((base (basename file))
80d0447c 1308 (log (string-append (dirname %state-directory) ; XXX
f5768afa 1309 "/log/guix/drvs/"
021a201f
LC
1310 (string-take base 2) "/"
1311 (string-drop base 2)))
1312 (log.bz2 (string-append log ".bz2")))
1313 (cond ((file-exists? log.bz2) log.bz2)
1314 ((file-exists? log) log)
1315 (else #f))))
eddd4077
LC
1316 (else
1317 (match (valid-derivers store file)
1318 ((derivers ...)
1319 ;; Return the first that works.
1320 (any (cut log-file store <>) derivers))
1321 (_ #f)))))