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