installer: Ensure 'packages' field is a superset of '%base-packages'.
[guix.git] / guix / download.scm
blob11984cf671f81ddc9d7d26e19c458cb7760cdadb
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2013, 2014, 2015 Andreas Enge <andreas@enge.fr>
4 ;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
5 ;;; Copyright © 2016 Alex Griffin <a@ajgrf.com>
6 ;;; Copyright © 2016 David Craven <david@craven.ch>
7 ;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
8 ;;; Copyright © 2019 Guy Fleury Iteriteka <hoonandon@gmail.com>
9 ;;;
10 ;;; This file is part of GNU Guix.
11 ;;;
12 ;;; GNU Guix is free software; you can redistribute it and/or modify it
13 ;;; under the terms of the GNU General Public License as published by
14 ;;; the Free Software Foundation; either version 3 of the License, or (at
15 ;;; your option) any later version.
16 ;;;
17 ;;; GNU Guix is distributed in the hope that it will be useful, but
18 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;;; GNU General Public License for more details.
21 ;;;
22 ;;; You should have received a copy of the GNU General Public License
23 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
25 (define-module (guix download)
26   #:use-module (ice-9 match)
27   #:use-module (guix derivations)
28   #:use-module (guix packages)
29   #:use-module (guix store)
30   #:use-module ((guix build download) #:prefix build:)
31   #:use-module (guix monads)
32   #:use-module (guix gexp)
33   #:use-module (guix utils)
34   #:use-module (web uri)
35   #:use-module (srfi srfi-1)
36   #:use-module (srfi srfi-26)
37   #:export (%mirrors
38             url-fetch
39             url-fetch/tarbomb
40             url-fetch/zipbomb
41             download-to-store))
43 ;;; Commentary:
44 ;;;
45 ;;; Produce fixed-output derivations with data fetched over HTTP or FTP.
46 ;;;
47 ;;; Code:
49 (define %mirrors
50   ;; Mirror lists used when `mirror://' URLs are passed.
51   (let* ((gnu-mirrors
52           '(;; This one redirects to a (supposedly) nearby and (supposedly)
53             ;; up-to-date mirror.
54             "https://ftpmirror.gnu.org/gnu/"
56             "ftp://ftp.cs.tu-berlin.de/pub/gnu/"
57             "ftp://ftp.funet.fi/pub/mirrors/ftp.gnu.org/gnu/"
59             ;; This one is the master repository, and thus it's always
60             ;; up-to-date.
61             "http://ftp.gnu.org/pub/gnu/")))
62     `((gnu ,@gnu-mirrors)
63       (gcc
64        "ftp://ftp.nluug.nl/mirror/languages/gcc/"
65        "ftp://ftp.fu-berlin.de/unix/languages/gcc/"
66        "ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/"
67        "ftp://gcc.gnu.org/pub/gcc/"
68        ,@(map (cut string-append <> "/gcc") gnu-mirrors))
69       (gnupg
70        "http://artfiles.org/gnupg.org"
71        "http://www.crysys.hu/"
72        "https://gnupg.org/ftp/gcrypt/"
73        "ftp://mirrors.dotsrc.org/gcrypt/"
74        "ftp://mirror.cict.fr/gnupg/"
75        "ftp://ftp.franken.de/pub/crypt/mirror/ftp.gnupg.org/gcrypt/"
76        "ftp://ftp.freenet.de/pub/ftp.gnupg.org/gcrypt/"
77        "ftp://ftp.hi.is/pub/mirrors/gnupg/"
78        "ftp://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/"
79        "ftp://ftp.bit.nl/mirror/gnupg/"
80        "ftp://ftp.surfnet.nl/pub/security/gnupg/"
81        "ftp://ftp.iasi.roedu.net/pub/mirrors/ftp.gnupg.org/"
82        "ftp://ftp.sunet.se/pub/security/gnupg/"
83        "ftp://mirror.switch.ch/mirror/gnupg/"
84        "ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/"
85        "ftp://ftp.mirrorservice.org/sites/ftp.gnupg.org/gcrypt/"
86        "ftp://ftp.ring.gr.jp/pub/net/gnupg/"
87        "ftp://ftp.gnupg.org/gcrypt/")
88       (gnome
89        "http://ftp.belnet.be/ftp.gnome.org/"
90        "http://ftp.linux.org.uk/mirrors/ftp.gnome.org/"
91        "http://ftp.gnome.org/pub/GNOME/"
92        "https://download.gnome.org/"
93        "http://mirror.yandex.ru/mirrors/ftp.gnome.org/")
94       (hackage
95        "http://hackage.haskell.org/")
96       (savannah
97        "http://download.savannah.gnu.org/releases/"
98        "http://ftp.cc.uoc.gr/mirrors/nongnu.org/"
99        "http://ftp.twaren.net/Unix/NonGNU/"
100        "http://mirror.csclub.uwaterloo.ca/nongnu/"
101        "http://nongnu.askapache.com/"
102        "http://savannah.c3sl.ufpr.br/"
103        "http://download.savannah.gnu.org/releases-noredirect/"
104        "http://download-mirror.savannah.gnu.org/releases/"
105        "ftp://ftp.twaren.net/Unix/NonGNU/"
106        "ftp://mirror.csclub.uwaterloo.ca/nongnu/"
107        "ftp://mirror.publicns.net/pub/nongnu/"
108        "ftp://savannah.c3sl.ufpr.br/")
109       (sourceforge ; https://sourceforge.net/p/forge/documentation/Mirrors/
110        "http://downloads.sourceforge.net/project/"
111        "http://ufpr.dl.sourceforge.net/project/"
112        "http://heanet.dl.sourceforge.net/project/"
113        "http://freefr.dl.sourceforge.net/project/"
114        "http://internode.dl.sourceforge.net/project/"
115        "http://jaist.dl.sourceforge.net/project/"
116        "http://kent.dl.sourceforge.net/project/"
117        "http://liquidtelecom.dl.sourceforge.net/project/"
118        ;; "http://nbtelecom.dl.sourceforge.net/project/"  ;never returns 404s
119        "http://nchc.dl.sourceforge.net/project/"
120        "http://ncu.dl.sourceforge.net/project/"
121        "http://netcologne.dl.sourceforge.net/project/"
122        "http://netix.dl.sourceforge.net/project/"
123        "http://pilotfiber.dl.sourceforge.net/project/"
124        "http://superb-sea2.dl.sourceforge.net/project/"
125        "http://tenet.dl.sourceforge.net/project/"
126        "http://vorboss.dl.sourceforge.net/project/"
127        "http://netassist.dl.sourceforge.net/project/")
128       (netfilter.org ; https://www.netfilter.org/mirrors.html
129        "http://ftp.netfilter.org/pub/"
130        "ftp://ftp.es.netfilter.org/mirrors/netfilter/"
131        "ftp://ftp.hu.netfilter.org/"
132        "ftp://www.lt.netfilter.org/pub/")
133       (kernel.org
134        "http://ramses.wh2.tu-dresden.de/pub/mirrors/kernel.org/"
135        "http://linux-kernel.uio.no/pub/"
136        "http://kernel.osuosl.org/pub/"
137        "http://ftp.be.debian.org/pub/"
138        "http://mirror.linux.org.au/"
139        "ftp://ftp.funet.fi/pub/mirrors/ftp.kernel.org/pub/")
140       (apache             ; from http://www.apache.org/mirrors/dist.html
141        "http://www.eu.apache.org/dist/"
142        "http://www.us.apache.org/dist/"
143        "http://apache.belnet.be/"
144        "http://mirrors.ircam.fr/pub/apache/"
145        "http://apache-mirror.rbc.ru/pub/apache/"
147        ;; As a last resort, try the archive.
148        "http://archive.apache.org/dist/")
149       (xorg               ; from http://www.x.org/wiki/Releases/Download
150        "http://www.x.org/releases/" ; main mirrors
151        "http://mirror.csclub.uwaterloo.ca/x.org/" ; North America
152        "http://xorg.mirrors.pair.com/"
153        "http://mirror.us.leaseweb.net/xorg/"
154        "ftp://mirror.csclub.uwaterloo.ca/x.org/"
155        "ftp://xorg.mirrors.pair.com/"
156        "ftp://artfiles.org/x.org/" ; Europe
157        "ftp://ftp.chg.ru/pub/X11/x.org/"
158        "ftp://ftp.fu-berlin.de/unix/X11/FTP.X.ORG/"
159        "ftp://ftp.gwdg.de/pub/x11/x.org/"
160        "ftp://ftp.mirrorservice.org/sites/ftp.x.org/"
161        "ftp://ftp.ntua.gr/pub/X11/"
162        "ftp://ftp.piotrkosoft.net/pub/mirrors/ftp.x.org/"
163        "ftp://ftp.portal-to-web.de/pub/mirrors/x.org/"
164        "ftp://ftp.solnet.ch/mirror/x.org/"
165        "ftp://mi.mirror.garr.it/mirrors/x.org/"
166        "ftp://mirror.cict.fr/x.org/"
167        "ftp://mirror.switch.ch/mirror/X11/"
168        "ftp://mirrors.ircam.fr/pub/x.org/"
169        "ftp://x.mirrors.skynet.be/pub/ftp.x.org/"
170        "http://x.cs.pu.edu.tw/" ; East Asia
171        "ftp://ftp.cs.cuhk.edu.hk/pub/X11"
172        "ftp://ftp.u-aizu.ac.jp/pub/x11/x.org/"
173        "ftp://ftp.yz.yamagata-u.ac.jp/pub/X11/x.org/"
174        "ftp://ftp.kaist.ac.kr/x.org/"
175        "ftp://mirrors.go-part.com/xorg/"
176        "ftp://ftp.is.co.za/pub/x.org")            ; South Africa
177       (cpan
178        "http://www.cpan.org/"
179        "http://cpan.metacpan.org/"
180        ;; A selection of HTTP mirrors from http://www.cpan.org/SITES.html.
181        ;; Europe.
182        "http://ftp.belnet.be/mirror/ftp.cpan.org/"
183        "http://mirrors.nic.cz/CPAN/"
184        "http://mirror.ibcp.fr/pub/CPAN/"
185        "http://ftp.ntua.gr/pub/lang/perl/"
186        "http://kvin.lv/pub/CPAN/"
187        "http://mirror.as43289.net/pub/CPAN/"
188        "http://cpan.cs.uu.nl/"
189        "http://cpan.uib.no/"
190        "http://cpan-mirror.rbc.ru/pub/CPAN/"
191        "http://mirror.sbb.rs/CPAN/"
192        "http://cpan.lnx.sk/"
193        "http://ftp.rediris.es/mirror/CPAN/"
194        "http://mirror.ox.ac.uk/sites/www.cpan.org/"
195        ;; Africa.
196        "http://mirror.liquidtelecom.com/CPAN/"
197        "http://cpan.mirror.ac.za/"
198        "http://mirror.is.co.za/pub/cpan/"
199        "http://cpan.saix.net/"
200        "http://mirror.ucu.ac.ug/cpan/"
201        ;; North America.
202        "http://mirrors.gossamer-threads.com/CPAN/"
203        "http://mirror.csclub.uwaterloo.ca/CPAN/"
204        "http://mirrors.ucr.ac.cr/CPAN/"
205        "http://www.msg.com.mx/CPAN/"
206        "http://mirrors.namecheap.com/CPAN/"
207        "http://mirror.uic.edu/CPAN/"
208        "http://mirror.datapipe.net/CPAN/"
209        "http://mirror.cc.columbia.edu/pub/software/cpan/"
210        "http://mirror.uta.edu/CPAN/"
211        ;; South America.
212        "http://cpan.mmgdesigns.com.ar/"
213        "http://mirror.nbtelecom.com.br/CPAN/"
214        "http://linorg.usp.br/CPAN/"
215        "http://cpan.dcc.uchile.cl/"
216        "http://mirror.cedia.org.ec/CPAN/"
217        ;; Oceania.
218        "http://cpan.mirror.serversaustralia.com.au/"
219        "http://mirror.waia.asn.au/pub/cpan/"
220        "http://mirror.as24220.net/pub/cpan/"
221        "http://cpan.lagoon.nc/pub/CPAN/"
222        "http://cpan.inspire.net.nz/"
223        ;; Asia.
224        "http://mirror.dhakacom.com/CPAN/"
225        "http://mirrors.ustc.edu.cn/CPAN/"
226        "http://ftp.cuhk.edu.hk/pub/packages/perl/CPAN/"
227        "http://kambing.ui.ac.id/cpan/"
228        "http://cpan.hostiran.ir/"
229        "http://ftp.nara.wide.ad.jp/pub/CPAN/"
230        "http://mirror.neolabs.kz/CPAN/"
231        "http://cpan.nctu.edu.tw/"
232        "http://cpan.ulak.net.tr/"
233        "http://mirrors.vinahost.vn/CPAN/")
234       (cran
235        ;; Arbitrary mirrors from http://cran.r-project.org/mirrors.html
236        ;; This one automatically redirects to servers worldwide
237        "http://cran.r-project.org/"
238        "http://cran.rstudio.com/"
239        "http://cran.univ-lyon1.fr/"
240        "http://cran.ism.ac.jp/"
241        "http://cran.stat.auckland.ac.nz/"
242        "http://cran.mirror.ac.za/"
243        "http://cran.csie.ntu.edu.tw/")
244       (imagemagick
245        ;; from http://www.imagemagick.org/script/download.php
246        ;; (without mirrors that are unavailable or not up to date)
247        ;; mirrors keeping old versions at the top level
248        "https://sunsite.icm.edu.pl/packages/ImageMagick/"
249        ;; mirrors moving old versions to "legacy"
250        "http://mirrors-usa.go-parts.com/mirrors/ImageMagick/"
251        "http://mirror.checkdomain.de/imagemagick/"
252        "http://ftp.surfnet.nl/pub/ImageMagick/"
253        "http://mirror.searchdaimon.com/ImageMagick"
254        "http://mirror.is.co.za/pub/imagemagick/"
255        "http://www.imagemagick.org/download/"
256        "ftp://mirror.aarnet.edu.au/pub/imagemagick/"
257        "ftp://ftp.kddlabs.co.jp/graphics/ImageMagick/"
258        "ftp://ftp.u-aizu.ac.jp/pub/graphics/image/ImageMagick/imagemagick.org/"
259        "ftp://ftp.nluug.nl/pub/ImageMagick/"
260        "ftp://ftp.tpnet.pl/pub/graphics/ImageMagick/"
261        "ftp://ftp.fifi.org/pub/ImageMagick/"
262        ;; one legacy location as a last resort
263        "http://www.imagemagick.org/download/legacy/")
264       (debian
265        "http://ftp.de.debian.org/debian/"
266        "http://ftp.fr.debian.org/debian/"
267        "http://ftp.debian.org/debian/"
268        "http://archive.debian.org/debian/")
269       (kde
270        "http://download.kde.org"
271        "http://download.kde.org/Attic" ; for when it gets archived.
272        ;; Mirrors from http://files.kde.org/extra/mirrors.html
273        ;; Europe
274        "http://mirror.easyname.at/kde"
275        "http://mirror.karneval.cz/pub/kde"
276        "http://ftp.fi.muni.cz/pub/kde/"
277        "http://mirror.oss.maxcdn.com/kde/"
278        "http://ftp5.gwdg.de/pub/linux/kde/"
279        "http://ftp-stud.fht-esslingen.de/Mirrors/ftp.kde.org/pub/kde/"
280        "http://mirror.klaus-uwe.me/kde/ftp/"
281        "http://kde.beta.mirror.ga/"
282        "http://kde.alpha.mirror.ga/"
283        "http://mirror.netcologne.de/kde"
284        "http://vesta.informatik.rwth-aachen.de/ftp/pub/mirror/kde/"
285        "http://ftp.rz.uni-wuerzburg.de/pub/unix/kde/"
286        "http://mirrors.dotsrc.org/kde/"
287        "http://ftp.funet.fi/pub/mirrors/ftp.kde.org/pub/kde/"
288        "http://kde-mirror.freenux.org/"
289        "http://mirrors.ircam.fr/pub/KDE/"
290        "http://www-ftp.lip6.fr/pub/X11/kde/"
291        "http://fr2.rpmfind.net/linux/KDE/"
292        "http://kde.mirror.anlx.net/"
293        "http://www.mirrorservice.org/sites/ftp.kde.org/pub/kde/"
294        "http://ftp.heanet.ie/mirrors/ftp.kde.org/"
295        "http://ftp.nluug.nl/pub/windowing/kde/"
296        "http://ftp.surfnet.nl/windowing/kde/"
297        "http://ftp.icm.edu.pl/pub/unix/kde/"
298        "http://ftp.pbone.net/pub/kde/"
299        "http://piotrkosoft.net/pub/mirrors/ftp.kde.org/"
300        "http://mirrors.fe.up.pt/pub/kde/"
301        "http://ftp.iasi.roedu.net/pub/mirrors/ftp.kde.org/"
302        "http://ftp.acc.umu.se/mirror/kde.org/ftp/"
303        "http://kde.ip-connect.vn.ua/"
304        ;; North America
305        "http://mirror.its.dal.ca/kde/"
306        "http://mirror.csclub.uwaterloo.ca/kde/"
307        "http://mirror.cc.columbia.edu/pub/software/kde/"
308        "http://mirrors-usa.go-parts.com/kde"
309        "http://kde.mirrors.hoobly.com/"
310        "http://ftp.ussg.iu.edu/kde/"
311        "http://mirrors.mit.edu/kde/"
312        "http://kde.mirrors.tds.net/pub/kde/"
313        ;; Oceania
314        "http://ftp.kddlabs.co.jp/pub/X11/kde/"
315        "http://kde.mirror.uber.com.au/")
316       (openbsd
317        "https://ftp.openbsd.org/pub/OpenBSD/"
318        ;; Anycast CDN redirecting to your friendly local mirror.
319        "https://mirrors.evowise.com/pub/OpenBSD/"
320        ;; Other HTTPS mirrors from https://www.openbsd.org/ftp.html
321        "https://mirror.aarnet.edu.au/pub/OpenBSD/"
322        "https://ftp2.eu.openbsd.org/pub/OpenBSD/"
323        "https://openbsd.c3sl.ufpr.br/pub/OpenBSD/"
324        "https://openbsd.ipacct.com/pub/OpenBSD/"
325        "https://ftp.OpenBSD.org/pub/OpenBSD/"
326        "https://openbsd.cs.toronto.edu/pub/OpenBSD/"
327        "https://openbsd.delfic.org/pub/OpenBSD/"
328        "https://openbsd.mirror.netelligent.ca/pub/OpenBSD/"
329        "https://mirrors.ucr.ac.cr/pub/OpenBSD/"
330        "https://mirrors.dotsrc.org/pub/OpenBSD/"
331        "https://mirror.one.com/pub/OpenBSD/"
332        "https://ftp.fr.openbsd.org/pub/OpenBSD/"
333        "https://ftp2.fr.openbsd.org/pub/OpenBSD/"
334        "https://mirrors.ircam.fr/pub/OpenBSD/"
335        "https://ftp.spline.de/pub/OpenBSD/"
336        "https://mirror.hs-esslingen.de/pub/OpenBSD/"
337        "https://ftp.halifax.rwth-aachen.de/openbsd/"
338        "https://ftp.hostserver.de/pub/OpenBSD/"
339        "https://ftp.fau.de/pub/OpenBSD/"
340        "https://ftp.cc.uoc.gr/pub/OpenBSD/"
341        "https://openbsd.hk/pub/OpenBSD/"
342        "https://ftp.heanet.ie/pub/OpenBSD/"
343        "https://openbsd.mirror.garr.it/pub/OpenBSD/"
344        "https://mirror.litnet.lt/pub/OpenBSD/"
345        "https://mirror.meerval.net/pub/OpenBSD/"
346        "https://ftp.nluug.nl/pub/OpenBSD/"
347        "https://ftp.bit.nl/pub/OpenBSD/"
348        "https://mirrors.dalenys.com/pub/OpenBSD/"
349        "https://ftp.icm.edu.pl/pub/OpenBSD/"
350        "https://ftp.rnl.tecnico.ulisboa.pt/pub/OpenBSD/"
351        "https://mirrors.pidginhost.com/pub/OpenBSD/"
352        "https://mirror.yandex.ru/pub/OpenBSD/"
353        "https://ftp.eu.openbsd.org/pub/OpenBSD/"
354        "https://ftp.yzu.edu.tw/pub/OpenBSD/"
355        "https://www.mirrorservice.org/pub/OpenBSD/"
356        "https://anorien.csc.warwick.ac.uk/pub/OpenBSD/"
357        "https://mirror.bytemark.co.uk/pub/OpenBSD/"
358        "https://mirrors.sonic.net/pub/OpenBSD/"
359        "https://ftp3.usa.openbsd.org/pub/OpenBSD/"
360        "https://mirrors.syringanetworks.net/pub/OpenBSD/"
361        "https://openbsd.mirror.constant.com/pub/OpenBSD/"
362        "https://ftp4.usa.openbsd.org/pub/OpenBSD/"
363        "https://ftp5.usa.openbsd.org/pub/OpenBSD/"
364        "https://mirror.esc7.net/pub/OpenBSD/")
365       (mate
366        "https://pub.mate-desktop.org/releases/"
367        "http://pub.mate-desktop.org/releases/"))))
369 (define %mirror-file
370   ;; Copy of the list of mirrors to a file.  This allows us to keep a single
371   ;; copy in the store, and computing it here avoids repeated calls to
372   ;; 'object->string'.
373   (plain-file "mirrors" (object->string %mirrors)))
375 (define %content-addressed-mirrors
376   ;; List of content-addressed mirrors.  Each mirror is represented as a
377   ;; procedure that takes a file name, an algorithm (symbol) and a hash
378   ;; (bytevector), and returns a URL or #f.
379   '(begin
380      (use-modules (guix base32))
382      (define (guix-publish host)
383        (lambda (file algo hash)
384          ;; Files served by 'guix publish' are accessible under a single
385          ;; hash algorithm.
386          (string-append "https://" host "/file/"
387                         file "/" (symbol->string algo) "/"
388                         (bytevector->nix-base32-string hash))))
390      ;; XXX: (guix base16) appeared in March 2017 (and thus 0.13.0) so old
391      ;; installations of the daemon might lack it.  Thus, load it lazily to
392      ;; avoid gratuitous errors.  See <https://bugs.gnu.org/33542>.
393      (module-autoload! (current-module)
394                        '(guix base16) '(bytevector->base16-string))
396      (list (guix-publish "mirror.hydra.gnu.org")
397            (guix-publish "berlin.guixsd.org")
398            (lambda (file algo hash)
399              ;; 'tarballs.nixos.org' supports several algorithms.
400              (string-append "https://tarballs.nixos.org/"
401                             (symbol->string algo) "/"
402                             (bytevector->nix-base32-string hash)))
403            (lambda (file algo hash)
404              ;; Software Heritage usually archives VCS history rather than
405              ;; tarballs, but tarballs are sometimes available (and can be
406              ;; explicitly stored there.)  For example, see
407              ;; <https://archive.softwareheritage.org/api/1/content/sha256:92d0fa1c311cacefa89853bdb53c62f4110cdfda3820346b59cbd098f40f955e/>.
408              (string-append "https://archive.softwareheritage.org/api/1/content/"
409                             (symbol->string algo) ":"
410                             (bytevector->base16-string hash) "/raw/")))))
412 (define %content-addressed-mirror-file
413   ;; Content-addressed mirrors stored in a file.
414   (plain-file "content-addressed-mirrors"
415               (object->string %content-addressed-mirrors)))
417 (define built-in-builders*
418   (store-lift built-in-builders))
420 (define* (built-in-download file-name url
421                             #:key system hash-algo hash
422                             mirrors content-addressed-mirrors
423                             (guile 'unused))
424   "Download FILE-NAME from URL using the built-in 'download' builder.
426 This is an \"out-of-band\" download in that the returned derivation does not
427 explicitly depend on Guile, GnuTLS, etc.  Instead, the daemon performs the
428 download by itself using its own dependencies."
429   (mlet %store-monad ((mirrors (lower-object mirrors))
430                       (content-addressed-mirrors
431                        (lower-object content-addressed-mirrors)))
432     (raw-derivation file-name "builtin:download" '()
433                     #:system system
434                     #:hash-algo hash-algo
435                     #:hash hash
436                     #:inputs `((,mirrors)
437                                (,content-addressed-mirrors))
439                     ;; Honor the user's proxy and locale settings.
440                     #:leaked-env-vars '("http_proxy" "https_proxy"
441                                         "LC_ALL" "LC_MESSAGES" "LANG"
442                                         "COLUMNS")
444                     #:env-vars `(("url" . ,(object->string url))
445                                  ("mirrors" . ,mirrors)
446                                  ("content-addressed-mirrors"
447                                   . ,content-addressed-mirrors))
449                     ;; Do not offload this derivation because we cannot be
450                     ;; sure that the remote daemon supports the 'download'
451                     ;; built-in.  We may remove this limitation when support
452                     ;; for that built-in is widespread.
453                     #:local-build? #t)))
455 (define* (url-fetch url hash-algo hash
456                     #:optional name
457                     #:key (system (%current-system))
458                     (guile (default-guile)))
459   "Return a fixed-output derivation that fetches URL (a string, or a list of
460 strings denoting alternate URLs), which is expected to have hash HASH of type
461 HASH-ALGO (a symbol).  By default, the file name is the base name of URL;
462 optionally, NAME can specify a different file name.
464 When one of the URL starts with mirror://, then its host part is
465 interpreted as the name of a mirror scheme, taken from %MIRROR-FILE.
467 Alternately, when URL starts with file://, return the corresponding file name
468 in the store."
469   (define file-name
470     (match url
471       ((head _ ...)
472        (basename head))
473       (_
474        (basename url))))
476   (let ((uri (and (string? url) (string->uri url))))
477     (if (or (and (string? url) (not uri))
478             (and uri (memq (uri-scheme uri) '(#f file))))
479         (interned-file (if uri (uri-path uri) url)
480                        (or name file-name))
481         (mlet %store-monad ((builtins (built-in-builders*)))
482           ;; The "download" built-in builder was added in guix-daemon in
483           ;; Nov. 2016 and made it in the 0.12.0 release of Dec. 2016.  We now
484           ;; require it.
485           (unless (member "download" builtins)
486             (error "'guix-daemon' is too old, please upgrade" builtins))
488           (built-in-download (or name file-name) url
489                              #:guile guile
490                              #:system system
491                              #:hash-algo hash-algo
492                              #:hash hash
493                              #:mirrors %mirror-file
494                              #:content-addressed-mirrors
495                              %content-addressed-mirror-file)))))
497 (define* (url-fetch/tarbomb url hash-algo hash
498                             #:optional name
499                             #:key (system (%current-system))
500                             (guile (default-guile)))
501   "Similar to 'url-fetch' but unpack the file from URL in a directory of its
502 own.  This helper makes it easier to deal with \"tar bombs\"."
503   (define file-name
504     (match url
505       ((head _ ...)
506        (basename head))
507       (_
508        (basename url))))
509   (define gzip
510     (module-ref (resolve-interface '(gnu packages compression)) 'gzip))
511   (define tar
512     (module-ref (resolve-interface '(gnu packages base)) 'tar))
514   (mlet %store-monad ((drv (url-fetch url hash-algo hash
515                                       (string-append "tarbomb-"
516                                                      (or name file-name))
517                                       #:system system
518                                       #:guile guile)))
519     ;; Take the tar bomb, and simply unpack it as a directory.
520     ;; Use ungrafted tar/gzip so that the resulting tarball doesn't depend on
521     ;; whether grafts are enabled.
522     (gexp->derivation (or name file-name)
523                       (with-imported-modules '((guix build utils))
524                         #~(begin
525                             (use-modules (guix build utils))
526                             (mkdir #$output)
527                             (setenv "PATH" (string-append #$gzip "/bin"))
528                             (chdir #$output)
529                             (invoke (string-append #$tar "/bin/tar")
530                                     "xf" #$drv)))
531                       #:graft? #f
532                       #:local-build? #t)))
534 (define* (url-fetch/zipbomb url hash-algo hash
535                             #:optional name
536                             #:key (system (%current-system))
537                             (guile (default-guile)))
538   "Similar to 'url-fetch' but unpack the zip file at URL in a directory of its
539 own.  This helper makes it easier to deal with \"zip bombs\"."
540   (define file-name
541     (match url
542       ((head _ ...)
543        (basename head))
544       (_
545        (basename url))))
546   (define unzip
547     (module-ref (resolve-interface '(gnu packages compression)) 'unzip))
549   (mlet %store-monad ((drv (url-fetch url hash-algo hash
550                                       (string-append "zipbomb-"
551                                                      (or name file-name))
552                                       #:system system
553                                       #:guile guile)))
554     ;; Take the zip bomb, and simply unpack it as a directory.
555     ;; Use ungrafted unzip so that the resulting tarball doesn't depend on
556     ;; whether grafts are enabled.
557     (gexp->derivation (or name file-name)
558                       (with-imported-modules '((guix build utils))
559                         #~(begin
560                             (use-modules (guix build utils))
561                             (mkdir #$output)
562                             (chdir #$output)
563                             (invoke (string-append #$unzip "/bin/unzip")
564                                     #$drv)))
565                       #:graft? #f
566                       #:local-build? #t)))
568 (define* (download-to-store store url #:optional (name (basename url))
569                             #:key (log (current-error-port)) recursive?
570                             (verify-certificate? #t))
571   "Download from URL to STORE, either under NAME or URL's basename if
572 omitted.  Write progress reports to LOG.  RECURSIVE? has the same effect as
573 the same-named parameter of 'add-to-store'.  VERIFY-CERTIFICATE? determines
574 whether or not to validate HTTPS server certificates."
575   (define uri
576     (string->uri url))
578   (if (or (not uri) (memq (uri-scheme uri) '(file #f)))
579       (add-to-store store name recursive? "sha256"
580                     (if uri (uri-path uri) url))
581       (call-with-temporary-output-file
582        (lambda (temp port)
583          (let ((result
584                 (parameterize ((current-output-port log))
585                   (build:url-fetch url temp
586                                    #:mirrors %mirrors
587                                    #:verify-certificate?
588                                    verify-certificate?))))
589            (close port)
590            (and result
591                 (add-to-store store name recursive? "sha256" temp)))))))
593 ;;; download.scm ends here