repl: Add "-q".
[jackhill/guix/guix.git] / guix / scripts / perform-download.scm
CommitLineData
94d92c77 1;;; GNU Guix --- Functional package management for GNU
240a9c69 2;;; Copyright © 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
94d92c77
LC
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (guix scripts perform-download)
20 #:use-module (guix ui)
21 #:use-module (guix derivations)
9b5364a3 22 #:use-module ((guix store) #:select (derivation-path? store-path?))
94d92c77
LC
23 #:use-module (guix build download)
24 #:use-module (ice-9 match)
25 #:export (guix-perform-download))
26
27;; This program is a helper for the daemon's 'download' built-in builder.
28
29(define-syntax derivation-let
30 (syntax-rules ()
31 ((_ drv ((id name) rest ...) body ...)
32 (let ((id (assoc-ref (derivation-builder-environment-vars drv)
33 name)))
34 (derivation-let drv (rest ...) body ...)))
35 ((_ drv () body ...)
36 (begin body ...))))
37
38(define %user-module
39 ;; Module in which content-address mirror procedures are evaluated.
40 (let ((module (make-fresh-user-module)))
41 (module-use! module (resolve-interface '(guix base32)))
42 module))
43
240a9c69
LC
44(define* (perform-download drv #:optional output
45 #:key print-build-trace?)
9b5364a3
LC
46 "Perform the download described by DRV, a fixed-output derivation, to
47OUTPUT.
48
26ab00a0
LC
49Note: Unless OUTPUT is #f, we don't read the value of 'out' in DRV since the
50actual output is different from that when we're doing a 'bmCheck' or
51'bmRepair' build."
94d92c77 52 (derivation-let drv ((url "url")
26ab00a0 53 (output* "out")
94d92c77
LC
54 (executable "executable")
55 (mirrors "mirrors")
56 (content-addressed-mirrors "content-addressed-mirrors"))
57 (unless url
69daee23 58 (leave (G_ "~a: missing URL~%") (derivation-file-name drv)))
94d92c77 59
26ab00a0
LC
60 (let* ((output (or output output*))
61 (url (call-with-input-string url read))
94d92c77
LC
62 (drv-output (assoc-ref (derivation-outputs drv) "out"))
63 (algo (derivation-output-hash-algo drv-output))
64 (hash (derivation-output-hash drv-output)))
65 (unless (and algo hash)
69daee23 66 (leave (G_ "~a is not a fixed-output derivation~%")
94d92c77
LC
67 (derivation-file-name drv)))
68
69 ;; We're invoked by the daemon, which gives us write access to OUTPUT.
70 (when (url-fetch url output
240a9c69 71 #:print-build-trace? print-build-trace?
94d92c77
LC
72 #:mirrors (if mirrors
73 (call-with-input-file mirrors read)
74 '())
75 #:content-addressed-mirrors
76 (if content-addressed-mirrors
77 (call-with-input-file content-addressed-mirrors
78 (lambda (port)
79 (eval (read port) %user-module)))
80 '())
81 #:hashes `((,algo . ,hash))
82
83 ;; Since DRV's output hash is known, X.509 certificate
84 ;; validation is pointless.
85 #:verify-certificate? #f)
86 (when (and executable (string=? executable "1"))
87 (chmod output #o755))))))
88
89(define (assert-low-privileges)
90 (when (zero? (getuid))
69daee23 91 (leave (G_ "refusing to run with elevated privileges (UID ~a)~%")
94d92c77
LC
92 (getuid))))
93
94(define (guix-perform-download . args)
95 "Perform the download described by the given fixed-output derivation.
96
97This is an \"out-of-band\" download in that this code is executed directly by
98the daemon and not explicitly described as an input of the derivation. This
99allows us to sidestep bootstrapping problems, such downloading the source code
100of GnuTLS over HTTPS, before we have built GnuTLS. See
101<http://bugs.gnu.org/22774>."
26ab00a0 102
240a9c69
LC
103 (define print-build-trace?
104 (match (getenv "_NIX_OPTIONS")
105 (#f #f)
106 (str (string-contains str "print-extended-build-trace=1"))))
107
26ab00a0
LC
108 ;; This program must be invoked by guix-daemon under an unprivileged UID to
109 ;; prevent things downloading from 'file:///etc/shadow' or arbitrary code
110 ;; execution via the content-addressed mirror procedures. (That means we
111 ;; exclude users who did not pass '--build-users-group'.)
94d92c77
LC
112 (with-error-handling
113 (match args
9b5364a3 114 (((? derivation-path? drv) (? store-path? output))
94d92c77 115 (assert-low-privileges)
015f17e8 116 (perform-download (read-derivation-from-file drv)
240a9c69
LC
117 output
118 #:print-build-trace? print-build-trace?))
26ab00a0
LC
119 (((? derivation-path? drv)) ;backward compatibility
120 (assert-low-privileges)
240a9c69
LC
121 (perform-download (read-derivation-from-file drv)
122 #:print-build-trace? print-build-trace?))
94d92c77
LC
123 (("--version")
124 (show-version-and-exit))
125 (x
9b5364a3 126 (leave
69daee23 127 (G_ "fixed-output derivation and output file name expected~%"))))))
94d92c77
LC
128
129;; Local Variables:
130;; eval: (put 'derivation-let 'scheme-indent-function 2)
131;; End:
132
133;; perform-download.scm ends here