store: Add 'with-build-handler'.
[jackhill/guix/guix.git] / guix / store.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
041b340d 2;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
f3a42251 3;;; Copyright © 2018 Jan Nieuwenhuizen <janneke@gnu.org>
5d52d106 4;;; Copyright © 2019, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
771c5e15 5;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de>
77d3cf08 6;;;
233e7676 7;;; This file is part of GNU Guix.
77d3cf08 8;;;
233e7676 9;;; GNU Guix is free software; you can redistribute it and/or modify it
77d3cf08
LC
10;;; under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 3 of the License, or (at
12;;; your option) any later version.
13;;;
233e7676 14;;; GNU Guix is distributed in the hope that it will be useful, but
77d3cf08
LC
15;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
233e7676 20;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
77d3cf08
LC
21
22(define-module (guix store)
82058eff 23 #:use-module (guix utils)
d8eea3d2 24 #:use-module (guix config)
de9fbe9c 25 #:use-module (guix deprecation)
f9704f17 26 #:use-module (guix memoization)
0f41c26f 27 #:use-module (guix serialization)
e87f0591 28 #:use-module (guix monads)
c6080c32 29 #:use-module (guix records)
4c0c4db0 30 #:use-module (guix base16)
cd041b26 31 #:use-module (guix base32)
ca719424 32 #:use-module (gcrypt hash)
03870da8 33 #:use-module (guix profiling)
b0a6a971 34 #:autoload (guix build syscalls) (terminal-columns)
77d3cf08 35 #:use-module (rnrs bytevectors)
2535635f 36 #:use-module (ice-9 binary-ports)
c6080c32 37 #:use-module ((ice-9 control) #:select (let/ec))
77d3cf08
LC
38 #:use-module (srfi srfi-1)
39 #:use-module (srfi srfi-9)
bf8e7fc5 40 #:use-module (srfi srfi-9 gnu)
6581ec9a 41 #:use-module (srfi srfi-11)
77d3cf08 42 #:use-module (srfi srfi-26)
e87088c9
LC
43 #:use-module (srfi srfi-34)
44 #:use-module (srfi srfi-35)
26bbbb95 45 #:use-module (srfi srfi-39)
77d3cf08 46 #:use-module (ice-9 match)
3f1e6939 47 #:use-module (ice-9 vlist)
6bfec3ed 48 #:use-module (ice-9 popen)
b100a704 49 #:use-module (ice-9 threads)
1f3ea898 50 #:use-module (ice-9 format)
1397b422
LC
51 #:use-module (web uri)
52 #:export (%daemon-socket-uri
a9d2a105 53 %gc-roots-directory
f8a8e0fe 54 %default-substitute-urls
9fd72fb1 55
de9fbe9c
LC
56 store-connection?
57 store-connection-version
58 store-connection-major-version
59 store-connection-minor-version
60 store-connection-socket
61
62 ;; Deprecated forms for 'store-connection'.
9fd72fb1 63 nix-server?
dc0f74e5 64 nix-server-version
77d3cf08
LC
65 nix-server-major-version
66 nix-server-minor-version
67 nix-server-socket
de9fbe9c 68
dc0f74e5 69 current-store-protocol-version ;for internal use
c6080c32 70 mcached
77d3cf08 71
f9e8a123
LC
72 &store-error store-error?
73 &store-connection-error store-connection-error?
74 store-connection-error-file
75 store-connection-error-code
76 &store-protocol-error store-protocol-error?
77 store-protocol-error-message
78 store-protocol-error-status
79
80 ;; Deprecated forms for '&store-error' et al.
e87088c9 81 &nix-error nix-error?
ef86c39f
LC
82 &nix-connection-error nix-connection-error?
83 nix-connection-error-file
84 nix-connection-error-code
e87088c9
LC
85 &nix-protocol-error nix-protocol-error?
86 nix-protocol-error-message
87 nix-protocol-error-status
88
26bbbb95 89 hash-algo
07e70f48 90 build-mode
26bbbb95 91
77d3cf08 92 open-connection
2f608c14 93 port->connection
3abaf0c4 94 close-connection
ce4a4829 95 with-store
77d3cf08 96 set-build-options
4f740b67 97 set-build-options*
31ef99a8 98 valid-path?
82058eff 99 query-path-hash
11e7a6cf 100 hash-part->path
533d1768 101 query-path-info
0d268c5d 102 add-data-to-store
77d3cf08
LC
103 add-text-to-store
104 add-to-store
7f11efba 105 add-file-tree-to-store
f3a42251 106 binary-file
041b340d 107 with-build-handler
abac874b
LC
108 build-things
109 build
16748d80
LC
110 query-failed-paths
111 clear-failed-paths
3259877d 112 add-temp-root
34811f02 113 add-indirect-root
a9d2a105
LC
114 add-permanent-root
115 remove-permanent-root
26bbbb95 116
0f3d2504
LC
117 substitutable?
118 substitutable-path
119 substitutable-deriver
120 substitutable-references
121 substitutable-download-size
122 substitutable-nar-size
123 has-substitutes?
124 substitutable-paths
125 substitutable-path-info
126
533d1768
DT
127 path-info?
128 path-info-deriver
129 path-info-hash
130 path-info-references
131 path-info-registration-time
132 path-info-nar-size
133
f9aefa2d 134 built-in-builders
fae31edc 135 references
6581ec9a 136 references/substitutes
e74f64b9 137 references*
0744a9f0 138 query-path-info*
3f1e6939 139 requisites
fae31edc 140 referrers
e3fd0ce6 141 optimize-store
c63d9403 142 verify-store
50add477 143 topologically-sorted
fae31edc
LC
144 valid-derivers
145 query-derivation-outputs
3259877d
LC
146 live-paths
147 dead-paths
148 collect-garbage
149 delete-paths
526382ff
LC
150 import-paths
151 export-paths
3259877d 152
dcee50c1
LC
153 current-build-output-port
154
e87f0591
LC
155 %store-monad
156 store-bind
157 store-return
158 store-lift
023d9892 159 store-lower
e87f0591
LC
160 run-with-store
161 %guile-for-build
98a7b528
LC
162 current-system
163 set-current-system
e51de343 164 current-target-system
5d52d106 165 set-current-target
e87f0591
LC
166 text-file
167 interned-file
7f11efba 168 interned-file-tree
e87f0591 169
26bbbb95 170 %store-prefix
cd041b26
LC
171 store-path
172 output-path
173 fixed-output-path
26bbbb95 174 store-path?
9336e5b5 175 direct-store-path?
e3d74106 176 derivation-path?
771c5e15 177 store-path-base
2c6ab6cc 178 store-path-package-name
eddd4077 179 store-path-hash-part
cdb5b075 180 direct-store-path
fb94d82b 181 derivation-log-file
eddd4077 182 log-file))
77d3cf08 183
6ef61cc4 184(define %protocol-version #x163)
77d3cf08 185
d66b704b
LC
186(define %worker-magic-1 #x6e697863) ; "nixc"
187(define %worker-magic-2 #x6478696f) ; "dxio"
77d3cf08
LC
188
189(define (protocol-major magic)
190 (logand magic #xff00))
191(define (protocol-minor magic)
192 (logand magic #x00ff))
dc0f74e5
LC
193(define (protocol-version major minor)
194 (logior major minor))
77d3cf08
LC
195
196(define-syntax define-enumerate-type
197 (syntax-rules ()
198 ((_ name->int (name id) ...)
199 (define-syntax name->int
200 (syntax-rules (name ...)
201 ((_ name) id) ...)))))
202
203(define-enumerate-type operation-id
204 ;; operation numbers from worker-protocol.hh
205 (quit 0)
206 (valid-path? 1)
207 (has-substitutes? 3)
208 (query-path-hash 4)
209 (query-references 5)
210 (query-referrers 6)
211 (add-to-store 7)
212 (add-text-to-store 8)
abac874b 213 (build-things 9)
77d3cf08
LC
214 (ensure-path 10)
215 (add-temp-root 11)
216 (add-indirect-root 12)
217 (sync-with-gc 13)
218 (find-roots 14)
219 (export-path 16)
220 (query-deriver 18)
221 (set-options 19)
222 (collect-garbage 20)
63193ebf 223 ;;(query-substitutable-path-info 21) ; obsolete as of #x10c
77d3cf08 224 (query-derivation-outputs 22)
63193ebf 225 (query-all-valid-paths 23)
77d3cf08
LC
226 (query-failed-paths 24)
227 (clear-failed-paths 25)
228 (query-path-info 26)
229 (import-paths 27)
63193ebf
LC
230 (query-derivation-output-names 28)
231 (query-path-from-hash-part 29)
232 (query-substitutable-path-infos 30)
233 (query-valid-paths 31)
fae31edc 234 (query-substitutable-paths 32)
e3fd0ce6 235 (query-valid-derivers 33)
c63d9403 236 (optimize-store 34)
f9aefa2d
LC
237 (verify-store 35)
238 (built-in-builders 80))
77d3cf08
LC
239
240(define-enumerate-type hash-algo
241 ;; hash.hh
242 (md5 1)
243 (sha1 2)
244 (sha256 3))
245
07e70f48
LC
246(define-enumerate-type build-mode
247 ;; store-api.hh
248 (normal 0)
249 (repair 1)
250 (check 2))
251
3259877d
LC
252(define-enumerate-type gc-action
253 ;; store-api.hh
254 (return-live 0)
255 (return-dead 1)
256 (delete-dead 2)
257 (delete-specific 3))
258
77d3cf08 259(define %default-socket-path
80d0447c 260 (string-append %state-directory "/daemon-socket/socket"))
77d3cf08 261
1397b422
LC
262(define %daemon-socket-uri
263 ;; URI or file name of the socket the daemon listens too.
9fd72fb1
LC
264 (make-parameter (or (getenv "GUIX_DAEMON_SOCKET")
265 %default-socket-path)))
266
267
77d3cf08 268\f
0f3d2504
LC
269;; Information about a substitutable store path.
270(define-record-type <substitutable>
271 (substitutable path deriver refs dl-size nar-size)
272 substitutable?
273 (path substitutable-path)
274 (deriver substitutable-deriver)
275 (refs substitutable-references)
276 (dl-size substitutable-download-size)
277 (nar-size substitutable-nar-size))
278
279(define (read-substitutable-path-list p)
280 (let loop ((len (read-int p))
281 (result '()))
282 (if (zero? len)
283 (reverse result)
284 (let ((path (read-store-path p))
285 (deriver (read-store-path p))
286 (refs (read-store-path-list p))
287 (dl-size (read-long-long p))
288 (nar-size (read-long-long p)))
289 (loop (- len 1)
290 (cons (substitutable path deriver refs dl-size nar-size)
291 result))))))
292
533d1768
DT
293;; Information about a store path.
294(define-record-type <path-info>
295 (path-info deriver hash references registration-time nar-size)
296 path-info?
22572d56 297 (deriver path-info-deriver) ;string | #f
533d1768
DT
298 (hash path-info-hash)
299 (references path-info-references)
300 (registration-time path-info-registration-time)
301 (nar-size path-info-nar-size))
302
303(define (read-path-info p)
22572d56
LC
304 (let ((deriver (match (read-store-path p)
305 ("" #f)
306 (x x)))
533d1768
DT
307 (hash (base16-string->bytevector (read-string p)))
308 (refs (read-store-path-list p))
309 (registration-time (read-int p))
310 (nar-size (read-long-long p)))
311 (path-info deriver hash refs registration-time nar-size)))
312
77d3cf08 313(define-syntax write-arg
0d268c5d
LC
314 (syntax-rules (integer boolean bytevector
315 string string-list string-pairs
3259877d 316 store-path store-path-list base16)
77d3cf08
LC
317 ((_ integer arg p)
318 (write-int arg p))
319 ((_ boolean arg p)
320 (write-int (if arg 1 0) p))
0d268c5d
LC
321 ((_ bytevector arg p)
322 (write-bytevector arg p))
77d3cf08
LC
323 ((_ string arg p)
324 (write-string arg p))
325 ((_ string-list arg p)
82058eff 326 (write-string-list arg p))
6c20d1d0
LC
327 ((_ string-pairs arg p)
328 (write-string-pairs arg p))
3259877d
LC
329 ((_ store-path arg p)
330 (write-store-path arg p))
331 ((_ store-path-list arg p)
332 (write-store-path-list arg p))
82058eff
LC
333 ((_ base16 arg p)
334 (write-string (bytevector->base16-string arg) p))))
77d3cf08
LC
335
336(define-syntax read-arg
f9aefa2d 337 (syntax-rules (integer boolean string store-path store-path-list string-list
533d1768 338 substitutable-path-list path-info base16)
77d3cf08
LC
339 ((_ integer p)
340 (read-int p))
341 ((_ boolean p)
342 (not (zero? (read-int p))))
343 ((_ string p)
344 (read-string p))
345 ((_ store-path p)
82058eff 346 (read-store-path p))
3259877d
LC
347 ((_ store-path-list p)
348 (read-store-path-list p))
f9aefa2d
LC
349 ((_ string-list p)
350 (read-string-list p))
0f3d2504
LC
351 ((_ substitutable-path-list p)
352 (read-substitutable-path-list p))
533d1768
DT
353 ((_ path-info p)
354 (read-path-info p))
0f3d2504 355 ((_ base16 p)
82058eff 356 (base16-string->bytevector (read-string p)))))
77d3cf08
LC
357
358\f
359;; remote-store.cc
360
de9fbe9c
LC
361(define-record-type* <store-connection> store-connection %make-store-connection
362 store-connection?
363 (socket store-connection-socket)
364 (major store-connection-major-version)
365 (minor store-connection-minor-version)
2c3f47ee 366
de9fbe9c
LC
367 (buffer store-connection-output-port) ;output port
368 (flush store-connection-flush-output) ;thunk
e037e9db 369
2c3f47ee
LC
370 ;; Caches. We keep them per-connection, because store paths build
371 ;; during the session are temporary GC roots kept for the duration of
372 ;; the session.
de9fbe9c
LC
373 (ats-cache store-connection-add-to-store-cache)
374 (atts-cache store-connection-add-text-to-store-cache)
375 (object-cache store-connection-object-cache
3961edf2
LC
376 (default vlist-null)) ;vhash
377 (built-in-builders store-connection-built-in-builders
378 (default (delay '())))) ;promise
77d3cf08 379
de9fbe9c 380(set-record-type-printer! <store-connection>
bf8e7fc5 381 (lambda (obj port)
de9fbe9c
LC
382 (format port "#<store-connection ~a.~a ~a>"
383 (store-connection-major-version obj)
384 (store-connection-minor-version obj)
bf8e7fc5
LC
385 (number->string (object-address obj)
386 16))))
387
de9fbe9c
LC
388(define-deprecated/alias nix-server? store-connection?)
389(define-deprecated/alias nix-server-major-version
390 store-connection-major-version)
391(define-deprecated/alias nix-server-minor-version
392 store-connection-minor-version)
393(define-deprecated/alias nix-server-socket store-connection-socket)
394
395
f9e8a123
LC
396(define-condition-type &store-error &error
397 store-error?)
e87088c9 398
f9e8a123
LC
399(define-condition-type &store-connection-error &store-error
400 store-connection-error?
401 (file store-connection-error-file)
402 (errno store-connection-error-code))
403
404(define-condition-type &store-protocol-error &store-error
405 store-protocol-error?
406 (message store-protocol-error-message)
407 (status store-protocol-error-status))
408
409(define-deprecated/alias &nix-error &store-error)
410(define-deprecated/alias nix-error? store-error?)
411(define-deprecated/alias &nix-connection-error &store-connection-error)
412(define-deprecated/alias nix-connection-error? store-connection-error?)
413(define-deprecated/alias nix-connection-error-file
414 store-connection-error-file)
415(define-deprecated/alias nix-connection-error-code
416 store-connection-error-code)
417(define-deprecated/alias &nix-protocol-error &store-protocol-error)
418(define-deprecated/alias nix-protocol-error? store-protocol-error?)
419(define-deprecated/alias nix-protocol-error-message
420 store-protocol-error-message)
421(define-deprecated/alias nix-protocol-error-status
422 store-protocol-error-status)
ef86c39f 423
e87088c9 424
3b5cd17a
LC
425(define-syntax-rule (system-error-to-connection-error file exp ...)
426 "Catch 'system-error' exceptions and translate them to
f9e8a123 427'&store-connection-error'."
3b5cd17a
LC
428 (catch 'system-error
429 (lambda ()
430 exp ...)
431 (lambda args
432 (let ((errno (system-error-errno args)))
f9e8a123 433 (raise (condition (&store-connection-error
3b5cd17a
LC
434 (file file)
435 (errno errno))))))))
436
6230d6f0
LC
437(define (open-unix-domain-socket file)
438 "Connect to the Unix-domain socket at FILE and return it. Raise a
f9e8a123 439'&store-connection-error' upon error."
77d3cf08
LC
440 (let ((s (with-fluids ((%default-port-encoding #f))
441 ;; This trick allows use of the `scm_c_read' optimization.
442 (socket PF_UNIX SOCK_STREAM 0)))
443 (a (make-socket-address PF_UNIX file)))
df1fab58 444
3b5cd17a
LC
445 (system-error-to-connection-error file
446 (connect s a)
447 s)))
ef86c39f 448
5df1395a
LC
449(define %default-guix-port
450 ;; Default port when connecting to a daemon over TCP/IP.
451 44146)
452
3dff90ce
LC
453(define (open-inet-socket host port)
454 "Connect to the Unix-domain socket at HOST:PORT and return it. Raise a
f9e8a123 455'&store-connection-error' upon error."
3dff90ce
LC
456 (let ((sock (with-fluids ((%default-port-encoding #f))
457 ;; This trick allows use of the `scm_c_read' optimization.
458 (socket PF_UNIX SOCK_STREAM 0))))
459 (define addresses
460 (getaddrinfo host
461 (if (number? port) (number->string port) port)
462 (if (number? port)
463 (logior AI_ADDRCONFIG AI_NUMERICSERV)
7ae97a4c
LC
464 AI_ADDRCONFIG)
465 0 ;any address family
466 SOCK_STREAM)) ;TCP only
3dff90ce
LC
467
468 (let loop ((addresses addresses))
469 (match addresses
470 ((ai rest ...)
471 (let ((s (socket (addrinfo:fam ai)
472 ;; TCP/IP only
473 SOCK_STREAM IPPROTO_IP)))
474
475 (catch 'system-error
476 (lambda ()
477 (connect s (addrinfo:addr ai))
950d51c9
LC
478
479 ;; Setting this option makes a dramatic difference because it
480 ;; avoids the "ACK delay" on our RPC messages.
481 (setsockopt s IPPROTO_TCP TCP_NODELAY 1)
3dff90ce
LC
482 s)
483 (lambda args
484 ;; Connection failed, so try one of the other addresses.
485 (close s)
486 (if (null? rest)
f9e8a123 487 (raise (condition (&store-connection-error
3dff90ce
LC
488 (file host)
489 (errno (system-error-errno args)))))
490 (loop rest))))))))))
491
1397b422
LC
492(define (connect-to-daemon uri)
493 "Connect to the daemon at URI, a string that may be an actual URI or a file
494name."
285f63e8 495 (define (not-supported)
f9e8a123 496 (raise (condition (&store-connection-error
285f63e8
LC
497 (file uri)
498 (errno ENOTSUP)))))
499
1397b422
LC
500 (define connect
501 (match (string->uri uri)
502 (#f ;URI is a file name
503 open-unix-domain-socket)
504 ((? uri? uri)
505 (match (uri-scheme uri)
506 ((or #f 'file 'unix)
507 (lambda (_)
508 (open-unix-domain-socket (uri-path uri))))
3dff90ce
LC
509 ('guix
510 (lambda (_)
5df1395a
LC
511 (open-inet-socket (uri-host uri)
512 (or (uri-port uri) %default-guix-port))))
285f63e8
LC
513 ((? symbol? scheme)
514 ;; Try to dynamically load a module for SCHEME.
515 ;; XXX: Errors are swallowed.
516 (match (false-if-exception
517 (resolve-interface `(guix store ,scheme)))
518 ((? module? module)
519 (match (false-if-exception
520 (module-ref module 'connect-to-daemon))
521 ((? procedure? connect)
522 (lambda (_)
523 (connect uri)))
524 (x (not-supported))))
525 (#f (not-supported))))
1397b422 526 (x
285f63e8 527 (not-supported))))))
1397b422
LC
528
529 (connect uri))
530
531(define* (open-connection #:optional (uri (%daemon-socket-uri))
6230d6f0 532 #:key port (reserve-space? #t) cpu-affinity)
1397b422
LC
533 "Connect to the daemon at URI (a string), or, if PORT is not #f, use it as
534the I/O port over which to communicate to a build daemon.
6230d6f0
LC
535
536When RESERVE-SPACE? is true, instruct it to reserve a little bit of extra
537space on the file system so that the garbage collector can still operate,
538should the disk become full. When CPU-AFFINITY is true, it must be an integer
539corresponding to an OS-level CPU number to which the daemon's worker process
540for this connection will be pinned. Return a server object."
13d5e8da
LC
541 (guard (c ((nar-error? c)
542 ;; One of the 'write-' or 'read-' calls below failed, but this is
543 ;; really a connection error.
544 (raise (condition
f9e8a123
LC
545 (&store-connection-error (file (or port uri))
546 (errno EPROTO))
13d5e8da 547 (&message (message "build daemon handshake failed"))))))
e037e9db
LC
548 (let*-values (((port)
549 (or port (connect-to-daemon uri)))
550 ((output flush)
551 (buffering-output-port port
552 (make-bytevector 8192))))
13d5e8da
LC
553 (write-int %worker-magic-1 port)
554 (let ((r (read-int port)))
555 (and (eqv? r %worker-magic-2)
556 (let ((v (read-int port)))
557 (and (eqv? (protocol-major %protocol-version)
558 (protocol-major v))
559 (begin
560 (write-int %protocol-version port)
561 (when (>= (protocol-minor v) 14)
562 (write-int (if cpu-affinity 1 0) port)
563 (when cpu-affinity
564 (write-int cpu-affinity port)))
565 (when (>= (protocol-minor v) 11)
566 (write-int (if reserve-space? 1 0) port))
3961edf2
LC
567 (letrec* ((built-in-builders
568 (delay (%built-in-builders conn)))
569 (conn
570 (%make-store-connection port
571 (protocol-major v)
572 (protocol-minor v)
573 output flush
574 (make-hash-table 100)
575 (make-hash-table 100)
576 vlist-null
577 built-in-builders)))
13d5e8da
LC
578 (let loop ((done? (process-stderr conn)))
579 (or done? (process-stderr conn)))
580 conn)))))))))
77d3cf08 581
2f608c14
LC
582(define* (port->connection port
583 #:key (version %protocol-version))
584 "Assimilate PORT, an input/output port, and return a connection to the
585daemon, assuming the given protocol VERSION.
586
587Warning: this procedure assumes that the initial handshake with the daemon has
588already taken place on PORT and that we're just continuing on this established
589connection. Use with care."
590 (let-values (((output flush)
591 (buffering-output-port port (make-bytevector 8192))))
3961edf2
LC
592 (define connection
593 (%make-store-connection port
594 (protocol-major version)
595 (protocol-minor version)
596 output flush
597 (make-hash-table 100)
598 (make-hash-table 100)
599 vlist-null
600 (delay (%built-in-builders connection))))
601
602 connection))
de9fbe9c
LC
603
604(define (store-connection-version store)
dc0f74e5 605 "Return the protocol version of STORE as an integer."
de9fbe9c
LC
606 (protocol-version (store-connection-major-version store)
607 (store-connection-minor-version store)))
608
609(define-deprecated/alias nix-server-version store-connection-version)
dc0f74e5 610
e037e9db
LC
611(define (write-buffered-output server)
612 "Flush SERVER's output port."
de9fbe9c
LC
613 (force-output (store-connection-output-port server))
614 ((store-connection-flush-output server)))
e037e9db 615
3abaf0c4
LC
616(define (close-connection server)
617 "Close the connection to SERVER."
de9fbe9c 618 (close (store-connection-socket server)))
3abaf0c4 619
95207e70
LC
620(define (call-with-store proc)
621 "Call PROC with an open store connection."
ce4a4829
LC
622 (let ((store (open-connection)))
623 (dynamic-wind
624 (const #f)
625 (lambda ()
dc0f74e5 626 (parameterize ((current-store-protocol-version
de9fbe9c 627 (store-connection-version store)))
95207e70 628 (proc store)))
ce4a4829
LC
629 (lambda ()
630 (false-if-exception (close-connection store))))))
631
95207e70
LC
632(define-syntax-rule (with-store store exp ...)
633 "Bind STORE to an open connection to the store and evaluate EXPs;
634automatically close the store when the dynamic extent of EXP is left."
635 (call-with-store (lambda (store) exp ...)))
636
dc0f74e5
LC
637(define current-store-protocol-version
638 ;; Protocol version of the store currently used. XXX: This is a hack to
639 ;; communicate the protocol version to the build output port. It's a hack
640 ;; because it could be inaccurrate, for instance if there's code that
641 ;; manipulates several store connections at once; it works well for the
642 ;; purposes of (guix status) though.
643 (make-parameter #f))
644
dcee50c1
LC
645(define current-build-output-port
646 ;; The port where build output is sent.
647 (make-parameter (current-error-port)))
648
526382ff
LC
649(define* (dump-port in out
650 #:optional len
651 #:key (buffer-size 16384))
652 "Read LEN bytes from IN (or as much as possible if LEN is #f) and write it
653to OUT, using chunks of BUFFER-SIZE bytes."
654 (define buffer
655 (make-bytevector buffer-size))
656
657 (let loop ((total 0)
658 (bytes (get-bytevector-n! in buffer 0
659 (if len
660 (min len buffer-size)
661 buffer-size))))
662 (or (eof-object? bytes)
663 (and len (= total len))
664 (let ((total (+ total bytes)))
665 (put-bytevector out buffer 0 bytes)
666 (loop total
667 (get-bytevector-n! in buffer 0
668 (if len
669 (min (- len total) buffer-size)
670 buffer-size)))))))
671
d28869af
LC
672(define %newlines
673 ;; Newline characters triggering a flush of 'current-build-output-port'.
76832d34 674 ;; Unlike Guile's 'line, we flush upon #\return so that progress reports
d28869af
LC
675 ;; that use that trick are correctly displayed.
676 (char-set #\newline #\return))
677
526382ff 678(define* (process-stderr server #:optional user-port)
dcee50c1
LC
679 "Read standard output and standard error from SERVER, writing it to
680CURRENT-BUILD-OUTPUT-PORT. Return #t when SERVER is done sending data, and
681#f otherwise; in the latter case, the caller should call `process-stderr'
bbdb3ffa
LC
682again until #t is returned or an error is raised.
683
684Since the build process's output cannot be assumed to be UTF-8, we
685conservatively consider it to be Latin-1, thereby avoiding possible
686encoding conversion errors."
77d3cf08 687 (define p
de9fbe9c 688 (store-connection-socket server))
77d3cf08
LC
689
690 ;; magic cookies from worker-protocol.hh
5674a3fd
LC
691 (define %stderr-next #x6f6c6d67) ; "olmg", build log
692 (define %stderr-read #x64617461) ; "data", data needed from source
693 (define %stderr-write #x64617416) ; "dat\x16", data for sink
694 (define %stderr-last #x616c7473) ; "alts", we're done
695 (define %stderr-error #x63787470) ; "cxtp", error reporting
77d3cf08
LC
696
697 (let ((k (read-int p)))
698 (cond ((= k %stderr-write)
526382ff
LC
699 ;; Write a byte stream to USER-PORT.
700 (let* ((len (read-int p))
701 (m (modulo len 8)))
6374633b
LC
702 (dump-port p user-port len
703 #:buffer-size (if (<= len 16384) 16384 65536))
526382ff
LC
704 (unless (zero? m)
705 ;; Consume padding, as for strings.
706 (get-bytevector-n p (- 8 m))))
dcee50c1 707 #f)
77d3cf08 708 ((= k %stderr-read)
526382ff 709 ;; Read a byte stream from USER-PORT.
5895f244
LC
710 ;; Note: Avoid 'get-bytevector-n' to work around
711 ;; <http://bugs.gnu.org/17591> in Guile up to 2.0.11.
526382ff 712 (let* ((max-len (read-int p))
5895f244
LC
713 (data (make-bytevector max-len))
714 (len (get-bytevector-n! user-port data 0 max-len)))
39d1e965 715 (write-bytevector data p len)
dcee50c1 716 #f))
77d3cf08 717 ((= k %stderr-next)
ce72c780
LC
718 ;; Log a string. Build logs are usually UTF-8-encoded, but they
719 ;; may also contain arbitrary byte sequences that should not cause
720 ;; this to fail. Thus, use the permissive
721 ;; 'read-maybe-utf8-string'.
722 (let ((s (read-maybe-utf8-string p)))
dcee50c1 723 (display s (current-build-output-port))
d28869af 724 (when (string-any %newlines s)
2535635f 725 (force-output (current-build-output-port)))
dcee50c1 726 #f))
77d3cf08 727 ((= k %stderr-error)
526382ff 728 ;; Report an error.
ce72c780 729 (let ((error (read-maybe-utf8-string p))
0ff3e3aa
LC
730 ;; Currently the daemon fails to send a status code for early
731 ;; errors like DB schema version mismatches, so check for EOF.
de9fbe9c 732 (status (if (and (>= (store-connection-minor-version server) 8)
0ff3e3aa 733 (not (eof-object? (lookahead-u8 p))))
77d3cf08
LC
734 (read-int p)
735 1)))
f9e8a123 736 (raise (condition (&store-protocol-error
e87088c9
LC
737 (message error)
738 (status status))))))
77d3cf08 739 ((= k %stderr-last)
dcee50c1 740 ;; The daemon is done (see `stopWork' in `nix-worker.cc'.)
77d3cf08
LC
741 #t)
742 (else
f9e8a123 743 (raise (condition (&store-protocol-error
e87088c9
LC
744 (message "invalid error code")
745 (status k))))))))
77d3cf08 746
4d581220 747(define %default-substitute-urls
d70533cb
LC
748 ;; Default list of substituters. This is *not* the list baked in
749 ;; 'guix-daemon', but it is used by 'guix-service-type' and and a couple of
750 ;; clients ('guix build --log-file' uses it.)
df061d07
LC
751 (map (if (false-if-exception (resolve-interface '(gnutls)))
752 (cut string-append "https://" <>)
753 (cut string-append "http://" <>))
757e633d 754 '("ci.guix.gnu.org")))
4d581220 755
81c580c8
LC
756(define (current-user-name)
757 "Return the name of the calling user."
758 (catch #t
759 (lambda ()
760 (passwd:name (getpwuid (getuid))))
761 (lambda _
762 (getenv "USER"))))
763
77d3cf08 764(define* (set-build-options server
c3eb878f 765 #:key keep-failed? keep-going? fallback?
77d3cf08 766 (verbosity 0)
2fba87ac 767 rounds ;number of build rounds
deac976d 768 max-build-jobs
6c20d1d0 769 timeout
deac976d 770 max-silent-time
7f44ab48
LC
771 (offload? #t)
772 (use-build-hook? *unspecified*) ;deprecated
77d3cf08
LC
773 (build-verbosity 0)
774 (log-type 0)
e036c31b 775 (print-build-trace #t)
81c580c8 776 (user-name (current-user-name))
dc0f74e5
LC
777
778 ;; When true, provide machine-readable "build
779 ;; traces" for use by (guix status). Old clients
780 ;; are unable to make sense, which is why it's
781 ;; disabled by default.
782 print-extended-build-trace?
783
6ef61cc4
LC
784 ;; When true, the daemon prefixes builder output
785 ;; with "@ build-log" traces so we can
786 ;; distinguish it from daemon output, and we can
787 ;; distinguish each builder's output
788 ;; (PRINT-BUILD-TRACE must be true as well.) The
789 ;; latter is particularly useful when
790 ;; MAX-BUILD-JOBS > 1.
791 multiplexed-build-output?
792
deac976d 793 build-cores
63193ebf 794 (use-substitutes? #t)
4d581220 795
fb4bf72b
LC
796 ;; Client-provided substitute URLs. If it is #f,
797 ;; the daemon's settings are used. Otherwise, it
798 ;; overrides the daemons settings; see 'guix
799 ;; substitute'.
b0a6a971
LC
800 (substitute-urls #f)
801
802 ;; Number of columns in the client's terminal.
38f50f49
LC
803 (terminal-columns (terminal-columns))
804
805 ;; Locale of the client.
806 (locale (false-if-exception (setlocale LC_ALL))))
77d3cf08
LC
807 ;; Must be called after `open-connection'.
808
809 (define socket
de9fbe9c 810 (store-connection-socket server))
77d3cf08 811
7f44ab48
LC
812 (unless (unspecified? use-build-hook?)
813 (warn-about-deprecation #:use-build-hook? #f
814 #:replacement #:offload?))
815
77d3cf08 816 (let-syntax ((send (syntax-rules ()
e036c31b
LC
817 ((_ (type option) ...)
818 (begin
819 (write-arg type option socket)
820 ...)))))
821 (write-int (operation-id set-options) socket)
822 (send (boolean keep-failed?) (boolean keep-going?)
deac976d 823 (boolean fallback?) (integer verbosity))
de9fbe9c 824 (when (< (store-connection-minor-version server) #x61)
deac976d
LC
825 (let ((max-build-jobs (or max-build-jobs 1))
826 (max-silent-time (or max-silent-time 3600)))
827 (send (integer max-build-jobs) (integer max-silent-time))))
de9fbe9c 828 (when (>= (store-connection-minor-version server) 2)
7f44ab48
LC
829 (send (boolean (if (unspecified? use-build-hook?)
830 offload?
831 use-build-hook?))))
de9fbe9c 832 (when (>= (store-connection-minor-version server) 4)
371e87d2
LC
833 (send (integer build-verbosity) (integer log-type)
834 (boolean print-build-trace)))
de9fbe9c
LC
835 (when (and (>= (store-connection-minor-version server) 6)
836 (< (store-connection-minor-version server) #x61))
deac976d
LC
837 (let ((build-cores (or build-cores (current-processor-count))))
838 (send (integer build-cores))))
de9fbe9c 839 (when (>= (store-connection-minor-version server) 10)
371e87d2 840 (send (boolean use-substitutes?)))
de9fbe9c 841 (when (>= (store-connection-minor-version server) 12)
dc0f74e5
LC
842 (let ((pairs `(;; This option is honored by 'guix substitute' et al.
843 ,@(if print-build-trace
844 `(("print-extended-build-trace"
845 . ,(if print-extended-build-trace? "1" "0")))
846 '())
6ef61cc4
LC
847 ,@(if multiplexed-build-output?
848 `(("multiplexed-build-output"
849 . ,(if multiplexed-build-output? "true" "false")))
850 '())
dc0f74e5 851 ,@(if timeout
41c45e78
LC
852 `(("build-timeout" . ,(number->string timeout)))
853 '())
deac976d
LC
854 ,@(if max-silent-time
855 `(("build-max-silent-time"
856 . ,(number->string max-silent-time)))
857 '())
858 ,@(if max-build-jobs
859 `(("build-max-jobs"
860 . ,(number->string max-build-jobs)))
861 '())
862 ,@(if build-cores
863 `(("build-cores" . ,(number->string build-cores)))
864 '())
fb4bf72b
LC
865 ,@(if substitute-urls
866 `(("substitute-urls"
867 . ,(string-join substitute-urls)))
2fba87ac
LC
868 '())
869 ,@(if rounds
870 `(("build-repeat"
871 . ,(number->string (max 0 (1- rounds)))))
b0a6a971 872 '())
81c580c8
LC
873 ,@(if user-name
874 `(("user-name" . ,user-name))
875 '())
b0a6a971
LC
876 ,@(if terminal-columns
877 `(("terminal-columns"
878 . ,(number->string terminal-columns)))
38f50f49
LC
879 '())
880 ,@(if locale
881 `(("locale" . ,locale))
fb4bf72b 882 '()))))
f401b1e9 883 (send (string-pairs pairs))))
dcee50c1
LC
884 (let loop ((done? (process-stderr server)))
885 (or done? (process-stderr server)))))
77d3cf08 886
e037e9db
LC
887(define (buffering-output-port port buffer)
888 "Return two value: an output port wrapped around PORT that uses BUFFER (a
889bytevector) as its internal buffer, and a thunk to flush this output port."
890 ;; Note: In Guile 2.2.2, custom binary output ports already have their own
891 ;; 4K internal buffer.
892 (define size
893 (bytevector-length buffer))
894
895 (define total 0)
896
897 (define (flush)
898 (put-bytevector port buffer 0 total)
38098241 899 (force-output port)
e037e9db
LC
900 (set! total 0))
901
902 (define (write bv offset count)
903 (if (zero? count) ;end of file
904 (flush)
905 (let loop ((offset offset)
906 (count count)
907 (written 0))
908 (cond ((= total size)
909 (flush)
910 (loop offset count written))
911 ((zero? count)
912 written)
913 (else
914 (let ((to-copy (min count (- size total))))
915 (bytevector-copy! bv offset buffer total to-copy)
916 (set! total (+ total to-copy))
917 (loop (+ offset to-copy) (- count to-copy)
918 (+ written to-copy))))))))
919
920 ;; Note: We need to return FLUSH because the custom binary port has no way
921 ;; to be notified of a 'force-output' call on itself.
922 (values (make-custom-binary-output-port "buffering-output-port"
923 write #f #f flush)
924 flush))
925
73b0ebdd
LC
926(define profiled?
927 (let ((profiled
928 (or (and=> (getenv "GUIX_PROFILING") string-tokenize)
929 '())))
930 (lambda (component)
931 "Return true if COMPONENT profiling is active."
932 (member component profiled))))
933
f4453df9
LC
934(define %rpc-calls
935 ;; Mapping from RPC names (symbols) to invocation counts.
936 (make-hash-table))
937
938(define* (show-rpc-profile #:optional (port (current-error-port)))
939 "Write to PORT a summary of the RPCs that have been made."
940 (let ((profile (sort (hash-fold alist-cons '() %rpc-calls)
941 (lambda (rpc1 rpc2)
942 (< (cdr rpc1) (cdr rpc2))))))
943 (format port "Remote procedure call summary: ~a RPCs~%"
944 (match profile
945 (((names . counts) ...)
946 (reduce + 0 counts))))
947 (for-each (match-lambda
948 ((rpc . count)
949 (format port " ~30a ... ~5@a~%" rpc count)))
950 profile)))
951
952(define record-operation
953 ;; Optionally, increment the number of calls of the given RPC.
03870da8
LC
954 (if (profiled? "rpc")
955 (begin
956 (register-profiling-hook! "rpc" show-rpc-profile)
957 (lambda (name)
958 (let ((count (or (hashq-ref %rpc-calls name) 0)))
959 (hashq-set! %rpc-calls name (+ count 1)))))
960 (lambda (_)
961 #t)))
f4453df9 962
fd060fd3 963(define-syntax operation
77d3cf08 964 (syntax-rules ()
fd060fd3 965 "Define a client-side RPC stub for the given operation."
3259877d 966 ((_ (name (type arg) ...) docstring return ...)
fd060fd3 967 (lambda (server arg ...)
77d3cf08 968 docstring
de9fbe9c
LC
969 (let* ((s (store-connection-socket server))
970 (buffered (store-connection-output-port server)))
f4453df9 971 (record-operation 'name)
e037e9db
LC
972 (write-int (operation-id name) buffered)
973 (write-arg type arg buffered)
77d3cf08 974 ...
e037e9db
LC
975 (write-buffered-output server)
976
dcee50c1
LC
977 ;; Loop until the server is done sending error output.
978 (let loop ((done? (process-stderr server)))
979 (or done? (loop (process-stderr server))))
3259877d 980 (values (read-arg return s) ...))))))
77d3cf08 981
fd060fd3
LC
982(define-syntax-rule (define-operation (name args ...)
983 docstring return ...)
984 (define name
985 (operation (name args ...) docstring return ...)))
986
31ef99a8 987(define-operation (valid-path? (string path))
06b76acc
LC
988 "Return #t when PATH designates a valid store item and #f otherwise (an
989invalid item may exist on disk but still be invalid, for instance because it
990is the result of an aborted or failed build.)
991
f9e8a123 992A '&store-protocol-error' condition is raised if PATH is not prefixed by the
06b76acc 993store directory (/gnu/store)."
31ef99a8
LC
994 boolean)
995
63193ebf 996(define-operation (query-path-hash (store-path path))
aa8fff0c 997 "Return the SHA256 hash of the nar serialization of PATH as a bytevector."
82058eff
LC
998 base16)
999
11e7a6cf
LC
1000(define hash-part->path
1001 (let ((query-path-from-hash-part
1002 (operation (query-path-from-hash-part (string hash))
1003 #f
1004 store-path)))
1005 (lambda (server hash-part)
1006 "Return the store path whose hash part is HASH-PART (a nix-base32
7fcb86da 1007string). Return the empty string if no such path exists."
11e7a6cf
LC
1008 ;; This RPC is primarily used by Hydra to reply to HTTP GETs of
1009 ;; /HASH.narinfo.
1010 (query-path-from-hash-part server hash-part))))
1011
533d1768
DT
1012(define-operation (query-path-info (store-path path))
1013 "Return the info (hash, references, etc.) for PATH."
1014 path-info)
1015
0d268c5d 1016(define add-data-to-store
fd060fd3
LC
1017 ;; A memoizing version of `add-to-store', to avoid repeated RPCs with
1018 ;; the very same arguments during a given session.
1019 (let ((add-text-to-store
0d268c5d 1020 (operation (add-text-to-store (string name) (bytevector text)
fd060fd3
LC
1021 (string-list references))
1022 #f
d1f7748a
LC
1023 store-path))
1024 (lookup (if (profiled? "add-data-to-store-cache")
1025 (let ((lookups 0)
1026 (hits 0)
1027 (drv 0)
1028 (scheme 0))
1029 (define (show-stats)
1030 (define (% n)
1031 (if (zero? lookups)
1032 100.
1033 (* 100. (/ n lookups))))
1034
1035 (format (current-error-port) "
1036'add-data-to-store' cache:
1037 lookups: ~5@a
1038 hits: ~5@a (~,1f%)
1039 .drv files: ~5@a (~,1f%)
1040 Scheme files: ~5@a (~,1f%)~%"
1041 lookups hits (% hits)
1042 drv (% drv)
1043 scheme (% scheme)))
1044
1045 (register-profiling-hook! "add-data-to-store-cache"
1046 show-stats)
1047 (lambda (cache args)
1048 (let ((result (hash-ref cache args)))
1049 (set! lookups (+ 1 lookups))
1050 (when result
1051 (set! hits (+ 1 hits)))
1052 (match args
1053 ((_ name _)
1054 (cond ((string-suffix? ".drv" name)
1055 (set! drv (+ drv 1)))
1056 ((string-suffix? "-builder" name)
1057 (set! scheme (+ scheme 1)))
1058 ((string-suffix? ".scm" name)
1059 (set! scheme (+ scheme 1))))))
1060 result)))
1061 hash-ref)))
0d268c5d
LC
1062 (lambda* (server name bytes #:optional (references '()))
1063 "Add BYTES under file NAME in the store, and return its store path.
bdcf35a6
LC
1064REFERENCES is the list of store paths referred to by the resulting store
1065path."
0d268c5d 1066 (let* ((args `(,bytes ,name ,references))
de9fbe9c 1067 (cache (store-connection-add-text-to-store-cache server)))
d1f7748a 1068 (or (lookup cache args)
0d268c5d 1069 (let ((path (add-text-to-store server name bytes references)))
bdcf35a6
LC
1070 (hash-set! cache args path)
1071 path))))))
1072
0d268c5d
LC
1073(define* (add-text-to-store store name text #:optional (references '()))
1074 "Add TEXT under file NAME in the store, and return its store path.
1075REFERENCES is the list of store paths referred to by the resulting store
1076path."
1077 (add-data-to-store store name (string->utf8 text) references))
1078
1ec32f4a
LC
1079(define true
1080 ;; Define it once and for all since we use it as a default value for
1081 ;; 'add-to-store' and want to make sure two default values are 'eq?' for the
1082 ;; purposes or memoization.
1083 (lambda (file stat)
1084 #t))
1085
fd060fd3 1086(define add-to-store
a7b6ffee
LC
1087 ;; A memoizing version of `add-to-store'. This is important because
1088 ;; `add-to-store' leads to huge data transfers to the server, and
1089 ;; because it's often called many times with the very same argument.
1ec32f4a
LC
1090 (let ((add-to-store
1091 (lambda* (server basename recursive? hash-algo file-name
1092 #:key (select? true))
1093 ;; We don't use the 'operation' macro so we can pass SELECT? to
1094 ;; 'write-file'.
0ca3d556 1095 (record-operation 'add-to-store)
de9fbe9c 1096 (let ((port (store-connection-socket server)))
1ec32f4a
LC
1097 (write-int (operation-id add-to-store) port)
1098 (write-string basename port)
1099 (write-int 1 port) ;obsolete, must be #t
1100 (write-int (if recursive? 1 0) port)
1101 (write-string hash-algo port)
1102 (write-file file-name port #:select? select?)
38098241 1103 (write-buffered-output server)
1ec32f4a
LC
1104 (let loop ((done? (process-stderr server)))
1105 (or done? (loop (process-stderr server))))
1106 (read-store-path port)))))
1107 (lambda* (server basename recursive? hash-algo file-name
1108 #:key (select? true))
a9ebd9ef 1109 "Add the contents of FILE-NAME under BASENAME to the store. When
69792b28
LC
1110RECURSIVE? is false, FILE-NAME must designate a regular file--not a directory
1111nor a symlink. When RECURSIVE? is true and FILE-NAME designates a directory,
1112the contents of FILE-NAME are added recursively; if FILE-NAME designates a
1113flat file and RECURSIVE? is true, its contents are added, and its permission
1ec32f4a
LC
1114bits are kept. HASH-ALGO must be a string such as \"sha256\".
1115
1116When RECURSIVE? is true, call (SELECT? FILE STAT) for each directory entry,
1117where FILE is the entry's absolute file name and STAT is the result of
1118'lstat'; exclude entries for which SELECT? does not return true."
b4671215
LC
1119 ;; Note: We don't stat FILE-NAME at each call, and thus we assume that
1120 ;; the file remains unchanged for the lifetime of SERVER.
1121 (let* ((args `(,file-name ,basename ,recursive? ,hash-algo ,select?))
de9fbe9c 1122 (cache (store-connection-add-to-store-cache server)))
b4671215 1123 (or (hash-ref cache args)
1ec32f4a
LC
1124 (let ((path (add-to-store server basename recursive?
1125 hash-algo file-name
1126 #:select? select?)))
a7b6ffee
LC
1127 (hash-set! cache args path)
1128 path))))))
1129
7f11efba
LC
1130(define %not-slash
1131 (char-set-complement (char-set #\/)))
1132
1133(define* (add-file-tree-to-store server tree
1134 #:key
1135 (hash-algo "sha256")
1136 (recursive? #t))
1137 "Add the given TREE to the store on SERVER. TREE must be an entry such as:
1138
1139 (\"my-tree\" directory
1140 (\"a\" regular (data \"hello\"))
1141 (\"b\" symlink \"a\")
1142 (\"c\" directory
1143 (\"d\" executable (file \"/bin/sh\"))))
1144
1145This is a generalized version of 'add-to-store'. It allows you to reproduce
1146an arbitrary directory layout in the store without creating a derivation."
1147
1148 ;; Note: The format of TREE was chosen to allow trees to be compared with
1149 ;; 'equal?', which in turn allows us to memoize things.
1150
1151 (define root
1152 ;; TREE is a single entry.
1153 (list tree))
1154
1155 (define basename
1156 (match tree
1157 ((name . _) name)))
1158
1159 (define (lookup file)
1160 (let loop ((components (string-tokenize file %not-slash))
1161 (tree root))
1162 (match components
1163 ((basename)
1164 (assoc basename tree))
1165 ((head . rest)
1166 (loop rest
1167 (match (assoc-ref tree head)
1168 (('directory . entries) entries)))))))
1169
1170 (define (file-type+size file)
1171 (match (lookup file)
1172 ((_ (and type (or 'directory 'symlink)) . _)
1173 (values type 0))
1174 ((_ type ('file file))
1175 (values type (stat:size (stat file))))
1176 ((_ type ('data (? string? data)))
1177 (values type (string-length data)))
1178 ((_ type ('data (? bytevector? data)))
1179 (values type (bytevector-length data)))))
1180
1181 (define (file-port file)
1182 (match (lookup file)
1183 ((_ (or 'regular 'executable) content)
1184 (match content
1185 (('file (? string? file))
1186 (open-file file "r0b"))
1187 (('data (? string? str))
1188 (open-input-string str))
1189 (('data (? bytevector? bv))
1190 (open-bytevector-input-port bv))))))
1191
1192 (define (symlink-target file)
1193 (match (lookup file)
1194 ((_ 'symlink target) target)))
1195
1196 (define (directory-entries directory)
1197 (match (lookup directory)
1198 ((_ 'directory (names . _) ...) names)))
1199
1200 (define cache
de9fbe9c 1201 (store-connection-add-to-store-cache server))
7f11efba
LC
1202
1203 (or (hash-ref cache tree)
1204 (begin
1205 ;; We don't use the 'operation' macro so we can use 'write-file-tree'
1206 ;; instead of 'write-file'.
1207 (record-operation 'add-to-store/tree)
de9fbe9c 1208 (let ((port (store-connection-socket server)))
7f11efba
LC
1209 (write-int (operation-id add-to-store) port)
1210 (write-string basename port)
1211 (write-int 1 port) ;obsolete, must be #t
1212 (write-int (if recursive? 1 0) port)
1213 (write-string hash-algo port)
1214 (write-file-tree basename port
1215 #:file-type+size file-type+size
1216 #:file-port file-port
1217 #:symlink-target symlink-target
1218 #:directory-entries directory-entries)
000bbe02 1219 (write-buffered-output server)
7f11efba
LC
1220 (let loop ((done? (process-stderr server)))
1221 (or done? (loop (process-stderr server))))
1222 (let ((result (read-store-path port)))
1223 (hash-set! cache tree result)
1224 result)))))
1225
041b340d
LC
1226(define current-build-prompt
1227 ;; When true, this is the prompt to abort to when 'build-things' is called.
1228 (make-parameter #f))
1229
1230(define (call-with-build-handler handler thunk)
1231 "Register HANDLER as a \"build handler\" and invoke THUNK."
1232 (define tag
1233 (make-prompt-tag "build handler"))
1234
1235 (parameterize ((current-build-prompt tag))
1236 (call-with-prompt tag
1237 thunk
1238 (lambda (k . args)
1239 ;; Since HANDLER may call K, which in turn may call 'build-things'
1240 ;; again, reinstate a prompt (thus, it's not a tail call.)
1241 (call-with-build-handler handler
1242 (lambda ()
1243 (apply handler k args)))))))
1244
1245(define (invoke-build-handler store things mode)
1246 "Abort to 'current-build-prompt' if it is set."
1247 (or (not (current-build-prompt))
1248 (abort-to-prompt (current-build-prompt) store things mode)))
1249
1250(define-syntax-rule (with-build-handler handler exp ...)
1251 "Register HANDLER as a \"build handler\" and invoke THUNK. When
1252'build-things' is called within the dynamic extent of the call to THUNK,
1253HANDLER is invoked like so:
1254
1255 (HANDLER CONTINUE STORE THINGS MODE)
1256
1257where CONTINUE is the continuation, and the remaining arguments are those that
1258were passed to 'build-things'.
1259
1260Build handlers are useful to announce a build plan with 'show-what-to-build'
1261and to implement dry runs (by not invoking CONTINUE) in a way that gracefully
1262deals with \"dynamic dependencies\" such as grafts---derivations that depend
1263on the build output of a previous derivation."
1264 (call-with-build-handler handler (lambda () exp ...)))
1265
07e70f48
LC
1266(define build-things
1267 (let ((build (operation (build-things (string-list things)
1268 (integer mode))
1269 "Do it!"
2734cbb8
LC
1270 boolean))
1271 (build/old (operation (build-things (string-list things))
1272 "Do it!"
1273 boolean)))
07e70f48
LC
1274 (lambda* (store things #:optional (mode (build-mode normal)))
1275 "Build THINGS, a list of store items which may be either '.drv' files or
abac874b
LC
1276outputs, and return when the worker is done building them. Elements of THINGS
1277that are not derivations can only be substituted and not built locally.
f8a9f99c
LC
1278Alternately, an element of THING can be a derivation/output name pair, in
1279which case the daemon will attempt to substitute just the requested output of
041b340d
LC
1280the derivation. Return #t on success.
1281
1282When a handler is installed with 'with-build-handler', it is called any time
1283'build-things' is called."
1284 (or (not (invoke-build-handler store things mode))
1285 (let ((things (map (match-lambda
1286 ((drv . output) (string-append drv "!" output))
1287 (thing thing))
1288 things)))
1289 (parameterize ((current-store-protocol-version
1290 (store-connection-version store)))
1291 (if (>= (store-connection-minor-version store) 15)
1292 (build store things mode)
1293 (if (= mode (build-mode normal))
1294 (build/old store things)
1295 (raise (condition (&store-protocol-error
1296 (message "unsupported build mode")
1297 (status 1))))))))))))
26bbbb95 1298
d3648e01
LC
1299(define-operation (add-temp-root (store-path path))
1300 "Make PATH a temporary root for the duration of the current session.
1301Return #t."
1302 boolean)
1303
34811f02 1304(define-operation (add-indirect-root (string file-name))
a9d2a105
LC
1305 "Make the symlink FILE-NAME an indirect root for the garbage collector:
1306whatever store item FILE-NAME points to will not be collected. Return #t on
1307success.
1308
1309FILE-NAME can be anywhere on the file system, but it must be an absolute file
1310name--it is the caller's responsibility to ensure that it is an absolute file
1311name."
34811f02
LC
1312 boolean)
1313
a9d2a105
LC
1314(define %gc-roots-directory
1315 ;; The place where garbage collector roots (symlinks) are kept.
1316 (string-append %state-directory "/gcroots"))
1317
1318(define (add-permanent-root target)
1319 "Add a garbage collector root pointing to TARGET, an element of the store,
1320preventing TARGET from even being collected. This can also be used if TARGET
1321does not exist yet.
1322
1323Raise an error if the caller does not have write access to the GC root
1324directory."
1325 (let* ((root (string-append %gc-roots-directory "/" (basename target))))
1326 (catch 'system-error
1327 (lambda ()
1328 (symlink target root))
1329 (lambda args
1330 ;; If ROOT already exists, this is fine; otherwise, re-throw.
1331 (unless (= EEXIST (system-error-errno args))
1332 (apply throw args))))))
1333
1334(define (remove-permanent-root target)
1335 "Remove the permanent garbage collector root pointing to TARGET. Raise an
1336error if there is no such root."
1337 (delete-file (string-append %gc-roots-directory "/" (basename target))))
1338
fae31edc
LC
1339(define references
1340 (operation (query-references (store-path path))
1341 "Return the list of references of PATH."
1342 store-path-list))
1343
f09aea1b
LC
1344(define %reference-cache
1345 ;; Brute-force cache mapping store items to their list of references.
1346 ;; Caching matters because when building a profile in the presence of
1347 ;; grafts, we keep calling 'graft-derivation', which in turn calls
1348 ;; 'references/substitutes' many times with the same arguments. Ideally we
1349 ;; would use a cache associated with the daemon connection instead (XXX).
1350 (make-hash-table 100))
1351
6581ec9a
LC
1352(define (references/substitutes store items)
1353 "Return the list of list of references of ITEMS; the result has the same
1354length as ITEMS. Query substitute information for any item missing from the
f9e8a123 1355store at once. Raise a '&store-protocol-error' exception if reference
6581ec9a 1356information for one of ITEMS is missing."
b2fde480
LC
1357 (let* ((requested items)
1358 (local-refs (map (lambda (item)
f09aea1b 1359 (or (hash-ref %reference-cache item)
f9e8a123 1360 (guard (c ((store-protocol-error? c) #f))
f09aea1b 1361 (references store item))))
6581ec9a
LC
1362 items))
1363 (missing (fold-right (lambda (item local-ref result)
1364 (if local-ref
1365 result
1366 (cons item result)))
1367 '()
1368 items local-refs))
1369
1370 ;; Query all the substitutes at once to minimize the cost of
1371 ;; launching 'guix substitute' and making HTTP requests.
2633bd32
LC
1372 (substs (if (null? missing)
1373 '()
1374 (substitutable-path-info store missing))))
6581ec9a 1375 (when (< (length substs) (length missing))
f9e8a123 1376 (raise (condition (&store-protocol-error
6581ec9a
LC
1377 (message "cannot determine \
1378the list of references")
1379 (status 1)))))
1380
1381 ;; Intersperse SUBSTS and LOCAL-REFS.
dd78e90a
LC
1382 (let loop ((items items)
1383 (local-refs local-refs)
6581ec9a 1384 (result '()))
dd78e90a 1385 (match items
6581ec9a 1386 (()
f09aea1b
LC
1387 (let ((result (reverse result)))
1388 (for-each (cut hash-set! %reference-cache <> <>)
b2fde480 1389 requested result)
f09aea1b 1390 result))
dd78e90a
LC
1391 ((item items ...)
1392 (match local-refs
1393 ((#f tail ...)
1394 (loop items tail
1395 (cons (any (lambda (subst)
1396 (and (string=? (substitutable-path subst) item)
1397 (substitutable-references subst)))
1398 substs)
1399 result)))
1400 ((head tail ...)
1401 (loop items tail
1402 (cons head result)))))))))
6581ec9a 1403
f6fee16e 1404(define* (fold-path store proc seed paths
3f1e6939 1405 #:optional (relatives (cut references store <>)))
f6fee16e 1406 "Call PROC for each of the RELATIVES of PATHS, exactly once, and return the
3f1e6939
LC
1407result formed from the successive calls to PROC, the first of which is passed
1408SEED."
f6fee16e 1409 (let loop ((paths paths)
3f1e6939
LC
1410 (result seed)
1411 (seen vlist-null))
1412 (match paths
1413 ((path rest ...)
1414 (if (vhash-assoc path seen)
1415 (loop rest result seen)
1416 (let ((seen (vhash-cons path #t seen))
1417 (rest (append rest (relatives path)))
1418 (result (proc path result)))
1419 (loop rest result seen))))
1420 (()
1421 result))))
1422
f6fee16e
LC
1423(define (requisites store paths)
1424 "Return the requisites of PATHS, including PATHS---i.e., their closures (all
1425its references, recursively)."
1426 (fold-path store cons '() paths))
3f1e6939 1427
50add477
LC
1428(define (topologically-sorted store paths)
1429 "Return a list containing PATHS and all their references sorted in
1430topological order."
1431 (define (traverse)
1432 ;; Do a simple depth-first traversal of all of PATHS.
1433 (let loop ((paths paths)
1434 (visited vlist-null)
1435 (result '()))
1436 (define (visit n)
1437 (vhash-cons n #t visited))
1438
1439 (define (visited? n)
1440 (vhash-assoc n visited))
1441
1442 (match paths
1443 ((head tail ...)
1444 (if (visited? head)
1445 (loop tail visited result)
1446 (call-with-values
1447 (lambda ()
1448 (loop (references store head)
1449 (visit head)
1450 result))
1451 (lambda (visited result)
1452 (loop tail
1453 visited
1454 (cons head result))))))
1455 (()
1456 (values visited result)))))
1457
1458 (call-with-values traverse
1459 (lambda (_ result)
1460 (reverse result))))
1461
fae31edc
LC
1462(define referrers
1463 (operation (query-referrers (store-path path))
1464 "Return the list of path that refer to PATH."
1465 store-path-list))
1466
1467(define valid-derivers
1468 (operation (query-valid-derivers (store-path path))
1469 "Return the list of valid \"derivers\" of PATH---i.e., all the
1470.drv present in the store that have PATH among their outputs."
1471 store-path-list))
1472
1473(define query-derivation-outputs ; avoid name clash with `derivation-outputs'
1474 (operation (query-derivation-outputs (store-path path))
1475 "Return the list of outputs of PATH, a .drv file."
1476 store-path-list))
1477
0f3d2504
LC
1478(define-operation (has-substitutes? (store-path path))
1479 "Return #t if binary substitutes are available for PATH, and #f otherwise."
1480 boolean)
1481
1482(define substitutable-paths
1483 (operation (query-substitutable-paths (store-path-list paths))
1484 "Return the subset of PATHS that is substitutable."
1485 store-path-list))
1486
1487(define substitutable-path-info
f65cf81a 1488 (operation (query-substitutable-path-infos (store-path-list paths))
0f3d2504
LC
1489 "Return information about the subset of PATHS that is
1490substitutable. For each substitutable path, a `substitutable?' object is
dd78e90a
LC
1491returned; thus, the resulting list can be shorter than PATHS. Furthermore,
1492that there is no guarantee that the order of the resulting list matches the
1493order of PATHS."
0f3d2504
LC
1494 substitutable-path-list))
1495
3961edf2 1496(define %built-in-builders
f9aefa2d
LC
1497 (let ((builders (operation (built-in-builders)
1498 "Return the built-in builders."
1499 string-list)))
1500 (lambda (store)
1501 "Return the names of the supported built-in derivation builders
3961edf2 1502supported by STORE. The result is memoized for STORE."
f9aefa2d
LC
1503 ;; Check whether STORE's version supports this RPC and built-in
1504 ;; derivation builders in general, which appeared in Guix > 0.11.0.
1505 ;; Return the empty list if it doesn't. Note that this RPC does not
1506 ;; exist in 'nix-daemon'.
de9fbe9c
LC
1507 (if (or (> (store-connection-major-version store) #x100)
1508 (and (= (store-connection-major-version store) #x100)
1509 (>= (store-connection-minor-version store) #x60)))
f9aefa2d
LC
1510 (builders store)
1511 '()))))
1512
3961edf2
LC
1513(define (built-in-builders store)
1514 "Return the names of the supported built-in derivation builders
1515supported by STORE."
1516 (force (store-connection-built-in-builders store)))
1517
e3fd0ce6
LC
1518(define-operation (optimize-store)
1519 "Optimize the store by hard-linking identical files (\"deduplication\".)
1520Return #t on success."
1521 ;; Note: the daemon in Guix <= 0.8.2 does not implement this RPC.
1522 boolean)
1523
c63d9403
LC
1524(define verify-store
1525 (let ((verify (operation (verify-store (boolean check-contents?)
1526 (boolean repair?))
1527 "Verify the store."
1528 boolean)))
1529 (lambda* (store #:key check-contents? repair?)
1530 "Verify the integrity of the store and return false if errors remain,
1531and true otherwise. When REPAIR? is true, repair any missing or altered store
1532items by substituting them (this typically requires root privileges because it
1533is not an atomic operation.) When CHECK-CONTENTS? is true, check the contents
1534of store items; this can take a lot of time."
1535 (not (verify store check-contents? repair?)))))
1536
3259877d
LC
1537(define (run-gc server action to-delete min-freed)
1538 "Perform the garbage-collector operation ACTION, one of the
1539`gc-action' values. When ACTION is `delete-specific', the TO-DELETE is
1540the list of store paths to delete. IGNORE-LIVENESS? should always be
1541#f. MIN-FREED is the minimum amount of disk space to be freed, in
1542bytes, before the GC can stop. Return the list of store paths delete,
1543and the number of bytes freed."
de9fbe9c 1544 (let ((s (store-connection-socket server)))
3259877d
LC
1545 (write-int (operation-id collect-garbage) s)
1546 (write-int action s)
1547 (write-store-path-list to-delete s)
1548 (write-arg boolean #f s) ; ignore-liveness?
1549 (write-long-long min-freed s)
1550 (write-int 0 s) ; obsolete
de9fbe9c 1551 (when (>= (store-connection-minor-version server) 5)
3259877d
LC
1552 ;; Obsolete `use-atime' and `max-atime' parameters.
1553 (write-int 0 s)
1554 (write-int 0 s))
1555
1556 ;; Loop until the server is done sending error output.
1557 (let loop ((done? (process-stderr server)))
1558 (or done? (loop (process-stderr server))))
1559
1560 (let ((paths (read-store-path-list s))
1561 (freed (read-long-long s))
1562 (obsolete (read-long-long s)))
000c59b6
LC
1563 (unless (null? paths)
1564 ;; To be on the safe side, completely invalidate both caches.
1565 ;; Otherwise we could end up returning store paths that are no longer
1566 ;; valid.
de9fbe9c
LC
1567 (hash-clear! (store-connection-add-to-store-cache server))
1568 (hash-clear! (store-connection-add-text-to-store-cache server)))
000c59b6 1569
3259877d
LC
1570 (values paths freed))))
1571
1572(define-syntax-rule (%long-long-max)
1573 ;; Maximum unsigned 64-bit integer.
1574 (- (expt 2 64) 1))
1575
1576(define (live-paths server)
1577 "Return the list of live store paths---i.e., store paths still
1578referenced, and thus not subject to being garbage-collected."
1579 (run-gc server (gc-action return-live) '() (%long-long-max)))
1580
1581(define (dead-paths server)
1582 "Return the list of dead store paths---i.e., store paths no longer
1583referenced, and thus subject to being garbage-collected."
1584 (run-gc server (gc-action return-dead) '() (%long-long-max)))
1585
1586(define* (collect-garbage server #:optional (min-freed (%long-long-max)))
1587 "Collect garbage from the store at SERVER. If MIN-FREED is non-zero,
1588then collect at least MIN-FREED bytes. Return the paths that were
1589collected, and the number of bytes freed."
1590 (run-gc server (gc-action delete-dead) '() min-freed))
1591
1592(define* (delete-paths server paths #:optional (min-freed (%long-long-max)))
1593 "Delete PATHS from the store at SERVER, if they are no longer
1594referenced. If MIN-FREED is non-zero, then stop after at least
1595MIN-FREED bytes have been collected. Return the paths that were
1596collected, and the number of bytes freed."
1597 (run-gc server (gc-action delete-specific) paths min-freed))
1598
526382ff
LC
1599(define (import-paths server port)
1600 "Import the set of store paths read from PORT into SERVER's store. An error
1601is raised if the set of paths read from PORT is not signed (as per
1602'export-path #:sign? #t'.) Return the list of store paths imported."
de9fbe9c 1603 (let ((s (store-connection-socket server)))
526382ff
LC
1604 (write-int (operation-id import-paths) s)
1605 (let loop ((done? (process-stderr server port)))
1606 (or done? (loop (process-stderr server port))))
1607 (read-store-path-list s)))
1608
1609(define* (export-path server path port #:key (sign? #t))
1610 "Export PATH to PORT. When SIGN? is true, sign it."
de9fbe9c 1611 (let ((s (store-connection-socket server)))
526382ff
LC
1612 (write-int (operation-id export-path) s)
1613 (write-store-path path s)
1614 (write-arg boolean sign? s)
1615 (let loop ((done? (process-stderr server port)))
1616 (or done? (loop (process-stderr server port))))
1617 (= 1 (read-int s))))
1618
5b3d863f 1619(define* (export-paths server paths port #:key (sign? #t) recursive?)
99fbddf9 1620 "Export the store paths listed in PATHS to PORT, in topological order,
5b3d863f
LC
1621signing them if SIGN? is true. When RECURSIVE? is true, export the closure of
1622PATHS---i.e., PATHS and all their dependencies."
cafb92d8 1623 (define ordered
5b3d863f
LC
1624 (let ((sorted (topologically-sorted server paths)))
1625 ;; When RECURSIVE? is #f, filter out the references of PATHS.
1626 (if recursive?
1627 sorted
1628 (filter (cut member <> paths) sorted))))
cafb92d8 1629
1d506993
LC
1630 (let loop ((paths ordered))
1631 (match paths
1632 (()
1633 (write-int 0 port))
1634 ((head tail ...)
1635 (write-int 1 port)
1636 (and (export-path server head port #:sign? sign?)
1637 (loop tail))))))
526382ff 1638
16748d80
LC
1639(define-operation (query-failed-paths)
1640 "Return the list of store items for which a build failure is cached.
1641
1642The result is always the empty list unless the daemon was started with
1643'--cache-failures'."
1644 store-path-list)
1645
1646(define-operation (clear-failed-paths (store-path-list items))
1647 "Remove ITEMS from the list of cached build failures.
1648
1649This makes sense only when the daemon was started with '--cache-failures'."
1650 boolean)
1651
26bbbb95 1652\f
e87f0591
LC
1653;;;
1654;;; Store monad.
1655;;;
1656
4e190c28
LC
1657(define-syntax-rule (define-alias new old)
1658 (define-syntax new (identifier-syntax old)))
e87f0591 1659
4e190c28
LC
1660;; The store monad allows us to (1) build sequences of operations in the
1661;; store, and (2) make the store an implicit part of the execution context,
1662;; rather than a parameter of every single function.
1663(define-alias %store-monad %state-monad)
1664(define-alias store-return state-return)
1665(define-alias store-bind state-bind)
e87f0591 1666
dcb95c1f
LC
1667;; Instantiate templates for %STORE-MONAD since it's syntactically different
1668;; from %STATE-MONAD.
1669(template-directory instantiations %store-monad)
1670
c57e417e
LC
1671(define* (cache-object-mapping object keys result
1672 #:key (vhash-cons vhash-consq))
c6080c32
LC
1673 "Augment the store's object cache with a mapping from OBJECT/KEYS to RESULT.
1674KEYS is a list of additional keys to match against, for instance a (SYSTEM
c57e417e 1675TARGET) tuple. Use VHASH-CONS to insert OBJECT into the cache.
c6080c32
LC
1676
1677OBJECT is typically a high-level object such as a <package> or an <origin>,
1678and RESULT is typically its derivation."
1679 (lambda (store)
1680 (values result
de9fbe9c 1681 (store-connection
c6080c32 1682 (inherit store)
c57e417e
LC
1683 (object-cache (vhash-cons object (cons result keys)
1684 (store-connection-object-cache store)))))))
c6080c32 1685
73b0ebdd
LC
1686(define record-cache-lookup!
1687 (if (profiled? "object-cache")
1688 (let ((fresh 0)
1689 (lookups 0)
1690 (hits 0))
1691 (register-profiling-hook!
1692 "object-cache"
1693 (lambda ()
1694 (format (current-error-port) "Store object cache:
1695 fresh caches: ~5@a
1696 lookups: ~5@a
1697 hits: ~5@a (~,1f%)~%"
1698 fresh lookups hits
1699 (if (zero? lookups)
1700 100.
1701 (* 100. (/ hits lookups))))))
1702
1703 (lambda (hit? cache)
1704 (set! fresh
1705 (if (eq? cache vlist-null)
1706 (+ 1 fresh)
1707 fresh))
1708 (set! lookups (+ 1 lookups))
1709 (set! hits (if hit? (+ hits 1) hits))))
1710 (lambda (x y)
1711 #t)))
1712
c57e417e
LC
1713(define* (lookup-cached-object object #:optional (keys '())
1714 #:key (vhash-fold* vhash-foldq*))
c6080c32 1715 "Return the cached object in the store connection corresponding to OBJECT
c57e417e
LC
1716and KEYS; use VHASH-FOLD* to look for OBJECT in the cache. KEYS is a list of
1717additional keys to match against, and which are compared with 'equal?'.
1718Return #f on failure and the cached result otherwise."
c6080c32 1719 (lambda (store)
de9fbe9c 1720 (let* ((cache (store-connection-object-cache store))
73b0ebdd
LC
1721
1722 ;; Escape as soon as we find the result. This avoids traversing
1723 ;; the whole vlist chain and significantly reduces the number of
1724 ;; 'hashq' calls.
1725 (value (let/ec return
c57e417e
LC
1726 (vhash-fold* (lambda (item result)
1727 (match item
1728 ((value . keys*)
1729 (if (equal? keys keys*)
1730 (return value)
1731 result))))
1732 #f object
1733 cache))))
73b0ebdd
LC
1734 (record-cache-lookup! value cache)
1735 (values value store))))
c6080c32 1736
c57e417e
LC
1737(define* (%mcached mthunk object #:optional (keys '())
1738 #:key
1739 (vhash-cons vhash-consq)
1740 (vhash-fold* vhash-foldq*))
c6080c32 1741 "Bind the monadic value returned by MTHUNK, which supposedly corresponds to
c57e417e
LC
1742OBJECT/KEYS, or return its cached value. Use VHASH-CONS to insert OBJECT into
1743the cache, and VHASH-FOLD* to look it up."
1744 (mlet %store-monad ((cached (lookup-cached-object object keys
1745 #:vhash-fold* vhash-fold*)))
c6080c32
LC
1746 (if cached
1747 (return cached)
1748 (>>= (mthunk)
1749 (lambda (result)
c57e417e
LC
1750 (cache-object-mapping object keys result
1751 #:vhash-cons vhash-cons))))))
c6080c32 1752
c57e417e
LC
1753(define-syntax mcached
1754 (syntax-rules (eq? equal?)
1755 "Run MVALUE, which corresponds to OBJECT/KEYS, and cache it; or return the
c6080c32
LC
1756value associated with OBJECT/KEYS in the store's object cache if there is
1757one."
c57e417e
LC
1758 ((_ eq? mvalue object keys ...)
1759 (%mcached (lambda () mvalue)
1760 object (list keys ...)
1761 #:vhash-cons vhash-consq
1762 #:vhash-fold* vhash-foldq*))
1763 ((_ equal? mvalue object keys ...)
1764 (%mcached (lambda () mvalue)
1765 object (list keys ...)
1766 #:vhash-cons vhash-cons
1767 #:vhash-fold* vhash-fold*))
1768 ((_ mvalue object keys ...)
1769 (mcached eq? mvalue object keys ...))))
c6080c32 1770
5808dcc2
LC
1771(define (preserve-documentation original proc)
1772 "Return PROC with documentation taken from ORIGINAL."
1773 (set-object-property! proc 'documentation
1774 (procedure-property original 'documentation))
1775 proc)
1776
e87f0591
LC
1777(define (store-lift proc)
1778 "Lift PROC, a procedure whose first argument is a connection to the store,
1779in the store monad."
5808dcc2
LC
1780 (preserve-documentation proc
1781 (lambda args
1782 (lambda (store)
1783 (values (apply proc store args) store)))))
e87f0591 1784
023d9892
LC
1785(define (store-lower proc)
1786 "Lower PROC, a monadic procedure in %STORE-MONAD, to a \"normal\" procedure
1787taking the store as its first argument."
5808dcc2
LC
1788 (preserve-documentation proc
1789 (lambda (store . args)
1790 (run-with-store store (apply proc args)))))
023d9892 1791
e87f0591
LC
1792;;
1793;; Store monad operators.
1794;;
1795
f3a42251
JN
1796(define* (binary-file name
1797 data ;bytevector
1798 #:optional (references '()))
1799 "Return as a monadic value the absolute file name in the store of the file
1800containing DATA, a bytevector. REFERENCES is a list of store items that the
1801resulting text file refers to; it defaults to the empty list."
1802 (lambda (store)
1803 (values (add-data-to-store store name data references)
1804 store)))
1805
1806(define* (text-file name
1807 text ;string
ad372953 1808 #:optional (references '()))
e87f0591 1809 "Return as a monadic value the absolute file name in the store of the file
ad372953
LC
1810containing TEXT, a string. REFERENCES is a list of store items that the
1811resulting text file refers to; it defaults to the empty list."
e87f0591 1812 (lambda (store)
ad372953 1813 (values (add-text-to-store store name text references)
4e190c28 1814 store)))
e87f0591
LC
1815
1816(define* (interned-file file #:optional name
1ec32f4a 1817 #:key (recursive? #t) (select? true))
e87f0591
LC
1818 "Return the name of FILE once interned in the store. Use NAME as its store
1819name, or the basename of FILE if NAME is omitted.
1820
1821When RECURSIVE? is true, the contents of FILE are added recursively; if FILE
1822designates a flat file and RECURSIVE? is true, its contents are added, and its
1ec32f4a
LC
1823permission bits are kept.
1824
1825When RECURSIVE? is true, call (SELECT? FILE STAT) for each directory entry,
1826where FILE is the entry's absolute file name and STAT is the result of
1827'lstat'; exclude entries for which SELECT? does not return true."
e87f0591 1828 (lambda (store)
4e190c28 1829 (values (add-to-store store (or name (basename file))
1ec32f4a
LC
1830 recursive? "sha256" file
1831 #:select? select?)
4e190c28 1832 store)))
e87f0591 1833
7f11efba
LC
1834(define interned-file-tree
1835 (store-lift add-file-tree-to-store))
1836
abac874b
LC
1837(define build
1838 ;; Monadic variant of 'build-things'.
1839 (store-lift build-things))
1840
4f740b67
AK
1841(define set-build-options*
1842 (store-lift set-build-options))
1843
e74f64b9
LC
1844(define references*
1845 (store-lift references))
1846
0744a9f0
LC
1847(define (query-path-info* item)
1848 "Monadic version of 'query-path-info' that returns #f when ITEM is not in
1849the store."
1850 (lambda (store)
f9e8a123 1851 (guard (c ((store-protocol-error? c)
0744a9f0
LC
1852 ;; ITEM is not in the store; return #f.
1853 (values #f store)))
1854 (values (query-path-info store item) store))))
1855
98a7b528
LC
1856(define-inlinable (current-system)
1857 ;; Consult the %CURRENT-SYSTEM fluid at bind time. This is equivalent to
1858 ;; (lift0 %current-system %store-monad), but inlinable, thus avoiding
1859 ;; closure allocation in some cases.
1860 (lambda (state)
1861 (values (%current-system) state)))
1862
1863(define-inlinable (set-current-system system)
1864 ;; Set the %CURRENT-SYSTEM fluid at bind time.
1865 (lambda (state)
1866 (values (%current-system system) state)))
1867
e51de343
MO
1868(define-inlinable (current-target-system)
1869 ;; Consult the %CURRENT-TARGET-SYSTEM fluid at bind time.
1870 (lambda (state)
1871 (values (%current-target-system) state)))
1872
5d52d106
MO
1873(define-inlinable (set-current-target target)
1874 ;; Set the %CURRENT-TARGET-SYSTEM fluid at bind time.
1875 (lambda (state)
1876 (values (%current-target-system target) state)))
1877
e87f0591
LC
1878(define %guile-for-build
1879 ;; The derivation of the Guile to be used within the build environment,
1880 ;; when using 'gexp->derivation' and co.
1881 (make-parameter #f))
1882
dd0ee954
LC
1883(define set-store-connection-object-cache!
1884 (record-modifier <store-connection> 'object-cache))
1885
e87f0591
LC
1886(define* (run-with-store store mval
1887 #:key
1888 (guile-for-build (%guile-for-build))
45bba475
LC
1889 (system (%current-system))
1890 (target #f))
e87f0591 1891 "Run MVAL, a monadic value in the store monad, in STORE, an open store
3698f524 1892connection, and return the result."
a8afb9ae
LC
1893 ;; Initialize the dynamic bindings here to avoid bad surprises. The
1894 ;; difficulty lies in the fact that dynamic bindings are resolved at
1895 ;; bind-time and not at call time, which can be disconcerting.
e87f0591 1896 (parameterize ((%guile-for-build guile-for-build)
a8afb9ae 1897 (%current-system system)
45bba475 1898 (%current-target-system target))
3698f524
LC
1899 (call-with-values (lambda ()
1900 (run-with-state mval store))
dd0ee954 1901 (lambda (result new-store)
728a4ab1
LC
1902 (when (and store new-store)
1903 ;; Copy the object cache from NEW-STORE so we don't fully discard
1904 ;; the state.
1905 (let ((cache (store-connection-object-cache new-store)))
1906 (set-store-connection-object-cache! store cache)))
1907 result))))
e87f0591
LC
1908
1909\f
26bbbb95
LC
1910;;;
1911;;; Store paths.
1912;;;
1913
1914(define %store-prefix
1915 ;; Absolute path to the Nix store.
1d6816f9 1916 (make-parameter %store-directory))
26bbbb95 1917
cd041b26
LC
1918(define (compressed-hash bv size) ; `compressHash'
1919 "Given the hash stored in BV, return a compressed version thereof that fits
1920in SIZE bytes."
1921 (define new (make-bytevector size 0))
1922 (define old-size (bytevector-length bv))
1923 (let loop ((i 0))
1924 (if (= i old-size)
1925 new
1926 (let* ((j (modulo i size))
1927 (o (bytevector-u8-ref new j)))
1928 (bytevector-u8-set! new j
1929 (logxor o (bytevector-u8-ref bv i)))
1930 (loop (+ 1 i))))))
1931
1932(define (store-path type hash name) ; makeStorePath
1933 "Return the store path for NAME/HASH/TYPE."
1934 (let* ((s (string-append type ":sha256:"
1935 (bytevector->base16-string hash) ":"
1936 (%store-prefix) ":" name))
1937 (h (sha256 (string->utf8 s)))
1938 (c (compressed-hash h 20)))
1939 (string-append (%store-prefix) "/"
1940 (bytevector->nix-base32-string c) "-"
1941 name)))
1942
1943(define (output-path output hash name) ; makeOutputPath
1944 "Return an output path for OUTPUT (the name of the output as a string) of
1945the derivation called NAME with hash HASH."
1946 (store-path (string-append "output:" output) hash
1947 (if (string=? output "out")
1948 name
1949 (string-append name "-" output))))
1950
1951(define* (fixed-output-path name hash
1952 #:key
1953 (output "out")
1954 (hash-algo 'sha256)
1955 (recursive? #t))
1956 "Return an output path for the fixed output OUTPUT defined by HASH of type
1957HASH-ALGO, of the derivation NAME. RECURSIVE? has the same meaning as for
1958'add-to-store'."
1959 (if (and recursive? (eq? hash-algo 'sha256))
1960 (store-path "source" hash name)
1961 (let ((tag (string-append "fixed:" output ":"
1962 (if recursive? "r:" "")
1963 (symbol->string hash-algo) ":"
1964 (bytevector->base16-string hash) ":")))
1965 (store-path (string-append "output:" output)
1966 (sha256 (string->utf8 tag))
1967 name))))
1968
f39bd08a
LC
1969(define (store-path? path)
1970 "Return #t if PATH is a store path."
1971 ;; This is a lightweight check, compared to using a regexp, but this has to
1972 ;; be fast as it's called often in `derivation', for instance.
1973 ;; `isStorePath' in Nix does something similar.
1974 (string-prefix? (%store-prefix) path))
26bbbb95 1975
9336e5b5
LC
1976(define (direct-store-path? path)
1977 "Return #t if PATH is a store path, and not a sub-directory of a store path.
1978This predicate is sometimes needed because files *under* a store path are not
1979valid inputs."
1980 (and (store-path? path)
eee21271 1981 (not (string=? path (%store-prefix)))
9336e5b5
LC
1982 (let ((len (+ 1 (string-length (%store-prefix)))))
1983 (not (string-index (substring path len) #\/)))))
1984
cdb5b075
CS
1985(define (direct-store-path path)
1986 "Return the direct store path part of PATH, stripping components after
1987'/gnu/store/xxxx-foo'."
1988 (let ((prefix-length (+ (string-length (%store-prefix)) 35)))
1989 (if (> (string-length path) prefix-length)
1990 (let ((slash (string-index path #\/ prefix-length)))
1991 (if slash (string-take path slash) path))
1992 path)))
1993
26bbbb95
LC
1994(define (derivation-path? path)
1995 "Return #t if PATH is a derivation path."
1996 (and (store-path? path) (string-suffix? ".drv" path)))
e3d74106 1997
771c5e15
FP
1998(define (store-path-base path)
1999 "Return the base path of a path in the store."
2000 (and (string-prefix? (%store-prefix) path)
2001 (let ((base (string-drop path (+ 1 (string-length (%store-prefix))))))
2002 (and (> (string-length base) 33)
2003 (not (string-index base #\/))
2004 base))))
5c0f1845 2005
e3d74106
LC
2006(define (store-path-package-name path)
2007 "Return the package name part of PATH, a file name in the store."
771c5e15
FP
2008 (let ((base (store-path-base path)))
2009 (string-drop base (+ 32 1)))) ;32 hash part + 1 hyphen
2c6ab6cc
LC
2010
2011(define (store-path-hash-part path)
2012 "Return the hash part of PATH as a base32 string, or #f if PATH is not a
2013syntactically valid store path."
771c5e15
FP
2014 (let* ((base (store-path-base path))
2015 (hash (string-take base 32)))
2016 (and (string-every %nix-base32-charset hash)
2017 hash)))
eddd4077 2018
fb94d82b
LC
2019(define (derivation-log-file drv)
2020 "Return the build log file for DRV, a derivation file name, or #f if it
2021could not be found."
2022 (let* ((base (basename drv))
7c4700e9
LC
2023 (log (string-append (or (getenv "GUIX_LOG_DIRECTORY")
2024 (string-append %localstatedir "/log/guix"))
2025 "/drvs/"
fb94d82b
LC
2026 (string-take base 2) "/"
2027 (string-drop base 2)))
2028 (log.gz (string-append log ".gz"))
2029 (log.bz2 (string-append log ".bz2")))
2030 (cond ((file-exists? log.gz) log.gz)
2031 ((file-exists? log.bz2) log.bz2)
2032 ((file-exists? log) log)
2033 (else #f))))
2034
eddd4077
LC
2035(define (log-file store file)
2036 "Return the build log file for FILE, or #f if none could be found. FILE
2037must be an absolute store file name, or a derivation file name."
eddd4077 2038 (cond ((derivation-path? file)
fb94d82b 2039 (derivation-log-file file))
eddd4077
LC
2040 (else
2041 (match (valid-derivers store file)
2042 ((derivers ...)
2043 ;; Return the first that works.
2044 (any (cut log-file store <>) derivers))
2045 (_ #f)))))
3b5cd17a
LC
2046
2047;;; Local Variables:
2048;;; eval: (put 'system-error-to-connection-error 'scheme-indent-function 1)
2049;;; End: