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