]> git.ipfire.org Git - thirdparty/pdns.git/blame - tasks.py
Merge pull request #13735 from rgacogne/ddist-coverity-20240123
[thirdparty/pdns.git] / tasks.py
CommitLineData
99bb3530
PD
1from invoke import task
2from invoke.exceptions import Failure, UnexpectedExit
3
7ec6fb65 4import os
99bb3530
PD
5import sys
6import time
7
7d862cb3
AR
8auth_backend_ip_addr = os.getenv('AUTH_BACKEND_IP_ADDR', '127.0.0.1')
9
10clang_version = os.getenv('CLANG_VERSION', '13')
3e5c7a76
RG
11quiche_version = '0.18.0'
12quiche_hash = 'eb242a14c4d801a90b57b6021dd29f7a62099f3a4d7a7ba889e105f8328e6c1f'
7d862cb3 13
99bb3530 14all_build_deps = [
d3cb00f9 15 'ccache',
99bb3530
PD
16 'libboost-all-dev',
17 'libluajit-5.1-dev',
18 'libsodium-dev',
b69425da 19 'libssl-dev', # This will install libssl 1.1 on Debian 11 and libssl3 on Debian 12
99bb3530
PD
20 'libsystemd-dev',
21 'libtool',
22 'make',
23 'pkg-config',
24 'python3-venv',
25 'systemd',
26]
27git_build_deps = [
28 'autoconf',
29 'automake',
30 'bison',
31 'bzip2',
32 'curl',
33 'flex',
34 'git',
35 'ragel'
36]
37auth_build_deps = [ # FIXME: perhaps we should be stealing these from the debian (Ubuntu) control file
38 'default-libmysqlclient-dev',
39 'libcdb-dev',
40 'libcurl4-openssl-dev',
41 'libgeoip-dev',
42 'libkrb5-dev',
43 'libldap2-dev',
44 'liblmdb-dev',
45 'libmaxminddb-dev',
46 'libp11-kit-dev',
47 'libpq-dev',
48 'libsqlite3-dev',
49 'libyaml-cpp-dev',
50 'libzmq3-dev',
51 'ruby-bundler',
52 'ruby-dev',
53 'sqlite3',
9f930bd7 54 'unixodbc-dev',
26cf02ca 55 'cmake',
99bb3530
PD
56]
57rec_build_deps = [
58 'libcap-dev',
59 'libfstrm-dev',
60 'libsnmp-dev',
61]
4467dd85
O
62rec_bulk_deps = [
63 'curl',
4467dd85
O
64 'libboost-all-dev',
65 'libcap2',
2b219e37
O
66 'libfstrm0',
67 'libluajit-5.1-2',
7d862cb3 68 '"libsnmp[1-9]+"',
2b219e37 69 'libsodium23',
4467dd85 70 'libsystemd0',
2b219e37
O
71 'moreutils',
72 'pdns-tools',
869fc2b5 73 'unzip',
4467dd85 74]
99bb3530
PD
75dnsdist_build_deps = [
76 'libcap-dev',
77 'libcdb-dev',
78 'libedit-dev',
79 'libfstrm-dev',
79e3404d 80 'libgnutls28-dev',
99bb3530
PD
81 'libh2o-evloop-dev',
82 'liblmdb-dev',
ff4c1303 83 'libnghttp2-dev',
99bb3530
PD
84 'libre2-dev',
85 'libsnmp-dev',
86]
87auth_test_deps = [ # FIXME: we should be generating some of these from shlibdeps in build
88 'authbind',
89 'bc',
90 'bind9utils',
91 'curl',
92 'default-jre-headless',
93 'dnsutils',
222d17e2 94 'faketime',
99bb3530 95 'gawk',
bb4f68fd 96 'krb5-user',
99bb3530 97 'ldnsutils',
7d862cb3 98 '"libboost-serialization1.7[1-9]+"',
99bb3530
PD
99 'libcdb1',
100 'libcurl4',
101 'libgeoip1',
102 'libkrb5-3',
b69425da 103 '"libldap-2.[1-9]+"',
99bb3530
PD
104 'liblmdb0',
105 'libluajit-5.1-2',
106 'libmaxminddb0',
107 'libnet-dns-perl',
108 'libp11-kit0',
109 'libpq5',
110 'libsodium23',
111 'libsqlite3-dev',
99bb3530 112 'libsystemd0',
b69425da 113 '"libyaml-cpp0.[1-9]+"',
99bb3530 114 'libzmq3-dev',
3a52d52f 115 'lmdb-utils',
7c05901b 116 'prometheus',
0e77de07
PD
117 'ruby-bundler',
118 'ruby-dev',
99bb3530
PD
119 'socat',
120 'softhsm2',
121 'unbound-host',
122 'unixodbc',
869fc2b5 123 'wget',
99bb3530 124]
e8d83f88
FM
125doc_deps = [
126 'autoconf',
127 'automake',
128 'bison',
129 'curl',
130 'flex',
131 'g++',
132 'git',
133 'latexmk',
134 'libboost-all-dev',
135 'libedit-dev',
136 'libluajit-5.1-dev',
137 'libssl-dev',
138 'make',
139 'pkg-config',
140 'python3-venv',
141 'ragel',
142 'rsync',
143]
144doc_deps_pdf = [
145 'texlive-binaries',
146 'texlive-formats-extra',
147 'texlive-latex-extra',
148]
99bb3530
PD
149
150@task
151def apt_fresh(c):
152 c.sudo('apt-get update')
699d088a 153 c.sudo('apt-get -y --allow-downgrades dist-upgrade')
99bb3530
PD
154
155@task
156def install_clang(c):
157 """
7d862cb3 158 install clang and llvm
99bb3530 159 """
7d862cb3 160 c.sudo(f'apt-get -y --no-install-recommends install clang-{clang_version} llvm-{clang_version}')
99bb3530 161
fae3e64c
FM
162@task
163def install_clang_tidy_tools(c):
7d862cb3 164 c.sudo(f'apt-get -y --no-install-recommends install clang-tidy-{clang_version} clang-tools-{clang_version} bear python3-yaml')
fae3e64c 165
99bb3530
PD
166@task
167def install_clang_runtime(c):
168 # this gives us the symbolizer, for symbols in asan/ubsan traces
7d862cb3 169 c.sudo(f'apt-get -y --no-install-recommends install clang-{clang_version}')
99bb3530 170
9883d3f9
OM
171@task
172def ci_install_rust(c, repo):
c0500b19 173 c.sudo(f'{repo}/builder-support/helpers/install_rust.sh')
9883d3f9 174
d1c1159f
FM
175def install_libdecaf(c, product):
176 c.run('git clone https://git.code.sf.net/p/ed448goldilocks/code /tmp/libdecaf')
177 with c.cd('/tmp/libdecaf'):
178 c.run('git checkout 41f349')
2ef73ca0 179 c.run(f'CC={get_c_compiler()} CXX={get_cxx_compiler()} '
9466b8e6 180 'cmake -B build '
d1c1159f
FM
181 '-DCMAKE_INSTALL_PREFIX=/usr/local '
182 '-DCMAKE_INSTALL_LIBDIR=lib '
183 '-DENABLE_STATIC=OFF '
184 '-DENABLE_TESTS=OFF '
185 '-DCMAKE_C_FLAGS="-Wno-sizeof-array-div -Wno-array-parameter" .')
186 c.run('make -C build')
187 c.run('sudo make -C build install')
188 c.sudo(f'mkdir -p /opt/{product}/libdecaf')
189 c.sudo(f'cp /usr/local/lib/libdecaf.so* /opt/{product}/libdecaf/.')
190
e8d83f88
FM
191@task
192def install_doc_deps(c):
699d088a 193 c.sudo('apt-get install -y ' + ' '.join(doc_deps))
e8d83f88
FM
194
195@task
196def install_doc_deps_pdf(c):
699d088a 197 c.sudo('apt-get install -y ' + ' '.join(doc_deps_pdf))
e8d83f88 198
99bb3530
PD
199@task
200def install_auth_build_deps(c):
699d088a 201 c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + auth_build_deps))
825560a1
RG
202 if os.getenv('DECAF_SUPPORT', 'no') == 'yes':
203 install_libdecaf(c, 'pdns-auth')
99bb3530 204
628a1dec
RG
205def is_coverage_enabled():
206 sanitizers = os.getenv('SANITIZERS')
207 if sanitizers:
208 sanitizers = sanitizers.split('+')
209 if 'tsan' in sanitizers:
210 return False
211 return os.getenv('COVERAGE') == 'yes'
212
7146a45a
RG
213def get_coverage():
214 return '--enable-coverage=clang' if is_coverage_enabled() else ''
215
628a1dec
RG
216@task
217def install_coverage_deps(c):
218 if is_coverage_enabled():
219 c.sudo(f'apt-get install -y --no-install-recommends llvm-{clang_version}')
220
221@task
222def generate_coverage_info(c, binary, outputDir):
223 if is_coverage_enabled():
224 version = os.getenv('BUILDER_VERSION')
225 c.run(f'llvm-profdata-{clang_version} merge -sparse -o {outputDir}/temp.profdata /tmp/code-*.profraw')
226 c.run(f'llvm-cov-{clang_version} export --format=lcov --ignore-filename-regex=\'^/usr/\' -instr-profile={outputDir}/temp.profdata -object {binary} > {outputDir}/coverage.lcov')
227 c.run(f'{outputDir}/.github/scripts/normalize_paths_in_coverage.py {outputDir} {version} {outputDir}/coverage.lcov {outputDir}/normalized_coverage.lcov')
228 c.run(f'mv {outputDir}/normalized_coverage.lcov {outputDir}/coverage.lcov')
229
99bb3530
PD
230def setup_authbind(c):
231 c.sudo('touch /etc/authbind/byport/53')
232 c.sudo('chmod 755 /etc/authbind/byport/53')
233
234auth_backend_test_deps = dict(
235 gsqlite3=['sqlite3'],
236 gmysql=['default-libmysqlclient-dev'],
237 gpgsql=['libpq-dev'],
0e77de07 238 lmdb=[],
b33a88da
PD
239 remote=[],
240 bind=[],
241 geoip=[],
242 lua2=[],
222d17e2 243 tinydns=[],
8af54cc6
AR
244 authpy=[],
245 godbc_sqlite3=['libsqliteodbc'],
c4a7e1df
AR
246 godbc_mssql=['freetds-bin','tdsodbc'],
247 ldap=[],
248 geoip_mmdb=[]
99bb3530
PD
249)
250
251@task(help={'backend': 'Backend to install test deps for, e.g. gsqlite3; can be repeated'}, iterable=['backend'], optional=['backend'])
252def install_auth_test_deps(c, backend): # FIXME: rename this, we do way more than apt-get
253 extra=[]
254 for b in backend:
255 extra.extend(auth_backend_test_deps[b])
7d862cb3 256 c.sudo('DEBIAN_FRONTEND=noninteractive apt-get -y install ' + ' '.join(extra+auth_test_deps))
99bb3530
PD
257
258 c.run('chmod +x /opt/pdns-auth/bin/* /opt/pdns-auth/sbin/*')
259 # c.run('''if [ ! -e $HOME/bin/jdnssec-verifyzone ]; then
260 # wget https://github.com/dblacka/jdnssec-tools/releases/download/0.14/jdnssec-tools-0.14.tar.gz
261 # tar xfz jdnssec-tools-0.14.tar.gz -C $HOME
262 # rm jdnssec-tools-0.14.tar.gz
263 # fi
264 # echo 'export PATH=$HOME/jdnssec-tools-0.14/bin:$PATH' >> $BASH_ENV''') # FIXME: why did this fail with no error?
222d17e2
PD
265 c.run('touch regression-tests/tests/verify-dnssec-zone/allow-missing regression-tests.nobackend/rectify-axfr/allow-missing') # FIXME: can this go?
266 # FIXME we may want to start a background recursor here to make ALIAS tests more robust
99bb3530
PD
267 setup_authbind(c)
268
825560a1
RG
269 if os.getenv('DECAF_SUPPORT', 'no') == 'yes':
270 # Copy libdecaf out
271 c.sudo('mkdir -p /usr/local/lib')
272 c.sudo('cp /opt/pdns-auth/libdecaf/libdecaf.so* /usr/local/lib/.')
d1c1159f 273
4467dd85
O
274@task
275def install_rec_bulk_deps(c): # FIXME: rename this, we do way more than apt-get
699d088a 276 c.sudo('apt-get --no-install-recommends -y install ' + ' '.join(rec_bulk_deps))
4467dd85
O
277 c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*')
278
99bb3530
PD
279@task
280def install_rec_test_deps(c): # FIXME: rename this, we do way more than apt-get
699d088a 281 c.sudo('apt-get --no-install-recommends install -y ' + ' '.join(rec_bulk_deps) + ' \
4467dd85
O
282 pdns-server pdns-backend-bind daemontools \
283 jq libfaketime lua-posix lua-socket bc authbind \
6b45d67b 284 python3-venv python3-dev default-libmysqlclient-dev libpq-dev \
4467dd85 285 protobuf-compiler snmpd prometheus')
99bb3530
PD
286
287 c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*')
288
289 setup_authbind(c)
290
6b45d67b 291 c.run('sed "s/agentxperms 0700 0755 recursor/agentxperms 0777 0755/g" regression-tests.recursor-dnssec/snmpd.conf | sudo tee /etc/snmp/snmpd.conf')
7d862cb3 292 c.sudo('/etc/init.d/snmpd restart')
6b45d67b
O
293 time.sleep(5)
294 c.sudo('chmod 755 /var/agentx')
295
99bb3530
PD
296@task
297def install_dnsdist_test_deps(c): # FIXME: rename this, we do way more than apt-get
699d088a 298 c.sudo('apt-get install -y \
99bb3530
PD
299 libluajit-5.1-2 \
300 libboost-all-dev \
301 libcap2 \
302 libcdb1 \
303 libcurl4-openssl-dev \
304 libfstrm0 \
79e3404d 305 libgnutls30 \
99bb3530
PD
306 libh2o-evloop0.13 \
307 liblmdb0 \
ff4c1303 308 libnghttp2-14 \
7d862cb3 309 "libre2-[1-9]+" \
99bb3530
PD
310 libssl-dev \
311 libsystemd0 \
312 libsodium23 \
74a2ea87 313 lua-socket \
99bb3530
PD
314 patch \
315 protobuf-compiler \
316 python3-venv snmpd prometheus')
317 c.run('sed "s/agentxperms 0700 0755 dnsdist/agentxperms 0777 0755/g" regression-tests.dnsdist/snmpd.conf | sudo tee /etc/snmp/snmpd.conf')
7d862cb3 318 c.sudo('/etc/init.d/snmpd restart')
99bb3530
PD
319 time.sleep(5)
320 c.sudo('chmod 755 /var/agentx')
321
322@task
323def install_rec_build_deps(c):
699d088a 324 c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + rec_build_deps))
99bb3530
PD
325
326@task
327def install_dnsdist_build_deps(c):
699d088a 328 c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + dnsdist_build_deps))
99bb3530
PD
329
330@task
331def ci_autoconf(c):
e917c86b 332 c.run('autoreconf -vfi')
99bb3530 333
fdcc46e4
OM
334@task
335def ci_docs_rec_generate(c):
336 c.run('python3 generate.py')
337
e8d83f88
FM
338@task
339def ci_docs_build(c):
340 c.run('make -f Makefile.sphinx -C docs html')
341
342@task
343def ci_docs_build_pdf(c):
344 c.run('make -f Makefile.sphinx -C docs latexpdf')
345
346@task
e0ec64f1 347def ci_docs_upload_master(c, docs_host, pdf, username, product, directory=""):
5d9b131b
FM
348 rsync_cmd = " ".join([
349 "rsync",
350 "--checksum",
351 "--recursive",
352 "--verbose",
353 "--no-p",
354 "--chmod=g=rwX",
355 "--exclude '*~'",
356 ])
357 c.run(f"{rsync_cmd} --delete ./docs/_build/{product}-html-docs/ {username}@{docs_host}:{directory}")
358 c.run(f"{rsync_cmd} ./docs/_build/{product}-html-docs.tar.bz2 {username}@{docs_host}:{directory}/html-docs.tar.bz2")
359 c.run(f"{rsync_cmd} ./docs/_build/latex/{pdf} {username}@{docs_host}:{directory}")
e8d83f88
FM
360
361@task
362def ci_docs_add_ssh(c, ssh_key, host_key):
363 c.run('mkdir -m 700 -p ~/.ssh')
364 c.run(f'echo "{ssh_key}" > ~/.ssh/id_ed25519')
365 c.run('chmod 600 ~/.ssh/id_ed25519')
366 c.run(f'echo "{host_key}" > ~/.ssh/known_hosts')
367
8804bc1d
FM
368
369def get_sanitizers():
35859c0b 370 sanitizers = os.getenv('SANITIZERS', '')
8804bc1d
FM
371 if sanitizers != '':
372 sanitizers = sanitizers.split('+')
373 sanitizers = ['--enable-' + sanitizer for sanitizer in sanitizers]
374 sanitizers = ' '.join(sanitizers)
375 return sanitizers
376
7146a45a
RG
377def get_unit_tests(auth=False):
378 if os.getenv('UNIT_TESTS') != 'yes':
379 return ''
380 return '--enable-unit-tests --enable-backend-unit-tests' if auth else '--enable-unit-tests'
381
382def get_build_concurrency(default=8):
383 return os.getenv('CONCURRENCY', default)
384
385def get_fuzzing_targets():
386 return '--enable-fuzz-targets' if os.getenv('FUZZING_TARGETS') == 'yes' else ''
387
388def is_compiler_clang():
c6034e81 389 compiler = os.getenv('COMPILER', 'clang')
7146a45a
RG
390 return compiler == 'clang'
391
392def get_c_compiler():
393 return f'clang-{clang_version}' if is_compiler_clang() else 'gcc'
2ef73ca0
RG
394
395def get_cxx_compiler():
7146a45a 396 return f'clang++-{clang_version}' if is_compiler_clang() else 'g++'
2ef73ca0
RG
397
398def get_optimizations():
472404b9
RG
399 optimizations = os.getenv('OPTIMIZATIONS', 'yes')
400 return '-O1' if optimizations == 'yes' else '-O0'
8804bc1d
FM
401
402def get_cflags():
403 return " ".join([
2ef73ca0 404 get_optimizations(),
8804bc1d
FM
405 "-Werror=vla",
406 "-Werror=shadow",
407 "-Wformat=2",
408 "-Werror=format-security",
11c5018a
RG
409 "-fstack-clash-protection",
410 "-fstack-protector-strong",
411 "-fcf-protection=full",
7146a45a 412 "-Werror=string-plus-int" if is_compiler_clang() else '',
8804bc1d
FM
413 ])
414
415
416def get_cxxflags():
417 return " ".join([
418 get_cflags(),
419 "-Wp,-D_GLIBCXX_ASSERTIONS",
420 ])
421
422
7146a45a
RG
423def get_base_configure_cmd(additional_c_flags='', additional_cxx_flags='', enable_systemd=True, enable_sodium=True):
424 cflags = " ".join([get_cflags(), additional_c_flags])
425 cxxflags = " ".join([get_cxxflags(), additional_cxx_flags])
8804bc1d 426 return " ".join([
7146a45a
RG
427 f'CFLAGS="{cflags}"',
428 f'CXXFLAGS="{cxxflags}"',
8804bc1d 429 './configure',
2ef73ca0
RG
430 f"CC='{get_c_compiler()}'",
431 f"CXX='{get_cxx_compiler()}'",
8804bc1d 432 "--enable-option-checking=fatal",
7146a45a
RG
433 "--enable-systemd" if enable_systemd else '',
434 "--with-libsodium" if enable_sodium else '',
8804bc1d
FM
435 "--enable-fortify-source=auto",
436 "--enable-auto-var-init=pattern",
7146a45a
RG
437 get_coverage(),
438 get_sanitizers()
8804bc1d
FM
439 ])
440
441
99bb3530
PD
442@task
443def ci_auth_configure(c):
7146a45a
RG
444 unittests = get_unit_tests(True)
445 fuzz_targets = get_fuzzing_targets()
8804bc1d
FM
446 modules = " ".join([
447 "bind",
448 "geoip",
449 "gmysql",
450 "godbc",
451 "gpgsql",
452 "gsqlite3",
453 "ldap",
454 "lmdb",
455 "lua2",
456 "pipe",
457 "remote",
458 "tinydns",
459 ])
460 configure_cmd = " ".join([
461 get_base_configure_cmd(),
462 "LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib'",
463 f"--with-modules='{modules}'",
464 "--enable-tools",
2ef73ca0 465 "--enable-dns-over-tls",
8804bc1d
FM
466 "--enable-experimental-pkcs11",
467 "--enable-experimental-gss-tsig",
468 "--enable-remotebackend-zeromq",
469 "--with-lmdb=/usr",
825560a1 470 "--with-libdecaf" if os.getenv('DECAF_SUPPORT', 'no') == 'yes' else '',
8804bc1d
FM
471 "--prefix=/opt/pdns-auth",
472 "--enable-ixfrdist",
8804bc1d 473 unittests,
7146a45a 474 fuzz_targets
8804bc1d
FM
475 ])
476 res = c.run(configure_cmd, warn=True)
99bb3530
PD
477 if res.exited != 0:
478 c.run('cat config.log')
479 raise UnexpectedExit(res)
8804bc1d
FM
480
481
99bb3530
PD
482@task
483def ci_rec_configure(c):
7146a45a 484 unittests = get_unit_tests()
8804bc1d
FM
485
486 configure_cmd = " ".join([
487 get_base_configure_cmd(),
488 "--enable-nod",
489 "--prefix=/opt/pdns-recursor",
490 "--with-lua=luajit",
491 "--with-libcap",
492 "--with-net-snmp",
493 "--enable-dns-over-tls",
8804bc1d
FM
494 unittests,
495 ])
496 res = c.run(configure_cmd, warn=True)
99bb3530
PD
497 if res.exited != 0:
498 c.run('cat config.log')
499 raise UnexpectedExit(res)
500
8804bc1d 501
99bb3530 502@task
e3d6cf05
RG
503def ci_dnsdist_configure(c, features):
504 additional_flags = ''
505 if features == 'full':
506 features_set = '--enable-dnstap \
507 --enable-dnscrypt \
508 --enable-dns-over-tls \
509 --enable-dns-over-https \
3e5c7a76 510 --enable-dns-over-quic \
d1f77ae6 511 --enable-dns-over-http3 \
e3d6cf05
RG
512 --enable-systemd \
513 --prefix=/opt/dnsdist \
514 --with-gnutls \
f31d8bad 515 --with-h2o \
e3d6cf05
RG
516 --with-libsodium \
517 --with-lua=luajit \
518 --with-libcap \
d5d26f84 519 --with-net-snmp \
e3d6cf05 520 --with-nghttp2 \
7146a45a 521 --with-re2'
e3d6cf05
RG
522 else:
523 features_set = '--disable-dnstap \
524 --disable-dnscrypt \
525 --disable-ipcipher \
526 --disable-systemd \
527 --without-cdb \
528 --without-ebpf \
529 --without-gnutls \
f31d8bad 530 --without-h2o \
e3d6cf05
RG
531 --without-libedit \
532 --without-libsodium \
533 --without-lmdb \
534 --without-net-snmp \
6135a84e 535 --without-nghttp2 \
7146a45a 536 --without-re2'
e3d6cf05 537 additional_flags = '-DDISABLE_COMPLETION \
6b6f0aa6
RG
538 -DDISABLE_DELAY_PIPE \
539 -DDISABLE_DYNBLOCKS \
e3d6cf05
RG
540 -DDISABLE_PROMETHEUS \
541 -DDISABLE_PROTOBUF \
542 -DDISABLE_BUILTIN_HTML \
543 -DDISABLE_CARBON \
544 -DDISABLE_SECPOLL \
545 -DDISABLE_DEPRECATED_DYNBLOCK \
546 -DDISABLE_LUA_WEB_HANDLERS \
547 -DDISABLE_NON_FFI_DQ_BINDINGS \
548 -DDISABLE_POLICIES_BINDINGS \
549 -DDISABLE_PACKETCACHE_BINDINGS \
550 -DDISABLE_DOWNSTREAM_BINDINGS \
551 -DDISABLE_COMBO_ADDR_BINDINGS \
552 -DDISABLE_CLIENT_STATE_BINDINGS \
553 -DDISABLE_QPS_LIMITER_BINDINGS \
554 -DDISABLE_SUFFIX_MATCH_BINDINGS \
555 -DDISABLE_NETMASK_BINDINGS \
556 -DDISABLE_DNSNAME_BINDINGS \
557 -DDISABLE_DNSHEADER_BINDINGS \
558 -DDISABLE_RECVMMSG \
85241b78 559 -DDISABLE_WEB_CACHE_MANAGEMENT \
e3d6cf05
RG
560 -DDISABLE_WEB_CONFIG \
561 -DDISABLE_RULES_ALTERING_QUERIES \
562 -DDISABLE_ECS_ACTIONS \
dbefe674
RG
563 -DDISABLE_TOP_N_BINDINGS \
564 -DDISABLE_OCSP_STAPLING \
565 -DDISABLE_HASHED_CREDENTIALS \
566 -DDISABLE_FALSE_SHARING_PADDING \
567 -DDISABLE_NPN'
7146a45a
RG
568 unittests = get_unit_tests()
569 fuzztargets = get_fuzzing_targets()
570 tools = f'''AR=llvm-ar-{clang_version} RANLIB=llvm-ranlib-{clang_version}''' if is_compiler_clang() else ''
571 configure_cmd = " ".join([
572 tools,
573 get_base_configure_cmd(additional_c_flags='', additional_cxx_flags=additional_flags, enable_systemd=False, enable_sodium=False),
574 features_set,
575 unittests,
576 fuzztargets,
577 ' --enable-lto=thin',
578 '--prefix=/opt/dnsdist'
579 ])
580
581 res = c.run(configure_cmd, warn=True)
99bb3530
PD
582 if res.exited != 0:
583 c.run('cat config.log')
584 raise UnexpectedExit(res)
585
586@task
587def ci_auth_make(c):
7146a45a 588 c.run(f'make -j{get_build_concurrency()} -k V=1')
99bb3530 589
fae3e64c
FM
590@task
591def ci_auth_make_bear(c):
7146a45a 592 c.run(f'bear --append -- make -j{get_build_concurrency()} -k V=1')
fae3e64c 593
99bb3530
PD
594@task
595def ci_rec_make(c):
7146a45a 596 c.run(f'make -j{get_build_concurrency()} -k V=1')
99bb3530 597
f01e3a4a
FM
598@task
599def ci_rec_make_bear(c):
600 # Assumed to be running under ./pdns/recursordist/
7146a45a 601 c.run(f'bear --append -- make -j{get_build_concurrency()} -k V=1')
f01e3a4a 602
99bb3530
PD
603@task
604def ci_dnsdist_make(c):
7146a45a 605 c.run(f'make -j{get_build_concurrency(4)} -k V=1')
99bb3530 606
97145bb4
FM
607@task
608def ci_dnsdist_make_bear(c):
609 # Assumed to be running under ./pdns/dnsdistdist/
7146a45a 610 c.run(f'bear --append -- make -j{get_build_concurrency(4)} -k V=1')
97145bb4 611
99bb3530 612@task
e55d3a4b 613def ci_auth_install_remotebackend_test_deps(c):
99bb3530 614 with c.cd('modules/remotebackend'):
0e77de07
PD
615 # c.run('bundle config set path vendor/bundle')
616 c.run('sudo ruby -S bundle install')
699d088a 617 c.sudo('apt-get install -y socat')
99bb3530
PD
618
619@task
620def ci_auth_run_unit_tests(c):
621 res = c.run('make check', warn=True)
622 if res.exited != 0:
222d17e2
PD
623 c.run('cat pdns/test-suite.log', warn=True)
624 c.run('cat modules/remotebackend/test-suite.log', warn=True)
99bb3530
PD
625 raise UnexpectedExit(res)
626
627@task
628def ci_rec_run_unit_tests(c):
629 res = c.run('make check', warn=True)
630 if res.exited != 0:
631 c.run('cat test-suite.log')
632 raise UnexpectedExit(res)
633
634@task
635def ci_dnsdist_run_unit_tests(c):
636 res = c.run('make check', warn=True)
637 if res.exited != 0:
638 c.run('cat test-suite.log')
639 raise UnexpectedExit(res)
640
e917c86b
AR
641@task
642def ci_make_distdir(c):
643 res = c.run('make distdir')
644
99bb3530
PD
645@task
646def ci_make_install(c):
647 res = c.run('make install') # FIXME: this builds auth docs - again
648
649@task
7d862cb3 650def add_auth_repo(c, dist_name, dist_release_name, pdns_repo_version):
699d088a 651 c.sudo('apt-get install -y curl gnupg2')
7d862cb3 652 if pdns_repo_version == 'master':
99bb3530
PD
653 c.sudo('curl -s -o /etc/apt/trusted.gpg.d/pdns-repo.asc https://repo.powerdns.com/CBC8B383-pub.asc')
654 else:
655 c.sudo('curl -s -o /etc/apt/trusted.gpg.d/pdns-repo.asc https://repo.powerdns.com/FD380FBB-pub.asc')
7d862cb3 656 c.run(f"echo 'deb [arch=amd64] http://repo.powerdns.com/{dist_name} {dist_release_name}-auth-{pdns_repo_version} main' | sudo tee /etc/apt/sources.list.d/pdns.list")
99bb3530
PD
657 c.run("echo 'Package: pdns-*' | sudo tee /etc/apt/preferences.d/pdns")
658 c.run("echo 'Pin: origin repo.powerdns.com' | sudo tee -a /etc/apt/preferences.d/pdns")
659 c.run("echo 'Pin-Priority: 600' | sudo tee -a /etc/apt/preferences.d/pdns")
660 c.sudo('apt-get update')
661
662@task
663def test_api(c, product, backend=''):
664 if product == 'recursor':
665 with c.cd('regression-tests.api'):
666 c.run(f'PDNSRECURSOR=/opt/pdns-recursor/sbin/pdns_recursor ./runtests recursor {backend}')
667 elif product == 'auth':
668 with c.cd('regression-tests.api'):
7d862cb3 669 c.run(f'PDNSSERVER=/opt/pdns-auth/sbin/pdns_server PDNSUTIL=/opt/pdns-auth/bin/pdnsutil SDIG=/opt/pdns-auth/bin/sdig MYSQL_HOST={auth_backend_ip_addr} PGHOST={auth_backend_ip_addr} PGPORT=5432 ./runtests authoritative {backend}')
99bb3530
PD
670 else:
671 raise Failure('unknown product')
672
0e77de07 673backend_regress_tests = dict(
b33a88da 674 bind = [
8af54cc6
AR
675 'bind-both',
676 'bind-dnssec-both',
677 'bind-dnssec-nsec3-both',
678 'bind-dnssec-nsec3-optout-both',
679 'bind-dnssec-nsec3-narrow',
57d9ffa8 680 'bind-dnssec-pkcs11'
b33a88da
PD
681 ],
682 geoip = [
8af54cc6
AR
683 'geoip',
684 'geoip-nsec3-narrow'
b33a88da 685 ],
8af54cc6
AR
686 lua2 = ['lua2', 'lua2-dnssec'],
687 tinydns = ['tinydns'],
b33a88da 688 remote = [
8af54cc6
AR
689 'remotebackend-pipe',
690 'remotebackend-unix',
691 'remotebackend-http',
692 'remotebackend-zeromq',
693 'remotebackend-pipe-dnssec',
694 'remotebackend-unix-dnssec',
695 'remotebackend-http-dnssec',
696 'remotebackend-zeromq-dnssec'
b33a88da
PD
697 ],
698 lmdb = [
8af54cc6
AR
699 'lmdb-nodnssec-both',
700 'lmdb-both',
701 'lmdb-nsec3-both',
702 'lmdb-nsec3-optout-both',
703 'lmdb-nsec3-narrow'
704 ],
705 gmysql = [
706 'gmysql',
707 'gmysql-nodnssec-both',
708 'gmysql-nsec3-both',
709 'gmysql-nsec3-optout-both',
710 'gmysql-nsec3-narrow',
711 'gmysql_sp-both'
712 ],
713 gpgsql = [
714 'gpgsql',
715 'gpgsql-nodnssec-both',
716 'gpgsql-nsec3-both',
717 'gpgsql-nsec3-optout-both',
718 'gpgsql-nsec3-narrow',
719 'gpgsql_sp-both'
720 ],
721 gsqlite3 = [
722 'gsqlite3',
723 'gsqlite3-nodnssec-both',
724 'gsqlite3-nsec3-both',
725 'gsqlite3-nsec3-optout-both',
726 'gsqlite3-nsec3-narrow'
727 ],
728 godbc_sqlite3 = ['godbc_sqlite3-nodnssec'],
729 godbc_mssql = [
730 'godbc_mssql',
731 'godbc_mssql-nodnssec',
732 'godbc_mssql-nsec3',
733 'godbc_mssql-nsec3-optout',
734 'godbc_mssql-nsec3-narrow'
b33a88da 735 ],
c4a7e1df
AR
736 ldap = [
737 'ldap-tree',
738 'ldap-simple',
739 'ldap-strict'
740 ],
741 geoip_mmdb = ['geoip'],
0e77de07
PD
742)
743
b47c41d1 744godbc_mssql_credentials = {"username": "sa", "password": "SAsa12%%-not-a-secret-password"}
8af54cc6 745
7d862cb3 746godbc_config = f'''
8af54cc6
AR
747[pdns-mssql-docker]
748Driver=FreeTDS
749Trace=No
7d862cb3 750Server={auth_backend_ip_addr}
8af54cc6
AR
751Port=1433
752Database=pdns
753TDS_Version=7.1
754
755[pdns-mssql-docker-nodb]
756Driver=FreeTDS
757Trace=No
7d862cb3 758Server={auth_backend_ip_addr}
8af54cc6
AR
759Port=1433
760TDS_Version=7.1
761
762[pdns-sqlite3-1]
763Driver = SQLite3
764Database = pdns.sqlite3
765
766[pdns-sqlite3-2]
767Driver = SQLite3
768Database = pdns.sqlite32
769'''
770
771def setup_godbc_mssql(c):
772 with open(os.path.expanduser("~/.odbc.ini"), "a") as f:
773 f.write(godbc_config)
774 c.sudo('sh -c \'echo "Threading=1" | cat /usr/share/tdsodbc/odbcinst.ini - | tee -a /etc/odbcinst.ini\'')
775 c.sudo('sed -i "s/libtdsodbc.so/\/usr\/lib\/x86_64-linux-gnu\/odbc\/libtdsodbc.so/g" /etc/odbcinst.ini')
776 c.run(f'echo "create database pdns" | isql -v pdns-mssql-docker-nodb {godbc_mssql_credentials["username"]} {godbc_mssql_credentials["password"]}')
777 # FIXME: Skip 8bit-txt-unescaped test
778 c.run('touch ${PWD}/regression-tests/tests/8bit-txt-unescaped/skip')
779
780def setup_godbc_sqlite3(c):
781 with open(os.path.expanduser("~/.odbc.ini"), "a") as f:
782 f.write(godbc_config)
783 c.sudo('sed -i "s/libsqlite3odbc.so/\/usr\/lib\/x86_64-linux-gnu\/odbc\/libsqlite3odbc.so/g" /etc/odbcinst.ini')
784
c4a7e1df 785def setup_ldap_client(c):
699d088a 786 c.sudo('DEBIAN_FRONTEND=noninteractive apt-get install -y ldap-utils')
7d862cb3 787 c.sudo(f'sh -c \'echo "{auth_backend_ip_addr} ldapserver" | tee -a /etc/hosts\'')
c4a7e1df 788
57d9ffa8 789def setup_softhsm(c):
790 # Modify the location of the softhsm tokens and configuration directory.
791 # Enables token generation by non-root users (runner)
792 c.run('mkdir -p /opt/pdns-auth/softhsm/tokens')
793 c.run('echo "directories.tokendir = /opt/pdns-auth/softhsm/tokens" > /opt/pdns-auth/softhsm/softhsm2.conf')
794
0e77de07
PD
795@task
796def test_auth_backend(c, backend):
7d862cb3 797 pdns_auth_env_vars = f'PDNS=/opt/pdns-auth/sbin/pdns_server PDNS2=/opt/pdns-auth/sbin/pdns_server SDIG=/opt/pdns-auth/bin/sdig NOTIFY=/opt/pdns-auth/bin/pdns_notify NSEC3DIG=/opt/pdns-auth/bin/nsec3dig SAXFR=/opt/pdns-auth/bin/saxfr ZONE2SQL=/opt/pdns-auth/bin/zone2sql ZONE2LDAP=/opt/pdns-auth/bin/zone2ldap ZONE2JSON=/opt/pdns-auth/bin/zone2json PDNSUTIL=/opt/pdns-auth/bin/pdnsutil PDNSCONTROL=/opt/pdns-auth/bin/pdns_control PDNSSERVER=/opt/pdns-auth/sbin/pdns_server SDIG=/opt/pdns-auth/bin/sdig GMYSQLHOST={auth_backend_ip_addr} GMYSQL2HOST={auth_backend_ip_addr} MYSQL_HOST={auth_backend_ip_addr} PGHOST={auth_backend_ip_addr} PGPORT=5432'
8af54cc6 798
0e77de07 799 if backend == 'remote':
e55d3a4b 800 ci_auth_install_remotebackend_test_deps(c)
0e77de07 801
222d17e2 802 if backend == 'authpy':
7d862cb3 803 c.sudo(f'sh -c \'echo "{auth_backend_ip_addr} kerberos-server" | tee -a /etc/hosts\'')
222d17e2 804 with c.cd('regression-tests.auth-py'):
8af54cc6
AR
805 c.run(f'{pdns_auth_env_vars} WITHKERBEROS=YES ./runtests')
806 return
807
57d9ffa8 808 if backend == 'bind':
809 setup_softhsm(c)
810 with c.cd('regression-tests'):
811 for variant in backend_regress_tests[backend]:
812 c.run(f'{pdns_auth_env_vars} SOFTHSM2_CONF=/opt/pdns-auth/softhsm/softhsm2.conf ./start-test-stop 5300 {variant}')
813 return
814
8af54cc6
AR
815 if backend == 'godbc_sqlite3':
816 setup_godbc_sqlite3(c)
817 with c.cd('regression-tests'):
818 for variant in backend_regress_tests[backend]:
819 c.run(f'{pdns_auth_env_vars} GODBC_SQLITE3_DSN=pdns-sqlite3-1 ./start-test-stop 5300 {variant}')
820 return
821
822 if backend == 'godbc_mssql':
823 setup_godbc_mssql(c)
824 with c.cd('regression-tests'):
825 for variant in backend_regress_tests[backend]:
826 c.run(f'{pdns_auth_env_vars} GODBC_MSSQL_PASSWORD={godbc_mssql_credentials["password"]} GODBC_MSSQL_USERNAME={godbc_mssql_credentials["username"]} GODBC_MSSQL_DSN=pdns-mssql-docker GODBC_MSSQL2_PASSWORD={godbc_mssql_credentials["password"]} GODBC_MSSQL2_USERNAME={godbc_mssql_credentials["username"]} GODBC_MSSQL2_DSN=pdns-mssql-docker ./start-test-stop 5300 {variant}')
222d17e2
PD
827 return
828
c4a7e1df
AR
829 if backend == 'ldap':
830 setup_ldap_client(c)
831
832 if backend == 'geoip_mmdb':
833 with c.cd('regression-tests'):
834 for variant in backend_regress_tests[backend]:
835 c.run(f'{pdns_auth_env_vars} geoipdatabase=../modules/geoipbackend/regression-tests/GeoLiteCity.mmdb ./start-test-stop 5300 {variant}')
836 return
837
0e77de07 838 with c.cd('regression-tests'):
b33a88da
PD
839 if backend == 'lua2':
840 c.run('touch trustedkeys') # avoid silly error during cleanup
841 for variant in backend_regress_tests[backend]:
8af54cc6 842 c.run(f'{pdns_auth_env_vars} ./start-test-stop 5300 {variant}')
222d17e2
PD
843
844 if backend == 'gsqlite3':
7d862cb3
AR
845 if os.getenv('SKIP_IPV6_TESTS'):
846 pdns_auth_env_vars += ' context=noipv6'
222d17e2 847 with c.cd('regression-tests.nobackend'):
8af54cc6 848 c.run(f'{pdns_auth_env_vars} ./runtests')
222d17e2
PD
849 c.run('/opt/pdns-auth/bin/pdnsutil test-algorithms')
850 return
b33a88da
PD
851
852@task
853def test_ixfrdist(c):
854 with c.cd('regression-tests.ixfrdist'):
855 c.run('IXFRDISTBIN=/opt/pdns-auth/bin/ixfrdist ./runtests')
0e77de07 856
99bb3530
PD
857@task
858def test_dnsdist(c):
859 c.run('chmod +x /opt/dnsdist/bin/*')
860 c.run('ls -ald /var /var/agentx /var/agentx/master')
861 c.run('ls -al /var/agentx/master')
862 with c.cd('regression-tests.dnsdist'):
2ade4784 863 c.run('DNSDISTBIN=/opt/dnsdist/bin/dnsdist LD_LIBRARY_PATH=/opt/dnsdist/lib/ ./runtests')
d3cb00f9 864
6b45d67b
O
865@task
866def test_regression_recursor(c):
867 c.run('/opt/pdns-recursor/sbin/pdns_recursor --version')
7d862cb3 868 c.run('PDNSRECURSOR=/opt/pdns-recursor/sbin/pdns_recursor RECCONTROL=/opt/pdns-recursor/bin/rec_control ./build-scripts/test-recursor')
6b45d67b
O
869
870@task
375c8fd6
O
871def test_bulk_recursor(c, threads, mthreads, shards):
872 # We run an extremely small version of the bulk test, as GH does not seem to be able to handle the UDP load
6b45d67b
O
873 with c.cd('regression-tests'):
874 c.run('curl -LO http://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip')
875 c.run('unzip top-1m.csv.zip -d .')
876 c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*')
30a57c3d 877 c.run(f'DNSBULKTEST=/usr/bin/dnsbulktest RECURSOR=/opt/pdns-recursor/sbin/pdns_recursor RECCONTROL=/opt/pdns-recursor/bin/rec_control THRESHOLD=95 TRACE=no ./recursor-test 5300 100 {threads} {mthreads} {shards}')
6b45d67b 878
dab788a9
PD
879@task
880def install_swagger_tools(c):
881 c.run('npm install -g api-spec-converter')
882
883@task
884def swagger_syntax_check(c):
885 c.run('api-spec-converter docs/http-api/swagger/authoritative-api-swagger.yaml -f swagger_2 -t openapi_3 -s json -c')
886
66c07369 887@task
df23d4bf
RG
888def install_coverity_tools(c, project):
889 token = os.getenv('COVERITY_TOKEN')
890 c.run(f'curl -s https://scan.coverity.com/download/linux64 --data "token={token}&project={project}" | gunzip | sudo tar xvf /dev/stdin --strip-components=1 --no-same-owner -C /usr/local', hide=True)
66c07369
RG
891
892@task
893def coverity_clang_configure(c):
7d862cb3 894 c.sudo(f'/usr/local/bin/cov-configure --template --comptype clangcc --compiler clang++-{clang_version}')
66c07369
RG
895
896@task
897def coverity_make(c):
898 c.run('/usr/local/bin/cov-build --dir cov-int make -j8 -k')
899
900@task
901def coverity_tarball(c, tarball):
902 c.run(f'tar caf {tarball} cov-int')
903
904@task
df23d4bf
RG
905def coverity_upload(c, email, project, tarball):
906 token = os.getenv('COVERITY_TOKEN')
66c07369
RG
907 c.run(f'curl --form token={token} \
908 --form email="{email}" \
909 --form file=@{tarball} \
910 --form version="$(./builder-support/gen-version)" \
911 --form description="master build" \
df23d4bf 912 https://scan.coverity.com/builds?project={project}', hide=True)
66c07369 913
3e5c7a76
RG
914@task
915def ci_build_and_install_quiche(c):
916 # we have to pass -L because GitHub will do a redirect, sadly
917 c.run(f'curl -L -o quiche-{quiche_version}.tar.gz https://github.com/cloudflare/quiche/archive/{quiche_version}.tar.gz')
918 # Line below should echo two spaces between digest and name
919 c.run(f'echo {quiche_hash}" "quiche-{quiche_version}.tar.gz | sha256sum -c -')
920 c.run(f'tar xf quiche-{quiche_version}.tar.gz')
921 with c.cd(f'quiche-{quiche_version}'):
2ade4784 922 c.run('cargo build --release --no-default-features --features ffi,boringssl-boring-crate --package quiche')
3e5c7a76
RG
923 # cannot use c.sudo() inside a cd() context, see https://github.com/pyinvoke/invoke/issues/687
924 c.run('sudo install -Dm644 quiche/include/quiche.h /usr/include')
2ade4784
RG
925 c.run('sudo install -Dm644 target/release/libquiche.so /usr/lib')
926 c.run('install -D target/release/libquiche.so /opt/dnsdist/lib/libquiche.so')
927 c.run(f"""sudo install -Dm644 /dev/stdin /usr/lib/pkgconfig/quiche.pc <<PC
3e5c7a76
RG
928# quiche
929Name: quiche
930Description: quiche library
931URL: https://github.com/cloudflare/quiche
2ade4784 932Version: {quiche_version}
3e5c7a76
RG
933Libs: -lquiche
934PC""")
935
d3cb00f9
PD
936# this is run always
937def setup():
938 if '/usr/lib/ccache' not in os.environ['PATH']:
939 os.environ['PATH']='/usr/lib/ccache:'+os.environ['PATH']
940
941setup()