Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{
2 lib,
3 buildPackages ? {
4 inherit stdenvNoCC;
5 },
6 stdenvNoCC,
7 curl, # Note that `curl' may be `null', in case of the native stdenvNoCC.
8 cacert ? null,
9 rewriteURL,
10}:
11
12let
13
14 mirrors = import ./mirrors.nix;
15
16 # Write the list of mirrors to a file that we can reuse between
17 # fetchurl instantiations, instead of passing the mirrors to
18 # fetchurl instantiations via environment variables. This makes the
19 # resulting store derivations (.drv files) much smaller, which in
20 # turn makes nix-env/nix-instantiate faster.
21 mirrorsFile = buildPackages.stdenvNoCC.mkDerivation (
22 {
23 name = "mirrors-list";
24 strictDeps = true;
25 builder = ./write-mirror-list.sh;
26 preferLocalBuild = true;
27 }
28 // mirrors
29 );
30
31 # Names of the master sites that are mirrored (i.e., "sourceforge",
32 # "gnu", etc.).
33 sites = builtins.attrNames mirrors;
34
35 impureEnvVars =
36 lib.fetchers.proxyImpureEnvVars
37 ++ [
38 # This variable allows the user to pass additional options to curl
39 "NIX_CURL_FLAGS"
40
41 # This variable allows the user to override hashedMirrors from the
42 # command-line.
43 "NIX_HASHED_MIRRORS"
44
45 # This variable allows overriding the timeout for connecting to
46 # the hashed mirrors.
47 "NIX_CONNECT_TIMEOUT"
48 ]
49 ++ (map (site: "NIX_MIRRORS_${site}") sites);
50
51in
52
53{
54 # URL to fetch.
55 url ? "",
56
57 # Alternatively, a list of URLs specifying alternative download
58 # locations. They are tried in order.
59 urls ? [ ],
60
61 # Additional curl options needed for the download to succeed.
62 # Warning: Each space (no matter the escaping) will start a new argument.
63 # If you wish to pass arguments with spaces, use `curlOptsList`
64 curlOpts ? "",
65
66 # Additional curl options needed for the download to succeed.
67 curlOptsList ? [ ],
68
69 # Name of the file. If empty, use the basename of `url' (or of the
70 # first element of `urls').
71 name ? "",
72
73 # for versioned downloads optionally take pname + version.
74 pname ? "",
75 version ? "",
76
77 # SRI hash.
78 hash ? "",
79
80 # Legacy ways of specifying the hash.
81 outputHash ? "",
82 outputHashAlgo ? "",
83 sha1 ? "",
84 sha256 ? "",
85 sha512 ? "",
86
87 recursiveHash ? false,
88
89 # Shell code to build a netrc file for BASIC auth
90 netrcPhase ? null,
91
92 # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes)
93 # needed for netrcPhase
94 netrcImpureEnvVars ? [ ],
95
96 # Shell code executed after the file has been fetched
97 # successfully. This can do things like check or transform the file.
98 postFetch ? "",
99
100 # Whether to download to a temporary path rather than $out. Useful
101 # in conjunction with postFetch. The location of the temporary file
102 # is communicated to postFetch via $downloadedFile.
103 downloadToTemp ? false,
104
105 # If true, set executable bit on downloaded file
106 executable ? false,
107
108 # If set, don't download the file, but write a list of all possible
109 # URLs (resulting from resolving mirror:// URLs) to $out.
110 showURLs ? false,
111
112 # Meta information, if any.
113 meta ? { },
114
115 # Passthru information, if any.
116 passthru ? { },
117 # Doing the download on a remote machine just duplicates network
118 # traffic, so don't do that by default
119 preferLocalBuild ? true,
120
121 # Additional packages needed as part of a fetch
122 nativeBuildInputs ? [ ],
123}@args:
124
125let
126 preRewriteUrls =
127 if urls != [ ] && url == "" then
128 (
129 if lib.isList urls then urls else throw "`urls` is not a list: ${lib.generators.toPretty { } urls}"
130 )
131 else if urls == [ ] && url != "" then
132 (
133 if lib.isString url then
134 [ url ]
135 else
136 throw "`url` is not a string: ${lib.generators.toPretty { } urls}"
137 )
138 else
139 throw "fetchurl requires either `url` or `urls` to be set: ${lib.generators.toPretty { } args}";
140
141 urls_ =
142 let
143 u = lib.lists.filter (url: lib.isString url) (map rewriteURL preRewriteUrls);
144 in
145 if u == [ ] then throw "urls is empty after rewriteURL (was ${toString preRewriteUrls})" else u;
146
147 hash_ =
148 if
149 with lib.lists;
150 length (
151 filter (s: s != "") [
152 hash
153 outputHash
154 sha1
155 sha256
156 sha512
157 ]
158 ) > 1
159 then
160 throw "multiple hashes passed to fetchurl: ${lib.generators.toPretty { } urls_}"
161 else
162
163 if hash != "" then
164 {
165 outputHashAlgo = null;
166 outputHash = hash;
167 }
168 else if outputHash != "" then
169 if outputHashAlgo != "" then
170 { inherit outputHashAlgo outputHash; }
171 else
172 throw "fetchurl was passed outputHash without outputHashAlgo: ${lib.generators.toPretty { } urls_}"
173 else if sha512 != "" then
174 {
175 outputHashAlgo = "sha512";
176 outputHash = sha512;
177 }
178 else if sha256 != "" then
179 {
180 outputHashAlgo = "sha256";
181 outputHash = sha256;
182 }
183 else if sha1 != "" then
184 {
185 outputHashAlgo = "sha1";
186 outputHash = sha1;
187 }
188 else if cacert != null then
189 {
190 outputHashAlgo = "sha256";
191 outputHash = "";
192 }
193 else
194 throw "fetchurl requires a hash for fixed-output derivation: ${lib.generators.toPretty urls_}";
195
196 resolvedUrl =
197 let
198 mirrorSplit = lib.match "mirror://([[:alpha:]]+)/(.+)" url;
199 mirrorName = lib.head mirrorSplit;
200 mirrorList =
201 if lib.hasAttr mirrorName mirrors then
202 mirrors."${mirrorName}"
203 else
204 throw "unknown mirror:// site ${mirrorName}";
205 in
206 if mirrorSplit == null || mirrorName == null then
207 url
208 else
209 "${lib.head mirrorList}${lib.elemAt mirrorSplit 1}";
210in
211
212assert
213 (lib.isList curlOpts)
214 -> lib.warn ''
215 fetchurl for ${toString (builtins.head urls_)}: curlOpts is a list (${
216 lib.generators.toPretty { multiline = false; } curlOpts
217 }), which is not supported anymore.
218 - If you wish to get the same effect as before, for elements with spaces (even if escaped) to expand to multiple curl arguments, use a string argument instead:
219 curlOpts = ${lib.strings.escapeNixString (toString curlOpts)};
220 - If you wish for each list element to be passed as a separate curl argument, allowing arguments to contain spaces, use curlOptsList instead:
221 curlOptsList = [ ${lib.concatMapStringsSep " " lib.strings.escapeNixString curlOpts} ];'' true;
222
223stdenvNoCC.mkDerivation (
224 (
225 if (pname != "" && version != "") then
226 { inherit pname version; }
227 else
228 {
229 name =
230 if showURLs then
231 "urls"
232 else if name != "" then
233 name
234 else
235 baseNameOf (toString (builtins.head urls_));
236 }
237 )
238 // {
239 builder = ./builder.sh;
240
241 nativeBuildInputs = [ curl ] ++ nativeBuildInputs;
242
243 urls = urls_;
244
245 # If set, prefer the content-addressable mirrors
246 # (http://tarballs.nixos.org) over the original URLs.
247 preferHashedMirrors = false;
248
249 # New-style output content requirements.
250 inherit (hash_) outputHashAlgo outputHash;
251
252 # Disable TLS verification only when we know the hash and no credentials are
253 # needed to access the resource
254 SSL_CERT_FILE =
255 if
256 (
257 hash_.outputHash == ""
258 || hash_.outputHash == lib.fakeSha256
259 || hash_.outputHash == lib.fakeSha512
260 || hash_.outputHash == lib.fakeHash
261 || netrcPhase != null
262 )
263 then
264 "${cacert}/etc/ssl/certs/ca-bundle.crt"
265 else
266 "/no-cert-file.crt";
267
268 outputHashMode = if (recursiveHash || executable) then "recursive" else "flat";
269
270 inherit curlOpts;
271 curlOptsList = lib.escapeShellArgs curlOptsList;
272 inherit
273 showURLs
274 mirrorsFile
275 postFetch
276 downloadToTemp
277 executable
278 ;
279
280 impureEnvVars = impureEnvVars ++ netrcImpureEnvVars;
281
282 nixpkgsVersion = lib.trivial.release;
283
284 inherit preferLocalBuild;
285
286 postHook =
287 if netrcPhase == null then
288 null
289 else
290 ''
291 ${netrcPhase}
292 curlOpts="$curlOpts --netrc-file $PWD/netrc"
293 '';
294
295 inherit meta;
296 passthru = {
297 inherit url resolvedUrl;
298 }
299 // passthru;
300 }
301)