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