1{
2 lib,
3 stdenv,
4 fetchurl,
5 # native deps.
6 runCommand,
7 pkg-config,
8 meson,
9 ninja,
10 makeWrapper,
11 # build+runtime deps.
12 knot-dns,
13 luajitPackages,
14 libuv,
15 gnutls,
16 lmdb,
17 jemalloc,
18 systemd,
19 libcap_ng,
20 dns-root-data,
21 nghttp2, # optionals, in principle
22 fstrm,
23 protobufc, # more optionals
24 # test-only deps.
25 cmocka,
26 which,
27 cacert,
28 extraFeatures ? false, # catch-all if defaults aren't enough
29}:
30let
31 result = if extraFeatures then wrapped-full else unwrapped;
32
33 inherit (lib) optional optionals optionalString;
34 lua = luajitPackages;
35
36 unwrapped = stdenv.mkDerivation rec {
37 pname = "knot-resolver";
38 version = "5.7.6";
39
40 src = fetchurl {
41 url = "https://secure.nic.cz/files/knot-resolver/${pname}-${version}.tar.xz";
42 sha256 = "500ccd3a560300e547b8dc5aaff322f7c8e2e7d6f0d7ef5f36e59cb60504d674";
43 };
44
45 outputs = [
46 "out"
47 "dev"
48 ];
49
50 # Path fixups for the NixOS service.
51 postPatch = ''
52 patch meson.build <<EOF
53 @@ -50,2 +50,2 @@
54 -systemd_work_dir = prefix / get_option('localstatedir') / 'lib' / 'knot-resolver'
55 -systemd_cache_dir = prefix / get_option('localstatedir') / 'cache' / 'knot-resolver'
56 +systemd_work_dir = '/var/lib/knot-resolver'
57 +systemd_cache_dir = '/var/cache/knot-resolver'
58 EOF
59
60 # ExecStart can't be overwritten in overrides.
61 # We need that to use wrapped executable and correct config file.
62 sed '/^ExecStart=/d' -i systemd/kresd@.service.in
63
64 # On x86_64-darwin loading by soname fails to find the libs, surprisingly.
65 # Even though they should already be loaded and they're in RPATH, too.
66 for f in daemon/lua/{kres,zonefile}.lua; do
67 substituteInPlace "$f" \
68 --replace-fail "ffi.load(" "ffi.load('${lib.getLib knot-dns}/lib/' .. "
69 done
70 ''
71 # some tests have issues with network sandboxing, apparently
72 + optionalString doInstallCheck ''
73 echo 'os.exit(77)' > daemon/lua/trust_anchors.test/bootstrap.test.lua
74 sed -E '/^[[:blank:]]*test_(dstaddr|headers),?$/d' -i \
75 tests/config/doh2.test.lua modules/http/http_doh.test.lua
76 '';
77
78 preConfigure = ''
79 patchShebangs scripts/
80 '';
81
82 nativeBuildInputs = [
83 pkg-config
84 meson
85 ninja
86 ];
87
88 # http://knot-resolver.readthedocs.io/en/latest/build.html#requirements
89 buildInputs = [
90 knot-dns
91 lua.lua
92 libuv
93 gnutls
94 lmdb
95 ]
96 ## the rest are optional dependencies
97 ++ optionals stdenv.hostPlatform.isLinux [
98 # lib
99 systemd
100 libcap_ng
101 ]
102 ++ [
103 jemalloc
104 nghttp2
105 ]
106 ++ [
107 fstrm
108 protobufc
109 ] # dnstap support
110 ;
111
112 mesonFlags = [
113 "-Dkeyfile_default=${dns-root-data}/root.ds"
114 "-Droot_hints=${dns-root-data}/root.hints"
115 "-Dinstall_kresd_conf=disabled" # not really useful; examples are inside share/doc/
116 "-Dmalloc=jemalloc"
117 "--default-library=static" # not used by anyone
118 ]
119 ++ optional doInstallCheck "-Dunit_tests=enabled"
120 ++ optional doInstallCheck "-Dconfig_tests=enabled"
121 ++ optional stdenv.hostPlatform.isLinux "-Dsystemd_files=enabled" # used by NixOS service
122 #"-Dextra_tests=enabled" # not suitable as in-distro tests; many deps, too.
123 ;
124
125 postInstall = ''
126 rm "$out"/lib/libkres.a
127 rm "$out"/lib/knot-resolver/upgrade-4-to-5.lua # not meaningful on NixOS
128 ''
129 + optionalString stdenv.hostPlatform.isLinux ''
130 rm -r "$out"/lib/sysusers.d/ # ATM more likely to harm than help
131 '';
132
133 doInstallCheck = with stdenv; hostPlatform == buildPlatform;
134 nativeInstallCheckInputs = [
135 cmocka
136 which
137 cacert
138 lua.cqueues
139 lua.basexx
140 lua.http
141 ];
142 installCheckPhase = ''
143 meson test --print-errorlogs --no-suite snowflake
144 '';
145
146 meta = with lib; {
147 description = "Caching validating DNS resolver, from .cz domain registry";
148 homepage = "https://knot-resolver.cz";
149 license = licenses.gpl3Plus;
150 platforms = platforms.unix;
151 maintainers = [
152 maintainers.vcunat # upstream developer
153 ];
154 mainProgram = "kresd";
155 };
156 };
157
158 wrapped-full =
159 runCommand unwrapped.name
160 {
161 nativeBuildInputs = [ makeWrapper ];
162 buildInputs = with luajitPackages; [
163 # For http module, prefill module, trust anchor bootstrap.
164 # It brings lots of deps; some are useful elsewhere (e.g. cqueues).
165 http
166 # used by policy.slice_randomize_psl()
167 psl
168 ];
169 preferLocalBuild = true;
170 allowSubstitutes = false;
171 inherit (unwrapped) meta;
172 }
173 (
174 ''
175 mkdir -p "$out"/bin
176 makeWrapper '${unwrapped}/bin/kresd' "$out"/bin/kresd \
177 --set LUA_PATH "$LUA_PATH" \
178 --set LUA_CPATH "$LUA_CPATH"
179
180 ln -sr '${unwrapped}/share' "$out"/
181 ln -sr '${unwrapped}/lib' "$out"/ # useful in NixOS service
182 ln -sr "$out"/{bin,sbin}
183 ''
184 + lib.optionalString unwrapped.doInstallCheck ''
185 echo "Checking that 'http' module loads, i.e. lua search paths work:"
186 echo "modules.load('http')" > test-http.lua
187 echo -e 'quit()' | env -i "$out"/bin/kresd -a 127.0.0.1#53535 -c test-http.lua
188 ''
189 );
190
191in
192result