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