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