···2727 boot.loader.generic-extlinux-compatible.enable = true;
28282929 boot.kernelPackages = pkgs.linuxPackages_latest;
3030- boot.kernelParams = ["console=ttyS0,115200n8" "console=tty0"];
3030+ # Increase the amount of CMA to ensure the virtual console on the RPi3 works.
3131+ boot.kernelParams = ["cma=32M" "console=ttyS0,115200n8" "console=tty0"];
3132 boot.consoleLogLevel = 7;
32333334 # FIXME: this probably should be in installation-device.nix
···106106binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')"
107107extraBuildFlags+=(--option "binary-caches" "$binary_caches")
108108109109-nixpkgs="$(readlink -f "$(nix-instantiate --find-file nixpkgs)")"
110110-export NIX_PATH="nixpkgs=$nixpkgs:nixos-config=$mountPoint/$NIXOS_CONFIG"
109109+# We only need nixpkgs in the path if we don't already have a system closure to install
110110+if [[ -z "$closure" ]]; then
111111+ nixpkgs="$(readlink -f "$(nix-instantiate --find-file nixpkgs)")"
112112+ export NIX_PATH="nixpkgs=$nixpkgs:nixos-config=$mountPoint/$NIXOS_CONFIG"
113113+fi
111114unset NIXOS_CONFIG
112115113116# TODO: do I need to set NIX_SUBSTITUTERS here or is the --option binary-caches above enough?
···123126}
124127125128system_closure="$tmpdir/system.closure"
129129+# Use a FIFO for piping nix-store --export into nix-store --import, saving disk
130130+# I/O and space. nix-store --import is run by nixos-prepare-root.
131131+mkfifo $system_closure
126132127133if [ -z "$closure" ]; then
128134 expr="(import <nixpkgs/nixos> {}).system"
···132138 system_root=$closure
133139 # Create a temporary file ending in .closure (so nixos-prepare-root knows to --import it) to transport the store closure
134140 # to the filesytem we're preparing. Also delete it on exit!
135135- nix-store --export $(nix-store -qR $closure) > $system_closure
141141+ # Run in background to avoid blocking while trying to write to the FIFO
142142+ # $system_closure refers to
143143+ nix-store --export $(nix-store -qR $closure) > $system_closure &
136144fi
137145138146channel_root="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
···24242525 kernel = config.boot.kernelPackages;
26262727- packages = {
2727+ packages = if config.boot.zfs.enableUnstable then {
2828+ spl = kernel.splUnstable;
2929+ zfs = kernel.zfsUnstable;
3030+ zfsUser = pkgs.zfsUnstable;
3131+ } else {
2832 spl = kernel.spl;
2933 zfs = kernel.zfs;
3034 zfsUser = pkgs.zfs;
···58625963 options = {
6064 boot.zfs = {
6565+ enableUnstable = mkOption {
6666+ type = types.bool;
6767+ default = false;
6868+ description = ''
6969+ Use the unstable zfs package. This might be an option, if the latest
7070+ kernel is not yet supported by a published release of ZFS. Enabling
7171+ this option will install a development version of ZFS on Linux. The
7272+ version will have already passed an extensive test suite, but it is
7373+ more likely to hit an undiscovered bug compared to running a released
7474+ version of ZFS on Linux.
7575+ '';
7676+ };
7777+6178 extraPools = mkOption {
6279 type = types.listOf types.str;
6380 default = [];
···214214 # Run the tests for each platform. You can run a test by doing
215215 # e.g. ‘nix-build -A tests.login.x86_64-linux’, or equivalently,
216216 # ‘nix-build tests/login.nix -A result’.
217217+ tests.acme = callTest tests/acme.nix {};
217218 tests.avahi = callTest tests/avahi.nix {};
218219 tests.bittorrent = callTest tests/bittorrent.nix {};
219220 tests.blivet = callTest tests/blivet.nix {};
···11+# Fully pluggable module to have Letsencrypt's Boulder ACME service running in
22+# a test environment.
33+#
44+# The certificate for the ACME service is exported as:
55+#
66+# config.test-support.letsencrypt.caCert
77+#
88+# This value can be used inside the configuration of other test nodes to inject
99+# the snakeoil certificate into security.pki.certificateFiles or into package
1010+# overlays.
1111+#
1212+# Another value that's needed if you don't use a custom resolver (see below for
1313+# notes on that) is to add the letsencrypt node as a nameserver to every node
1414+# that needs to acquire certificates using ACME, because otherwise the API host
1515+# for letsencrypt.org can't be resolved.
1616+#
1717+# A configuration example of a full node setup using this would be this:
1818+#
1919+# {
2020+# letsencrypt = import ./common/letsencrypt.nix;
2121+#
2222+# example = { nodes, ... }: {
2323+# networking.nameservers = [
2424+# nodes.letsencrypt.config.networking.primaryIPAddress
2525+# ];
2626+# security.pki.certificateFiles = [
2727+# nodes.letsencrypt.config.test-support.letsencrypt.caCert
2828+# ];
2929+# };
3030+# }
3131+#
3232+# By default, this module runs a local resolver, generated using resolver.nix
3333+# from the same directory to automatically discover all zones in the network.
3434+#
3535+# If you do not want this and want to use your own resolver, you can just
3636+# override networking.nameservers like this:
3737+#
3838+# {
3939+# letsencrypt = { nodes, ... }: {
4040+# imports = [ ./common/letsencrypt.nix ];
4141+# networking.nameservers = [
4242+# nodes.myresolver.config.networking.primaryIPAddress
4343+# ];
4444+# };
4545+#
4646+# myresolver = ...;
4747+# }
4848+#
4949+# Keep in mind, that currently only _one_ resolver is supported, if you have
5050+# more than one resolver in networking.nameservers only the first one will be
5151+# used.
5252+#
5353+# Also make sure that whenever you use a resolver from a different test node
5454+# that it has to be started _before_ the ACME service.
5555+{ config, pkgs, lib, ... }:
5656+5757+let
5858+ softhsm = pkgs.stdenv.mkDerivation rec {
5959+ name = "softhsm-${version}";
6060+ version = "1.3.8";
6161+6262+ src = pkgs.fetchurl {
6363+ url = "https://dist.opendnssec.org/source/${name}.tar.gz";
6464+ sha256 = "0flmnpkgp65ym7w3qyg78d3fbmvq3aznmi66rgd420n33shf7aif";
6565+ };
6666+6767+ configureFlags = [ "--with-botan=${pkgs.botan}" ];
6868+ buildInputs = [ pkgs.sqlite ];
6969+ };
7070+7171+ pkcs11-proxy = pkgs.stdenv.mkDerivation {
7272+ name = "pkcs11-proxy";
7373+7474+ src = pkgs.fetchFromGitHub {
7575+ owner = "SUNET";
7676+ repo = "pkcs11-proxy";
7777+ rev = "944684f78bca0c8da6cabe3fa273fed3db44a890";
7878+ sha256 = "1nxgd29y9wmifm11pjcdpd2y293p0dgi0x5ycis55miy97n0f5zy";
7979+ };
8080+8181+ postPatch = "patchShebangs mksyscalls.sh";
8282+8383+ nativeBuildInputs = [ pkgs.cmake ];
8484+ buildInputs = [ pkgs.openssl pkgs.libseccomp ];
8585+ };
8686+8787+ mkGoDep = { goPackagePath, url ? "https://${goPackagePath}", rev, sha256 }: {
8888+ inherit goPackagePath;
8989+ src = pkgs.fetchgit { inherit url rev sha256; };
9090+ };
9191+9292+ goose = let
9393+ owner = "liamstask";
9494+ repo = "goose";
9595+ rev = "8488cc47d90c8a502b1c41a462a6d9cc8ee0a895";
9696+ version = "20150116";
9797+9898+ in pkgs.buildGoPackage rec {
9999+ name = "${repo}-${version}";
100100+101101+ src = pkgs.fetchFromBitbucket {
102102+ name = "${name}-src";
103103+ inherit rev owner repo;
104104+ sha256 = "1jy0pscxjnxjdg3hj111w21g8079rq9ah2ix5ycxxhbbi3f0wdhs";
105105+ };
106106+107107+ goPackagePath = "bitbucket.org/${owner}/${repo}";
108108+ subPackages = [ "cmd/goose" ];
109109+ extraSrcs = map mkGoDep [
110110+ { goPackagePath = "github.com/go-sql-driver/mysql";
111111+ rev = "2e00b5cd70399450106cec6431c2e2ce3cae5034";
112112+ sha256 = "085g48jq9hzmlcxg122n0c4pi41sc1nn2qpx1vrl2jfa8crsppa5";
113113+ }
114114+ { goPackagePath = "github.com/kylelemons/go-gypsy";
115115+ rev = "08cad365cd28a7fba23bb1e57aa43c5e18ad8bb8";
116116+ sha256 = "1djv7nii3hy451n5jlslk0dblqzb1hia1cbqpdwhnps1g8hqjy8q";
117117+ }
118118+ { goPackagePath = "github.com/lib/pq";
119119+ rev = "ba5d4f7a35561e22fbdf7a39aa0070f4d460cfc0";
120120+ sha256 = "1mfbqw9g00bk24bfmf53wri5c2wqmgl0qh4sh1qv2da13a7cwwg3";
121121+ }
122122+ { goPackagePath = "github.com/mattn/go-sqlite3";
123123+ rev = "2acfafad5870400156f6fceb12852c281cbba4d5";
124124+ sha256 = "1rpgil3w4hh1cibidskv1js898hwz83ps06gh0hm3mym7ki8d5h7";
125125+ }
126126+ { goPackagePath = "github.com/ziutek/mymysql";
127127+ rev = "0582bcf675f52c0c2045c027fd135bd726048f45";
128128+ sha256 = "0bkc9x8sgqbzgdimsmsnhb0qrzlzfv33fgajmmjxl4hcb21qz3rf";
129129+ }
130130+ { goPackagePath = "golang.org/x/net";
131131+ url = "https://go.googlesource.com/net";
132132+ rev = "10c134ea0df15f7e34d789338c7a2d76cc7a3ab9";
133133+ sha256 = "14cbr2shl08gyg85n5gj7nbjhrhhgrd52h073qd14j97qcxsakcz";
134134+ }
135135+ ];
136136+ };
137137+138138+ boulder = let
139139+ owner = "letsencrypt";
140140+ repo = "boulder";
141141+ rev = "9866abab8962a591f06db457a4b84c518cc88243";
142142+ version = "20170510";
143143+144144+ in pkgs.buildGoPackage rec {
145145+ name = "${repo}-${version}";
146146+147147+ src = pkgs.fetchFromGitHub {
148148+ name = "${name}-src";
149149+ inherit rev owner repo;
150150+ sha256 = "170m5cjngbrm36wi7wschqw8jzs7kxpcyzmshq3pcrmcpigrhna1";
151151+ };
152152+153153+ postPatch = ''
154154+ # compat for go < 1.8
155155+ sed -i -e 's/time\.Until(\([^)]\+\))/\1.Sub(time.Now())/' \
156156+ test/ocsp/helper/helper.go
157157+158158+ find test -type f -exec sed -i -e '/libpkcs11-proxy.so/ {
159159+ s,/usr/local,${pkcs11-proxy},
160160+ }' {} +
161161+162162+ sed -i -r \
163163+ -e '/^def +install/a \ return True' \
164164+ -e 's,exec \./bin/,,' \
165165+ test/startservers.py
166166+167167+ cat "${snakeOilCa}/ca.key" > test/test-ca.key
168168+ cat "${snakeOilCa}/ca.pem" > test/test-ca.pem
169169+ '';
170170+171171+ goPackagePath = "github.com/${owner}/${repo}";
172172+ buildInputs = [ pkgs.libtool ];
173173+ };
174174+175175+ boulderSource = "${boulder.out}/share/go/src/${boulder.goPackagePath}";
176176+177177+ softHsmConf = pkgs.writeText "softhsm.conf" ''
178178+ 0:/var/lib/softhsm/slot0.db
179179+ 1:/var/lib/softhsm/slot1.db
180180+ '';
181181+182182+ snakeOilCa = pkgs.runCommand "snakeoil-ca" {
183183+ buildInputs = [ pkgs.openssl ];
184184+ } ''
185185+ mkdir "$out"
186186+ openssl req -newkey rsa:4096 -x509 -sha256 -days 36500 \
187187+ -subj '/CN=Snakeoil CA' -nodes \
188188+ -out "$out/ca.pem" -keyout "$out/ca.key"
189189+ '';
190190+191191+ createAndSignCert = fqdn: let
192192+ snakeoilCertConf = pkgs.writeText "snakeoil.cnf" ''
193193+ [req]
194194+ default_bits = 4096
195195+ prompt = no
196196+ default_md = sha256
197197+ req_extensions = req_ext
198198+ distinguished_name = dn
199199+ [dn]
200200+ CN = ${fqdn}
201201+ [req_ext]
202202+ subjectAltName = DNS:${fqdn}
203203+ '';
204204+ in pkgs.runCommand "snakeoil-certs-${fqdn}" {
205205+ buildInputs = [ pkgs.openssl ];
206206+ } ''
207207+ mkdir "$out"
208208+ openssl genrsa -out "$out/snakeoil.key" 4096
209209+ openssl req -new -key "$out/snakeoil.key" \
210210+ -config ${lib.escapeShellArg snakeoilCertConf} \
211211+ -out snakeoil.csr
212212+ openssl x509 -req -in snakeoil.csr -sha256 -set_serial 666 \
213213+ -CA "${snakeOilCa}/ca.pem" -CAkey "${snakeOilCa}/ca.key" \
214214+ -extfile ${lib.escapeShellArg snakeoilCertConf} \
215215+ -out "$out/snakeoil.pem" -days 36500
216216+ '';
217217+218218+ wfeCerts = createAndSignCert wfeDomain;
219219+ wfeDomain = "acme-v01.api.letsencrypt.org";
220220+ wfeCertFile = "${wfeCerts}/snakeoil.pem";
221221+ wfeKeyFile = "${wfeCerts}/snakeoil.key";
222222+223223+ siteCerts = createAndSignCert siteDomain;
224224+ siteDomain = "letsencrypt.org";
225225+ siteCertFile = "${siteCerts}/snakeoil.pem";
226226+ siteKeyFile = "${siteCerts}/snakeoil.key";
227227+228228+ # Retrieved via:
229229+ # curl -s -I https://acme-v01.api.letsencrypt.org/terms \
230230+ # | sed -ne 's/^[Ll]ocation: *//p'
231231+ tosUrl = "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf";
232232+ tosPath = builtins.head (builtins.match "https?://[^/]+(.*)" tosUrl);
233233+234234+ tosFile = pkgs.fetchurl {
235235+ url = tosUrl;
236236+ sha256 = "08b2gacdz23mzji2pjr1pwnk82a84rzvr36isif7mmi9kydl6wv3";
237237+ };
238238+239239+ resolver = let
240240+ message = "You need to define a resolver for the letsencrypt test module.";
241241+ firstNS = lib.head config.networking.nameservers;
242242+ in if config.networking.nameservers == [] then throw message else firstNS;
243243+244244+ cfgDir = pkgs.stdenv.mkDerivation {
245245+ name = "boulder-config";
246246+ src = "${boulderSource}/test/config";
247247+ nativeBuildInputs = [ pkgs.jq ];
248248+ phases = [ "unpackPhase" "patchPhase" "installPhase" ];
249249+ postPatch = ''
250250+ sed -i -e 's/5002/80/' -e 's/5002/443/' va.json
251251+ sed -i -e '/listenAddress/s/:4000/:80/' wfe.json
252252+ sed -i -r \
253253+ -e ${lib.escapeShellArg "s,http://boulder:4000/terms/v1,${tosUrl},g"} \
254254+ -e 's,http://(boulder|127\.0\.0\.1):4000,https://${wfeDomain},g' \
255255+ -e '/dnsResolver/s/127\.0\.0\.1:8053/${resolver}:53/' \
256256+ *.json
257257+ if grep 4000 *.json; then exit 1; fi
258258+259259+ # Change all ports from 1909X to 909X, because the 1909X range of ports is
260260+ # allocated by startservers.py in order to intercept gRPC communication.
261261+ sed -i -e 's/\<1\(909[0-9]\)\>/\1/' *.json
262262+263263+ # Patch out all additional issuer certs
264264+ jq '. + {ca: (.ca + {Issuers:
265265+ [.ca.Issuers[] | select(.CertFile == "test/test-ca.pem")]
266266+ })}' ca.json > tmp
267267+ mv tmp ca.json
268268+ '';
269269+ installPhase = "cp -r . \"$out\"";
270270+ };
271271+272272+ components = {
273273+ gsb-test-srv.args = "-apikey my-voice-is-my-passport";
274274+ gsb-test-srv.waitForPort = 6000;
275275+ gsb-test-srv.first = true;
276276+ boulder-sa.args = "--config ${cfgDir}/sa.json";
277277+ boulder-wfe.args = "--config ${cfgDir}/wfe.json";
278278+ boulder-ra.args = "--config ${cfgDir}/ra.json";
279279+ boulder-ca.args = "--config ${cfgDir}/ca.json";
280280+ boulder-va.args = "--config ${cfgDir}/va.json";
281281+ boulder-publisher.args = "--config ${cfgDir}/publisher.json";
282282+ boulder-publisher.waitForPort = 9091;
283283+ ocsp-updater.args = "--config ${cfgDir}/ocsp-updater.json";
284284+ ocsp-updater.after = [ "boulder-publisher" ];
285285+ ocsp-responder.args = "--config ${cfgDir}/ocsp-responder.json";
286286+ ct-test-srv = {};
287287+ mail-test-srv.args = "--closeFirst 5";
288288+ };
289289+290290+ commonPath = [ softhsm pkgs.mariadb goose boulder ];
291291+292292+ mkServices = a: b: with lib; listToAttrs (concatLists (mapAttrsToList a b));
293293+294294+ componentServices = mkServices (name: attrs: let
295295+ mkSrvName = n: "boulder-${n}.service";
296296+ firsts = lib.filterAttrs (lib.const (c: c.first or false)) components;
297297+ firstServices = map mkSrvName (lib.attrNames firsts);
298298+ firstServicesNoSelf = lib.remove "boulder-${name}.service" firstServices;
299299+ additionalAfter = firstServicesNoSelf ++ map mkSrvName (attrs.after or []);
300300+ needsPort = attrs ? waitForPort;
301301+ inits = map (n: "boulder-init-${n}.service") [ "mysql" "softhsm" ];
302302+ portWaiter = {
303303+ name = "boulder-${name}";
304304+ value = {
305305+ description = "Wait For Port ${toString attrs.waitForPort} (${name})";
306306+ after = [ "boulder-real-${name}.service" "bind.service" ];
307307+ requires = [ "boulder-real-${name}.service" ];
308308+ requiredBy = [ "boulder.service" ];
309309+ serviceConfig.Type = "oneshot";
310310+ serviceConfig.RemainAfterExit = true;
311311+ script = let
312312+ netcat = "${pkgs.netcat-openbsd}/bin/nc";
313313+ portCheck = "${netcat} -z 127.0.0.1 ${toString attrs.waitForPort}";
314314+ in "while ! ${portCheck}; do :; done";
315315+ };
316316+ };
317317+ in lib.optional needsPort portWaiter ++ lib.singleton {
318318+ name = if needsPort then "boulder-real-${name}" else "boulder-${name}";
319319+ value = {
320320+ description = "Boulder ACME Component (${name})";
321321+ after = inits ++ additionalAfter;
322322+ requires = inits;
323323+ requiredBy = [ "boulder.service" ];
324324+ path = commonPath;
325325+ environment.GORACE = "halt_on_error=1";
326326+ environment.SOFTHSM_CONF = softHsmConf;
327327+ environment.PKCS11_PROXY_SOCKET = "tcp://127.0.0.1:5657";
328328+ serviceConfig.WorkingDirectory = boulderSource;
329329+ serviceConfig.ExecStart = "${boulder}/bin/${name} ${attrs.args or ""}";
330330+ serviceConfig.Restart = "on-failure";
331331+ };
332332+ }) components;
333333+334334+in {
335335+ imports = [ ./resolver.nix ];
336336+337337+ options.test-support.letsencrypt.caCert = lib.mkOption {
338338+ type = lib.types.path;
339339+ description = ''
340340+ A certificate file to use with the <literal>nodes</literal> attribute to
341341+ inject the snakeoil CA certificate used in the ACME server into
342342+ <option>security.pki.certificateFiles</option>.
343343+ '';
344344+ };
345345+346346+ config = {
347347+ test-support = {
348348+ resolver.enable = let
349349+ isLocalResolver = config.networking.nameservers == [ "127.0.0.1" ];
350350+ in lib.mkOverride 900 isLocalResolver;
351351+ letsencrypt.caCert = "${snakeOilCa}/ca.pem";
352352+ };
353353+354354+ # This has priority 140, because modules/testing/test-instrumentation.nix
355355+ # already overrides this with priority 150.
356356+ networking.nameservers = lib.mkOverride 140 [ "127.0.0.1" ];
357357+ networking.firewall.enable = false;
358358+359359+ networking.extraHosts = ''
360360+ 127.0.0.1 ${toString [
361361+ "sa.boulder" "ra.boulder" "wfe.boulder" "ca.boulder" "va.boulder"
362362+ "publisher.boulder" "ocsp-updater.boulder" "admin-revoker.boulder"
363363+ "boulder" "boulder-mysql" wfeDomain
364364+ ]}
365365+ ${config.networking.primaryIPAddress} ${wfeDomain} ${siteDomain}
366366+ '';
367367+368368+ services.mysql.enable = true;
369369+ services.mysql.package = pkgs.mariadb;
370370+371371+ services.nginx.enable = true;
372372+ services.nginx.recommendedProxySettings = true;
373373+ services.nginx.virtualHosts.${wfeDomain} = {
374374+ onlySSL = true;
375375+ enableACME = false;
376376+ sslCertificate = wfeCertFile;
377377+ sslCertificateKey = wfeKeyFile;
378378+ locations."/".proxyPass = "http://127.0.0.1:80";
379379+ };
380380+ services.nginx.virtualHosts.${siteDomain} = {
381381+ onlySSL = true;
382382+ enableACME = false;
383383+ sslCertificate = siteCertFile;
384384+ sslCertificateKey = siteKeyFile;
385385+ locations.${tosPath}.extraConfig = "alias ${tosFile};";
386386+ };
387387+388388+ systemd.services = {
389389+ pkcs11-daemon = {
390390+ description = "PKCS11 Daemon";
391391+ after = [ "boulder-init-softhsm.service" ];
392392+ before = map (n: "${n}.service") (lib.attrNames componentServices);
393393+ wantedBy = [ "multi-user.target" ];
394394+ environment.SOFTHSM_CONF = softHsmConf;
395395+ environment.PKCS11_DAEMON_SOCKET = "tcp://127.0.0.1:5657";
396396+ serviceConfig.ExecStart = let
397397+ softhsmLib = "${softhsm}/lib/softhsm/libsofthsm.so";
398398+ in "${pkcs11-proxy}/bin/pkcs11-daemon ${softhsmLib}";
399399+ };
400400+401401+ boulder-init-mysql = {
402402+ description = "Boulder ACME Init (MySQL)";
403403+ after = [ "mysql.service" ];
404404+ serviceConfig.Type = "oneshot";
405405+ serviceConfig.RemainAfterExit = true;
406406+ serviceConfig.WorkingDirectory = boulderSource;
407407+ path = commonPath;
408408+ script = "${pkgs.bash}/bin/sh test/create_db.sh";
409409+ };
410410+411411+ boulder-init-softhsm = {
412412+ description = "Boulder ACME Init (SoftHSM)";
413413+ environment.SOFTHSM_CONF = softHsmConf;
414414+ serviceConfig.Type = "oneshot";
415415+ serviceConfig.RemainAfterExit = true;
416416+ serviceConfig.WorkingDirectory = boulderSource;
417417+ preStart = "mkdir -p /var/lib/softhsm";
418418+ path = commonPath;
419419+ script = ''
420420+ softhsm --slot 0 --init-token \
421421+ --label intermediate --pin 5678 --so-pin 1234
422422+ softhsm --slot 0 --import test/test-ca.key \
423423+ --label intermediate_key --pin 5678 --id FB
424424+ softhsm --slot 1 --init-token \
425425+ --label root --pin 5678 --so-pin 1234
426426+ softhsm --slot 1 --import test/test-root.key \
427427+ --label root_key --pin 5678 --id FA
428428+ '';
429429+ };
430430+431431+ boulder = {
432432+ description = "Boulder ACME Server";
433433+ after = map (n: "${n}.service") (lib.attrNames componentServices);
434434+ wantedBy = [ "multi-user.target" ];
435435+ serviceConfig.Type = "oneshot";
436436+ serviceConfig.RemainAfterExit = true;
437437+ script = let
438438+ ports = lib.range 8000 8005 ++ lib.singleton 80;
439439+ netcat = "${pkgs.netcat-openbsd}/bin/nc";
440440+ mkPortCheck = port: "${netcat} -z 127.0.0.1 ${toString port}";
441441+ checks = "(${lib.concatMapStringsSep " && " mkPortCheck ports})";
442442+ in "while ! ${checks}; do :; done";
443443+ };
444444+ } // componentServices;
445445+ };
446446+}
+141
nixos/tests/common/resolver.nix
···11+# This module automatically discovers zones in BIND and NSD NixOS
22+# configurations and creates zones for all definitions of networking.extraHosts
33+# (except those that point to 127.0.0.1 or ::1) within the current test network
44+# and delegates these zones using a fake root zone served by a BIND recursive
55+# name server.
66+{ config, nodes, pkgs, lib, ... }:
77+88+{
99+ options.test-support.resolver.enable = lib.mkOption {
1010+ type = lib.types.bool;
1111+ default = true;
1212+ internal = true;
1313+ description = ''
1414+ Whether to enable the resolver that automatically discovers zone in the
1515+ test network.
1616+1717+ This option is <literal>true</literal> by default, because the module
1818+ defining this option needs to be explicitly imported.
1919+2020+ The reason this option exists is for the
2121+ <filename>nixos/tests/common/letsencrypt.nix</filename> module, which
2222+ needs that option to disable the resolver once the user has set its own
2323+ resolver.
2424+ '';
2525+ };
2626+2727+ config = lib.mkIf config.test-support.resolver.enable {
2828+ networking.firewall.enable = false;
2929+ services.bind.enable = true;
3030+ services.bind.cacheNetworks = lib.mkForce [ "any" ];
3131+ services.bind.forwarders = lib.mkForce [];
3232+ services.bind.zones = lib.singleton {
3333+ name = ".";
3434+ file = let
3535+ addDot = zone: zone + lib.optionalString (!lib.hasSuffix "." zone) ".";
3636+ mkNsdZoneNames = zones: map addDot (lib.attrNames zones);
3737+ mkBindZoneNames = zones: map (zone: addDot zone.name) zones;
3838+ getZones = cfg: mkNsdZoneNames cfg.services.nsd.zones
3939+ ++ mkBindZoneNames cfg.services.bind.zones;
4040+4141+ getZonesForNode = attrs: {
4242+ ip = attrs.config.networking.primaryIPAddress;
4343+ zones = lib.filter (zone: zone != ".") (getZones attrs.config);
4444+ };
4545+4646+ zoneInfo = lib.mapAttrsToList (lib.const getZonesForNode) nodes;
4747+4848+ # A and AAAA resource records for all the definitions of
4949+ # networking.extraHosts except those for 127.0.0.1 or ::1.
5050+ #
5151+ # The result is an attribute set with keys being the host name and the
5252+ # values are either { ipv4 = ADDR; } or { ipv6 = ADDR; } where ADDR is
5353+ # the IP address for the corresponding key.
5454+ recordsFromExtraHosts = let
5555+ getHostsForNode = lib.const (n: n.config.networking.extraHosts);
5656+ allHostsList = lib.mapAttrsToList getHostsForNode nodes;
5757+ allHosts = lib.concatStringsSep "\n" allHostsList;
5858+5959+ reIp = "[a-fA-F0-9.:]+";
6060+ reHost = "[a-zA-Z0-9.-]+";
6161+6262+ matchAliases = str: let
6363+ matched = builtins.match "[ \t]+(${reHost})(.*)" str;
6464+ continue = lib.singleton (lib.head matched)
6565+ ++ matchAliases (lib.last matched);
6666+ in if matched == null then [] else continue;
6767+6868+ matchLine = str: let
6969+ result = builtins.match "[ \t]*(${reIp})[ \t]+(${reHost})(.*)" str;
7070+ in if result == null then null else {
7171+ ipAddr = lib.head result;
7272+ hosts = lib.singleton (lib.elemAt result 1)
7373+ ++ matchAliases (lib.last result);
7474+ };
7575+7676+ skipLine = str: let
7777+ rest = builtins.match "[^\n]*\n(.*)" str;
7878+ in if rest == null then "" else lib.head rest;
7979+8080+ getEntries = str: acc: let
8181+ result = matchLine str;
8282+ next = getEntries (skipLine str);
8383+ newEntry = acc ++ lib.singleton result;
8484+ continue = if result == null then next acc else next newEntry;
8585+ in if str == "" then acc else continue;
8686+8787+ isIPv6 = str: builtins.match ".*:.*" str != null;
8888+ loopbackIps = [ "127.0.0.1" "::1" ];
8989+ filterLoopback = lib.filter (e: !lib.elem e.ipAddr loopbackIps);
9090+9191+ allEntries = lib.concatMap (entry: map (host: {
9292+ inherit host;
9393+ ${if isIPv6 entry.ipAddr then "ipv6" else "ipv4"} = entry.ipAddr;
9494+ }) entry.hosts) (filterLoopback (getEntries (allHosts + "\n") []));
9595+9696+ mkRecords = entry: let
9797+ records = lib.optional (entry ? ipv6) "AAAA ${entry.ipv6}"
9898+ ++ lib.optional (entry ? ipv4) "A ${entry.ipv4}";
9999+ mkRecord = typeAndData: "${entry.host}. IN ${typeAndData}";
100100+ in lib.concatMapStringsSep "\n" mkRecord records;
101101+102102+ in lib.concatMapStringsSep "\n" mkRecords allEntries;
103103+104104+ # All of the zones that are subdomains of existing zones.
105105+ # For example if there is only "example.com" the following zones would
106106+ # be 'subZones':
107107+ #
108108+ # * foo.example.com.
109109+ # * bar.example.com.
110110+ #
111111+ # While the following would *not* be 'subZones':
112112+ #
113113+ # * example.com.
114114+ # * com.
115115+ #
116116+ subZones = let
117117+ allZones = lib.concatMap (zi: zi.zones) zoneInfo;
118118+ isSubZoneOf = z1: z2: lib.hasSuffix z2 z1 && z1 != z2;
119119+ in lib.filter (z: lib.any (isSubZoneOf z) allZones) allZones;
120120+121121+ # All the zones without 'subZones'.
122122+ filteredZoneInfo = map (zi: zi // {
123123+ zones = lib.filter (x: !lib.elem x subZones) zi.zones;
124124+ }) zoneInfo;
125125+126126+ in pkgs.writeText "fake-root.zone" ''
127127+ $TTL 3600
128128+ . IN SOA ns.fakedns. admin.fakedns. ( 1 3h 1h 1w 1d )
129129+ ns.fakedns. IN A ${config.networking.primaryIPAddress}
130130+ . IN NS ns.fakedns.
131131+ ${lib.concatImapStrings (num: { ip, zones }: ''
132132+ ns${toString num}.fakedns. IN A ${ip}
133133+ ${lib.concatMapStrings (zone: ''
134134+ ${zone} IN NS ns${toString num}.fakedns.
135135+ '') zones}
136136+ '') (lib.filter (zi: zi.zones != []) filteredZoneInfo)}
137137+ ${recordsFromExtraHosts}
138138+ '';
139139+ };
140140+ };
141141+}
+5-4
pkgs/applications/altcoins/go-ethereum.nix
···2233buildGoPackage rec {
44 name = "go-ethereum-${version}";
55- version = "1.6.7";
55+ version = "1.7.0";
66 goPackagePath = "github.com/ethereum/go-ethereum";
7788 # Fixes Cgo related build failures (see https://github.com/NixOS/nixpkgs/issues/25959 )
···1212 owner = "ethereum";
1313 repo = "go-ethereum";
1414 rev = "v${version}";
1515- sha256 = "19cq0pmif4y33v34jzvam4mcszl8vf2saf2gzfz01l4x1iv4hf1r";
1515+ sha256 = "0ybjaiyrfb320rab6a5r9iiqvkrcd8b2qvixzx0kjmc4a7l1q5zh";
1616 };
17171818 # Fix cyclic referencing on Darwin
···2323 done
2424 '';
25252626- meta = {
2626+ meta = with stdenv.lib; {
2727 homepage = https://ethereum.github.io/go-ethereum/;
2828 description = "Official golang implementation of the Ethereum protocol";
2929- license = with lib.licenses; [ lgpl3 gpl3 ];
2929+ license = with licenses; [ lgpl3 gpl3 ];
3030+ maintainers = [ maintainers.adisbladis ];
3031 };
3132}
···11-{ stdenv, fetchurl, buildPythonApplication, tempita, jinja2, pyyaml, clepy, mock
22-, nose, decorator, docutils
33-}:
44-55-# TODO: pitz has a pitz-shell utility that depends on ipython, but it just
66-# errors out and dies (it probably depends on an old ipython version):
77-#
88-# from IPython.Shell import IPShellEmbed
99-# ImportError: No module named Shell
1010-#
1111-# pitz-shell is not the primary interface, so it is not critical to have it
1212-# working. Concider fixing pitz upstream.
1313-1414-buildPythonApplication rec {
1515- name = "pitz-1.2.4";
1616- namePrefix = "";
1717-1818- src = fetchurl {
1919- url = "mirror://pypi/p/pitz/${name}.tar.gz";
2020- sha256 = "1k7f3h4acllzqy3mjqnjd4w5jskp03s79b7dx3c85vlmd7824smr";
2121- };
2222-2323- # propagatedBuildInputs is needed for pitz to find its dependencies at
2424- # runtime. If we use buildInputs it would just build, not run.
2525- propagatedBuildInputs = [ tempita jinja2 pyyaml clepy mock nose decorator docutils ];
2626-2727- meta = with stdenv.lib; {
2828- description = "Distributed bugtracker";
2929- license = licenses.bsd3;
3030- homepage = http://pitz.tplus1.com/;
3131- platforms = platforms.linux;
3232- maintainers = [ maintainers.bjornfor ];
3333- };
3434-}
···4455{ buildPackages, runCommand, lib }:
6677-{ name
77+lib.makeOverridable
88+({ name
89910, # The manifest file (if any). A symlink $out/manifest will be
1011 # created to it.
···6869 ''
6970 ${buildPackages.perl}/bin/perl -w ${./builder.pl}
7071 eval "$postBuild"
7171- ''
7272+ '')
···2626 };
27272828 files = builtins.filter (n: n != "default") (pkgs.lib.mapAttrsToList (name: type: let
2929- m = builtins.match "(.*)\.nix" name;
2929+ m = builtins.match "(.*)\\.nix" name;
3030 in if m == null then "default" else builtins.head m) (builtins.readDir ./.));
3131 in (builtins.listToAttrs (map (name: {
3232 inherit name;
···11-WGET_ARGS=( https://download.kde.org/stable/frameworks/5.37/ -A '*.tar.xz' )
11+WGET_ARGS=( https://download.kde.org/stable/frameworks/5.38/ -A '*.tar.xz' )
···11+{ stdenv, buildPythonPackage, fetchPypi, isPyPy, isPy35, ncurses }:
22+33+buildPythonPackage rec {
44+ pname = "cx_Freeze";
55+ version = "5.0.2";
66+ name = "${pname}-${version}";
77+88+ src = fetchPypi {
99+ inherit pname version;
1010+ sha256 = "0zbx9j5z5l06bvwvlqvvn7h9dm7zjcjgxm7agbb625nymkq6cd15";
1111+ };
1212+1313+ propagatedBuildInputs = [ ncurses ];
1414+1515+ # timestamp need to come after 1980 for zipfiles and nix store is set to epoch
1616+ prePatch = ''
1717+ substituteInPlace cx_Freeze/freezer.py --replace "os.stat(module.file).st_mtime" "time.time()"
1818+ '';
1919+2020+ # fails to find Console even though it exists on python 3.x
2121+ doCheck = false;
2222+2323+ meta = with stdenv.lib; {
2424+ description = "A set of scripts and modules for freezing Python scripts into executables";
2525+ homepage = "http://cx-freeze.sourceforge.net/";
2626+ license = licenses.psfl;
2727+ };
2828+}
+21
pkgs/development/python-modules/ijson/default.nix
···11+{ stdenv, buildPythonPackage, fetchPypi }:
22+33+buildPythonPackage rec {
44+ name = "${pname}-${version}";
55+ pname = "ijson";
66+ version = "2.3";
77+88+ src = fetchPypi {
99+ inherit pname version;
1010+ sha256 = "0x7l9k2dvxzd5mjgiq15nl9b0sxcqy1cqaz744bjwkz4z5mrypzg";
1111+ };
1212+1313+ doCheck = false; # something about yajl
1414+1515+ meta = with stdenv.lib; {
1616+ description = "Iterative JSON parser with a standard Python iterator interface";
1717+ homepage = "https://github.com/isagalaev/ijson";
1818+ license = licenses.bsd3;
1919+ maintainers = with maintainers; [ rvl ];
2020+ };
2121+}
+7-12
pkgs/development/python-modules/jedi/default.nix
···11-{ lib
22-, buildPythonPackage
33-, fetchPypi
44-, pytest
55-, glibcLocales
66-}:
11+{ stdenv, buildPythonPackage, fetchPypi, pytest, glibcLocales, tox, pytestcov }:
7283buildPythonPackage rec {
94 pname = "jedi";
···1510 sha256 = "7abb618cac6470ebbd142e59c23daec5e6e063bfcecc8a43a037d2ab57276f4e";
1611 };
17121818- checkInputs = [ pytest glibcLocales ];
1313+ checkInputs = [ pytest glibcLocales tox pytestcov ];
19142015 checkPhase = ''
2116 LC_ALL="en_US.UTF-8" py.test test
2217 '';
23182424- # 7 failed
2525- #doCheck = false;
1919+ # tox required for tests: https://github.com/davidhalter/jedi/issues/808
2020+ doCheck = false;
26212727- meta = {
2222+ meta = with stdenv.lib; {
2823 homepage = https://github.com/davidhalter/jedi;
2924 description = "An autocompletion tool for Python that can be used for text editors";
3030- license = lib.licenses.lgpl3Plus;
3131- maintainers = with lib.maintainers; [ garbas ];
2525+ license = licenses.lgpl3Plus;
2626+ maintainers = with maintainers; [ garbas ];
3227 };
3328}
+25
pkgs/development/python-modules/mdp/default.nix
···11+{ stdenv, buildPythonPackage, fetchPypi, pytest_29, future, numpy }:
22+33+buildPythonPackage rec {
44+ pname = "MDP";
55+ version = "3.5";
66+ name = "${pname}-${version}";
77+88+ src = fetchPypi {
99+ inherit pname version;
1010+ sha256 = "0aw1zxmyvx6gfmmnixbqmdaah28jl7rmqkzhxv53091asc23iw9k";
1111+ };
1212+1313+ checkInputs = [ pytest_29 ];
1414+ propagatedBuildInputs = [ future numpy ];
1515+1616+ # Tests disabled because of missing dependencies not in nix
1717+ doCheck = false;
1818+1919+ meta = with stdenv.lib; {
2020+ description = "Library for building complex data processing software by combining widely used machine learning algorithms";
2121+ homepage = http://mdp-toolkit.sourceforge.net;
2222+ license = licenses.bsd3;
2323+ maintainers = with maintainers; [ nico202 ];
2424+ };
2525+}
+32
pkgs/development/python-modules/moto/default.nix
···11+{ stdenv, buildPythonPackage, fetchPypi, jinja2, werkzeug, flask, requests, pytz
22+, six, boto, httpretty, xmltodict, nose, sure, boto3, freezegun, dateutil }:
33+44+buildPythonPackage rec {
55+ pname = "moto";
66+ version = "0.4.31";
77+ name = "moto-${version}";
88+ src = fetchPypi {
99+ inherit pname version;
1010+ sha256 = "19s8hfz4mzzzdksa0ddlvrga5mxdaqahk89p5l29a5id8127shr8";
1111+ };
1212+1313+ propagatedBuildInputs = [
1414+ boto
1515+ dateutil
1616+ flask
1717+ httpretty
1818+ jinja2
1919+ pytz
2020+ werkzeug
2121+ requests
2222+ six
2323+ xmltodict
2424+ ];
2525+2626+ checkInputs = [ boto3 nose sure freezegun ];
2727+2828+ checkPhase = "nosetests";
2929+3030+ # TODO: make this true; I think lots of the tests want network access but we can probably run the others
3131+ doCheck = false;
3232+}
···4646 ExceptionHandling = [];
4747 FWAUserLib = [];
4848 ForceFeedback = [ CF IOKit ];
4949- Foundation = [ CF libobjc Security ApplicationServices SystemConfiguration ];
4949+ # cf-private was moved first in list because of https://github.com/NixOS/nixpkgs/pull/28635
5050+ Foundation = [ cf-private CF libobjc Security ApplicationServices SystemConfiguration ];
5051 GLKit = [ CF ];
5152 GLUT = [ OpenGL ];
5253 GSS = [];
+30
pkgs/os-specific/darwin/duti/default.nix
···11+{stdenv, lib, fetchFromGitHub, autoreconfHook, darwin}:
22+33+stdenv.mkDerivation rec {
44+ pname = "duti";
55+ name = "${pname}-${version}";
66+ version = "1.5.4pre";
77+ src = fetchFromGitHub {
88+ owner = "moretension";
99+ repo = pname;
1010+ rev = "7dbcae86f99fedef5a6c4311f032a0f1ca0539cc";
1111+ sha256 = "1z9sa0yk87vs57d5338y6lvm1v1vvynxb7dy1x5aqzkcr0imhljl";
1212+ };
1313+ nativeBuildInputs = [autoreconfHook];
1414+ buildInputs = [darwin.apple_sdk.frameworks.ApplicationServices];
1515+ configureFlags = ["--with-macosx-sdk=/homeless-shelter"];
1616+ meta = with lib; {
1717+ description = "A command-line tool to select default applications for document types and URL schemes on Mac OS X";
1818+ longDescription = ''
1919+ duti is a command-line utility capable of setting default applications for
2020+ various document types on Mac OS X, using Apple's Uniform Type Identifiers. A
2121+ UTI is a unique string describing the format of a file's content. For instance,
2222+ a Microsoft Word document has a UTI of com.microsoft.word.doc. Using duti, the
2323+ user can change which application acts as the default handler for a given UTI.
2424+ '';
2525+ maintainers = with maintainers; [matthewbauer];
2626+ platforms = platforms.darwin;
2727+ licenses = licenses.publicDomain;
2828+ homepage = "http://duti.org/";
2929+ };
3030+}
···6868SCHED_STACK_END_CHECK y
6969BUG_ON_DATA_CORRUPTION y
70707171+${optionalString (versionAtLeast version "4.13") ''
7272+ REFCOUNT_FULL y
7373+''}
7474+7175# Perform usercopy bounds checking.
7276HARDENED_USERCOPY y
7377···8993 GCC_PLUGIN_STRUCTLEAK y # A port of the PaX structleak plugin
9094''}
91959696+${optionalString (versionAtLeast version "4.13") ''
9797+ GCC_PLUGIN_RANDSTRUCT y # A port of the PaX randstruct plugin
9898+ GCC_PLUGIN_RANDSTRUCT_PERFORMANCE y
9999+''}
100100+92101# Disable various dangerous settings
93102ACPI_CUSTOM_METHOD n # Allows writing directly to physical memory
94103PROC_KCORE n # Exposes kernel text image layout
···97106# Use -fstack-protector-strong (gcc 4.9+) for best stack canary coverage.
98107CC_STACKPROTECTOR_REGULAR n
99108CC_STACKPROTECTOR_STRONG y
109109+110110+# Enable compile/run-time buffer overflow detection ala glibc's _FORTIFY_SOURCE
111111+${optionalString (versionAtLeast version "4.13") ''
112112+ FORTIFY_SOURCE y
113113+''}
100114''
···5050 # it's a directory, so the set of overlays from the directory, ordered lexicographically
5151 let content = readDir path; in
5252 map (n: import (path + ("/" + n)))
5353- (builtins.filter (n: builtins.match ".*\.nix" n != null || pathExists (path + ("/" + n + "/default.nix")))
5353+ (builtins.filter (n: builtins.match ".*\\.nix" n != null || pathExists (path + ("/" + n + "/default.nix")))
5454 (attrNames content))
5555 else
5656 # it's a file, so the result is the contents of the file itself