pull: Create profile after the store connection has been opened.
[jackhill/guix/guix.git] / guix / scripts / perform-download.scm
... / ...
CommitLineData
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
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)
22 #:use-module ((guix store) #:select (derivation-path? store-path?))
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
44(define* (perform-download drv #:optional output
45 #:key print-build-trace?)
46 "Perform the download described by DRV, a fixed-output derivation, to
47OUTPUT.
48
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."
52 (derivation-let drv ((url "url")
53 (output* "out")
54 (executable "executable")
55 (mirrors "mirrors")
56 (content-addressed-mirrors "content-addressed-mirrors"))
57 (unless url
58 (leave (G_ "~a: missing URL~%") (derivation-file-name drv)))
59
60 (let* ((output (or output output*))
61 (url (call-with-input-string url read))
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)
66 (leave (G_ "~a is not a fixed-output derivation~%")
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
71 #:print-build-trace? print-build-trace?
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))
91 (leave (G_ "refusing to run with elevated privileges (UID ~a)~%")
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>."
102
103 (define print-build-trace?
104 (match (getenv "_NIX_OPTIONS")
105 (#f #f)
106 (str (string-contains str "print-extended-build-trace=1"))))
107
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'.)
112 (with-error-handling
113 (match args
114 (((? derivation-path? drv) (? store-path? output))
115 (assert-low-privileges)
116 (perform-download (read-derivation-from-file drv)
117 output
118 #:print-build-trace? print-build-trace?))
119 (((? derivation-path? drv)) ;backward compatibility
120 (assert-low-privileges)
121 (perform-download (read-derivation-from-file drv)
122 #:print-build-trace? print-build-trace?))
123 (("--version")
124 (show-version-and-exit))
125 (x
126 (leave
127 (G_ "fixed-output derivation and output file name expected~%"))))))
128
129;; Local Variables:
130;; eval: (put 'derivation-let 'scheme-indent-function 2)
131;; End:
132
133;; perform-download.scm ends here