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