]> git.ipfire.org Git - thirdparty/pdns.git/blob - tasks.py
Introduce structured YAML settings for Recursor.
[thirdparty/pdns.git] / tasks.py
1 from invoke import task
2 from invoke.exceptions import Failure, UnexpectedExit
3
4 import os
5 import sys
6 import time
7
8 auth_backend_ip_addr = os.getenv('AUTH_BACKEND_IP_ADDR', '127.0.0.1')
9
10 clang_version = os.getenv('CLANG_VERSION', '13')
11 rust_version = 'rust-1.72.0-x86_64-unknown-linux-gnu'
12
13 all_build_deps = [
14 'ccache',
15 'libboost-all-dev',
16 'libluajit-5.1-dev',
17 'libsodium-dev',
18 'libssl-dev',
19 'libsystemd-dev',
20 'libtool',
21 'make',
22 'pkg-config',
23 'python3-venv',
24 'systemd',
25 ]
26 git_build_deps = [
27 'autoconf',
28 'automake',
29 'bison',
30 'bzip2',
31 'curl',
32 'flex',
33 'git',
34 'ragel'
35 ]
36 auth_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',
50 'ruby-bundler',
51 'ruby-dev',
52 'sqlite3',
53 'unixodbc-dev',
54 'cmake',
55 ]
56 rec_build_deps = [
57 'libcap-dev',
58 'libfstrm-dev',
59 'libsnmp-dev',
60 ]
61 rec_bulk_deps = [
62 'curl',
63 'libboost-all-dev',
64 'libcap2',
65 'libfstrm0',
66 'libluajit-5.1-2',
67 '"libsnmp[1-9]+"',
68 'libsodium23',
69 'libssl1.1',
70 'libsystemd0',
71 'moreutils',
72 'pdns-tools',
73 'unzip',
74 ]
75 dnsdist_build_deps = [
76 'libcap-dev',
77 'libcdb-dev',
78 'libedit-dev',
79 'libfstrm-dev',
80 'libgnutls28-dev',
81 'libh2o-evloop-dev',
82 'liblmdb-dev',
83 'libnghttp2-dev',
84 'libre2-dev',
85 'libsnmp-dev',
86 ]
87 auth_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',
94 'docker-compose',
95 'faketime',
96 'gawk',
97 'krb5-user',
98 'ldnsutils',
99 '"libboost-serialization1.7[1-9]+"',
100 'libcdb1',
101 'libcurl4',
102 'libgeoip1',
103 'libkrb5-3',
104 'libldap-2.4-2',
105 'liblmdb0',
106 'libluajit-5.1-2',
107 'libmaxminddb0',
108 'libnet-dns-perl',
109 'libp11-kit0',
110 'libpq5',
111 'libsodium23',
112 'libsqlite3-dev',
113 'libssl1.1',
114 'libsystemd0',
115 'libyaml-cpp0.6',
116 'libzmq3-dev',
117 'lmdb-utils',
118 'prometheus',
119 'ruby-bundler',
120 'ruby-dev',
121 'socat',
122 'softhsm2',
123 'unbound-host',
124 'unixodbc',
125 'wget',
126 ]
127 doc_deps = [
128 'autoconf',
129 'automake',
130 'bison',
131 'curl',
132 'flex',
133 'g++',
134 'git',
135 'latexmk',
136 'libboost-all-dev',
137 'libedit-dev',
138 'libluajit-5.1-dev',
139 'libssl-dev',
140 'make',
141 'pkg-config',
142 'python3-venv',
143 'ragel',
144 'rsync',
145 ]
146 doc_deps_pdf = [
147 'texlive-binaries',
148 'texlive-formats-extra',
149 'texlive-latex-extra',
150 ]
151
152 @task
153 def apt_fresh(c):
154 c.sudo('sed -i \'s/azure\.//\' /etc/apt/sources.list')
155 c.sudo('apt-get update')
156 c.sudo('apt-get -y --allow-downgrades dist-upgrade')
157
158 @task
159 def install_clang(c):
160 """
161 install clang and llvm
162 """
163 c.sudo(f'apt-get -y --no-install-recommends install clang-{clang_version} llvm-{clang_version}')
164
165 @task
166 def install_clang_tidy_tools(c):
167 c.sudo(f'apt-get -y --no-install-recommends install clang-tidy-{clang_version} clang-tools-{clang_version} bear python3-yaml')
168
169 @task
170 def install_clang_runtime(c):
171 # this gives us the symbolizer, for symbols in asan/ubsan traces
172 c.sudo(f'apt-get -y --no-install-recommends install clang-{clang_version}')
173
174 @task
175 def ci_install_rust(c, repo):
176 c.sudo(f'{repo}/builder-support/helpers/install_rust.sh {rust_version}')
177
178 def install_libdecaf(c, product):
179 c.run('git clone https://git.code.sf.net/p/ed448goldilocks/code /tmp/libdecaf')
180 with c.cd('/tmp/libdecaf'):
181 c.run('git checkout 41f349')
182 c.run(f'CC=clang-{clang_version} CXX=clang-{clang_version} '
183 'cmake -B build '
184 '-DCMAKE_INSTALL_PREFIX=/usr/local '
185 '-DCMAKE_INSTALL_LIBDIR=lib '
186 '-DENABLE_STATIC=OFF '
187 '-DENABLE_TESTS=OFF '
188 '-DCMAKE_C_FLAGS="-Wno-sizeof-array-div -Wno-array-parameter" .')
189 c.run('make -C build')
190 c.run('sudo make -C build install')
191 c.sudo(f'mkdir -p /opt/{product}/libdecaf')
192 c.sudo(f'cp /usr/local/lib/libdecaf.so* /opt/{product}/libdecaf/.')
193
194 @task
195 def install_doc_deps(c):
196 c.sudo('apt-get install -y ' + ' '.join(doc_deps))
197
198 @task
199 def install_doc_deps_pdf(c):
200 c.sudo('apt-get install -y ' + ' '.join(doc_deps_pdf))
201
202 @task
203 def install_auth_build_deps(c):
204 c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + auth_build_deps))
205 install_libdecaf(c, 'pdns-auth')
206
207 def setup_authbind(c):
208 c.sudo('touch /etc/authbind/byport/53')
209 c.sudo('chmod 755 /etc/authbind/byport/53')
210
211 auth_backend_test_deps = dict(
212 gsqlite3=['sqlite3'],
213 gmysql=['default-libmysqlclient-dev'],
214 gpgsql=['libpq-dev'],
215 lmdb=[],
216 remote=[],
217 bind=[],
218 geoip=[],
219 lua2=[],
220 tinydns=[],
221 authpy=[],
222 godbc_sqlite3=['libsqliteodbc'],
223 godbc_mssql=['freetds-bin','tdsodbc'],
224 ldap=[],
225 geoip_mmdb=[]
226 )
227
228 @task(help={'backend': 'Backend to install test deps for, e.g. gsqlite3; can be repeated'}, iterable=['backend'], optional=['backend'])
229 def install_auth_test_deps(c, backend): # FIXME: rename this, we do way more than apt-get
230 extra=[]
231 for b in backend:
232 extra.extend(auth_backend_test_deps[b])
233 c.sudo('DEBIAN_FRONTEND=noninteractive apt-get -y install ' + ' '.join(extra+auth_test_deps))
234
235 c.run('chmod +x /opt/pdns-auth/bin/* /opt/pdns-auth/sbin/*')
236 # c.run('''if [ ! -e $HOME/bin/jdnssec-verifyzone ]; then
237 # wget https://github.com/dblacka/jdnssec-tools/releases/download/0.14/jdnssec-tools-0.14.tar.gz
238 # tar xfz jdnssec-tools-0.14.tar.gz -C $HOME
239 # rm jdnssec-tools-0.14.tar.gz
240 # fi
241 # echo 'export PATH=$HOME/jdnssec-tools-0.14/bin:$PATH' >> $BASH_ENV''') # FIXME: why did this fail with no error?
242 c.run('touch regression-tests/tests/verify-dnssec-zone/allow-missing regression-tests.nobackend/rectify-axfr/allow-missing') # FIXME: can this go?
243 # FIXME we may want to start a background recursor here to make ALIAS tests more robust
244 setup_authbind(c)
245
246 # Copy libdecaf out
247 c.sudo('mkdir -p /usr/local/lib')
248 c.sudo('cp /opt/pdns-auth/libdecaf/libdecaf.so* /usr/local/lib/.')
249
250 @task
251 def install_rec_bulk_deps(c): # FIXME: rename this, we do way more than apt-get
252 c.sudo('apt-get --no-install-recommends -y install ' + ' '.join(rec_bulk_deps))
253 c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*')
254
255 @task
256 def install_rec_test_deps(c): # FIXME: rename this, we do way more than apt-get
257 c.sudo('apt-get --no-install-recommends install -y ' + ' '.join(rec_bulk_deps) + ' \
258 pdns-server pdns-backend-bind daemontools \
259 jq libfaketime lua-posix lua-socket bc authbind \
260 python3-venv python3-dev default-libmysqlclient-dev libpq-dev \
261 protobuf-compiler snmpd prometheus')
262
263 c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*')
264
265 setup_authbind(c)
266
267 c.run('sed "s/agentxperms 0700 0755 recursor/agentxperms 0777 0755/g" regression-tests.recursor-dnssec/snmpd.conf | sudo tee /etc/snmp/snmpd.conf')
268 c.sudo('/etc/init.d/snmpd restart')
269 time.sleep(5)
270 c.sudo('chmod 755 /var/agentx')
271
272 @task
273 def install_dnsdist_test_deps(c): # FIXME: rename this, we do way more than apt-get
274 c.sudo('apt-get install -y \
275 libluajit-5.1-2 \
276 libboost-all-dev \
277 libcap2 \
278 libcdb1 \
279 libcurl4-openssl-dev \
280 libfstrm0 \
281 libgnutls30 \
282 libh2o-evloop0.13 \
283 liblmdb0 \
284 libnghttp2-14 \
285 "libre2-[1-9]+" \
286 libssl-dev \
287 libsystemd0 \
288 libsodium23 \
289 lua-socket \
290 patch \
291 protobuf-compiler \
292 python3-venv snmpd prometheus')
293 c.run('sed "s/agentxperms 0700 0755 dnsdist/agentxperms 0777 0755/g" regression-tests.dnsdist/snmpd.conf | sudo tee /etc/snmp/snmpd.conf')
294 c.sudo('/etc/init.d/snmpd restart')
295 time.sleep(5)
296 c.sudo('chmod 755 /var/agentx')
297
298 @task
299 def install_rec_build_deps(c):
300 c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + rec_build_deps))
301
302 @task
303 def install_dnsdist_build_deps(c):
304 c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + dnsdist_build_deps))
305
306 @task
307 def ci_autoconf(c):
308 c.run('BUILDER_VERSION=0.0.0-git1 autoreconf -vfi')
309
310 @task
311 def ci_docs_build(c):
312 c.run('make -f Makefile.sphinx -C docs html')
313
314 @task
315 def ci_docs_build_pdf(c):
316 c.run('make -f Makefile.sphinx -C docs latexpdf')
317
318 @task
319 def ci_docs_upload_master(c, docs_host, pdf, username, product, directory=""):
320 rsync_cmd = " ".join([
321 "rsync",
322 "--checksum",
323 "--recursive",
324 "--verbose",
325 "--no-p",
326 "--chmod=g=rwX",
327 "--exclude '*~'",
328 ])
329 c.run(f"{rsync_cmd} --delete ./docs/_build/{product}-html-docs/ {username}@{docs_host}:{directory}")
330 c.run(f"{rsync_cmd} ./docs/_build/{product}-html-docs.tar.bz2 {username}@{docs_host}:{directory}/html-docs.tar.bz2")
331 c.run(f"{rsync_cmd} ./docs/_build/latex/{pdf} {username}@{docs_host}:{directory}")
332
333 @task
334 def ci_docs_add_ssh(c, ssh_key, host_key):
335 c.run('mkdir -m 700 -p ~/.ssh')
336 c.run(f'echo "{ssh_key}" > ~/.ssh/id_ed25519')
337 c.run('chmod 600 ~/.ssh/id_ed25519')
338 c.run(f'echo "{host_key}" > ~/.ssh/known_hosts')
339
340
341 def get_sanitizers():
342 sanitizers = os.getenv('SANITIZERS')
343 if sanitizers != '':
344 sanitizers = sanitizers.split('+')
345 sanitizers = ['--enable-' + sanitizer for sanitizer in sanitizers]
346 sanitizers = ' '.join(sanitizers)
347 return sanitizers
348
349
350 def get_cflags():
351 return " ".join([
352 "-O1",
353 "-Werror=vla",
354 "-Werror=shadow",
355 "-Wformat=2",
356 "-Werror=format-security",
357 "-Werror=string-plus-int",
358 ])
359
360
361 def get_cxxflags():
362 return " ".join([
363 get_cflags(),
364 "-Wp,-D_GLIBCXX_ASSERTIONS",
365 ])
366
367
368 def get_base_configure_cmd():
369 return " ".join([
370 f'CFLAGS="{get_cflags()}"',
371 f'CXXFLAGS="{get_cxxflags()}"',
372 './configure',
373 f"CC='clang-{clang_version}'",
374 f"CXX='clang++-{clang_version}'",
375 "--enable-option-checking=fatal",
376 "--enable-systemd",
377 "--with-libsodium",
378 "--enable-fortify-source=auto",
379 "--enable-auto-var-init=pattern",
380 ])
381
382
383 @task
384 def ci_auth_configure(c):
385 sanitizers = get_sanitizers()
386
387 unittests = os.getenv('UNIT_TESTS')
388 if unittests == 'yes':
389 unittests = '--enable-unit-tests --enable-backend-unit-tests'
390 else:
391 unittests = ''
392
393 fuzz_targets = os.getenv('FUZZING_TARGETS')
394 fuzz_targets = '--enable-fuzz-targets' if fuzz_targets == 'yes' else ''
395
396 modules = " ".join([
397 "bind",
398 "geoip",
399 "gmysql",
400 "godbc",
401 "gpgsql",
402 "gsqlite3",
403 "ldap",
404 "lmdb",
405 "lua2",
406 "pipe",
407 "remote",
408 "tinydns",
409 ])
410 configure_cmd = " ".join([
411 get_base_configure_cmd(),
412 "LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib'",
413 f"--with-modules='{modules}'",
414 "--enable-tools",
415 "--enable-experimental-pkcs11",
416 "--enable-experimental-gss-tsig",
417 "--enable-remotebackend-zeromq",
418 "--with-lmdb=/usr",
419 "--with-libdecaf",
420 "--prefix=/opt/pdns-auth",
421 "--enable-ixfrdist",
422 sanitizers,
423 unittests,
424 fuzz_targets,
425 ])
426 res = c.run(configure_cmd, warn=True)
427 if res.exited != 0:
428 c.run('cat config.log')
429 raise UnexpectedExit(res)
430
431
432 @task
433 def ci_rec_configure(c):
434 sanitizers = get_sanitizers()
435
436 unittests = os.getenv('UNIT_TESTS')
437 unittests = '--enable-unit-tests' if unittests == 'yes' else ''
438
439 configure_cmd = " ".join([
440 get_base_configure_cmd(),
441 "--enable-nod",
442 "--prefix=/opt/pdns-recursor",
443 "--with-lua=luajit",
444 "--with-libcap",
445 "--with-net-snmp",
446 "--enable-dns-over-tls",
447 sanitizers,
448 unittests,
449 ])
450 res = c.run(configure_cmd, warn=True)
451 if res.exited != 0:
452 c.run('cat config.log')
453 raise UnexpectedExit(res)
454
455
456 @task
457 def ci_dnsdist_configure(c, features):
458 additional_flags = ''
459 if features == 'full':
460 features_set = '--enable-dnstap \
461 --enable-dnscrypt \
462 --enable-dns-over-tls \
463 --enable-dns-over-https \
464 --enable-systemd \
465 --prefix=/opt/dnsdist \
466 --with-gnutls \
467 --with-libsodium \
468 --with-lua=luajit \
469 --with-libcap \
470 --with-net-snmp \
471 --with-nghttp2 \
472 --with-re2 '
473 else:
474 features_set = '--disable-dnstap \
475 --disable-dnscrypt \
476 --disable-ipcipher \
477 --disable-systemd \
478 --without-cdb \
479 --without-ebpf \
480 --without-gnutls \
481 --without-libedit \
482 --without-libsodium \
483 --without-lmdb \
484 --without-net-snmp \
485 --without-nghttp2 \
486 --without-re2 '
487 additional_flags = '-DDISABLE_COMPLETION \
488 -DDISABLE_DELAY_PIPE \
489 -DDISABLE_DYNBLOCKS \
490 -DDISABLE_PROMETHEUS \
491 -DDISABLE_PROTOBUF \
492 -DDISABLE_BUILTIN_HTML \
493 -DDISABLE_CARBON \
494 -DDISABLE_SECPOLL \
495 -DDISABLE_DEPRECATED_DYNBLOCK \
496 -DDISABLE_LUA_WEB_HANDLERS \
497 -DDISABLE_NON_FFI_DQ_BINDINGS \
498 -DDISABLE_POLICIES_BINDINGS \
499 -DDISABLE_PACKETCACHE_BINDINGS \
500 -DDISABLE_DOWNSTREAM_BINDINGS \
501 -DDISABLE_COMBO_ADDR_BINDINGS \
502 -DDISABLE_CLIENT_STATE_BINDINGS \
503 -DDISABLE_QPS_LIMITER_BINDINGS \
504 -DDISABLE_SUFFIX_MATCH_BINDINGS \
505 -DDISABLE_NETMASK_BINDINGS \
506 -DDISABLE_DNSNAME_BINDINGS \
507 -DDISABLE_DNSHEADER_BINDINGS \
508 -DDISABLE_RECVMMSG \
509 -DDISABLE_WEB_CACHE_MANAGEMENT \
510 -DDISABLE_WEB_CONFIG \
511 -DDISABLE_RULES_ALTERING_QUERIES \
512 -DDISABLE_ECS_ACTIONS \
513 -DDISABLE_TOP_N_BINDINGS \
514 -DDISABLE_OCSP_STAPLING \
515 -DDISABLE_HASHED_CREDENTIALS \
516 -DDISABLE_FALSE_SHARING_PADDING \
517 -DDISABLE_NPN'
518 unittests = ' --enable-unit-tests' if os.getenv('UNIT_TESTS') == 'yes' else ''
519 sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else ''
520 cflags = '-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int'
521 cxxflags = cflags + ' -Wp,-D_GLIBCXX_ASSERTIONS ' + additional_flags
522 res = c.run(f'''CFLAGS="%s" \
523 CXXFLAGS="%s" \
524 AR=llvm-ar-{clang_version} \
525 RANLIB=llvm-ranlib-{clang_version} \
526 ./configure \
527 CC='clang-{clang_version}' \
528 CXX='clang++-{clang_version}' \
529 --enable-option-checking=fatal \
530 --enable-fortify-source=auto \
531 --enable-auto-var-init=pattern \
532 --enable-lto=thin \
533 --prefix=/opt/dnsdist %s %s %s''' % (cflags, cxxflags, features_set, sanitizers, unittests), warn=True)
534 if res.exited != 0:
535 c.run('cat config.log')
536 raise UnexpectedExit(res)
537
538 @task
539 def ci_auth_make(c):
540 c.run('make -j8 -k V=1')
541
542 @task
543 def ci_auth_make_bear(c):
544 # Needed for clang-tidy -line-filter vs project structure shenanigans
545 with c.cd('pdns'):
546 c.run('bear --append -- make -j8 -k V=1 -C ..')
547
548 @task
549 def ci_rec_make(c):
550 c.run('make -j8 -k V=1')
551
552 @task
553 def ci_rec_make_bear(c):
554 # Assumed to be running under ./pdns/recursordist/
555 c.run('bear --append -- make -j8 -k V=1')
556
557 @task
558 def ci_dnsdist_make(c):
559 c.run('make -j4 -k V=1')
560
561 @task
562 def ci_dnsdist_make_bear(c):
563 # Assumed to be running under ./pdns/dnsdistdist/
564 c.run('bear --append -- make -j4 -k V=1')
565
566 @task
567 def ci_auth_install_remotebackend_test_deps(c):
568 with c.cd('modules/remotebackend'):
569 # c.run('bundle config set path vendor/bundle')
570 c.run('sudo ruby -S bundle install')
571 c.sudo('apt-get install -y socat')
572
573 @task
574 def ci_auth_run_unit_tests(c):
575 res = c.run('make check', warn=True)
576 if res.exited != 0:
577 c.run('cat pdns/test-suite.log', warn=True)
578 c.run('cat modules/remotebackend/test-suite.log', warn=True)
579 raise UnexpectedExit(res)
580
581 @task
582 def ci_rec_run_unit_tests(c):
583 res = c.run('make check', warn=True)
584 if res.exited != 0:
585 c.run('cat test-suite.log')
586 raise UnexpectedExit(res)
587
588 @task
589 def ci_dnsdist_run_unit_tests(c):
590 res = c.run('make check', warn=True)
591 if res.exited != 0:
592 c.run('cat test-suite.log')
593 raise UnexpectedExit(res)
594
595 @task
596 def ci_make_install(c):
597 res = c.run('make install') # FIXME: this builds auth docs - again
598
599 @task
600 def add_auth_repo(c, dist_name, dist_release_name, pdns_repo_version):
601 c.sudo('apt-get install -y curl gnupg2')
602 if pdns_repo_version == 'master':
603 c.sudo('curl -s -o /etc/apt/trusted.gpg.d/pdns-repo.asc https://repo.powerdns.com/CBC8B383-pub.asc')
604 else:
605 c.sudo('curl -s -o /etc/apt/trusted.gpg.d/pdns-repo.asc https://repo.powerdns.com/FD380FBB-pub.asc')
606 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")
607 c.run("echo 'Package: pdns-*' | sudo tee /etc/apt/preferences.d/pdns")
608 c.run("echo 'Pin: origin repo.powerdns.com' | sudo tee -a /etc/apt/preferences.d/pdns")
609 c.run("echo 'Pin-Priority: 600' | sudo tee -a /etc/apt/preferences.d/pdns")
610 c.sudo('apt-get update')
611
612 @task
613 def test_api(c, product, backend=''):
614 if product == 'recursor':
615 with c.cd('regression-tests.api'):
616 c.run(f'PDNSRECURSOR=/opt/pdns-recursor/sbin/pdns_recursor ./runtests recursor {backend}')
617 elif product == 'auth':
618 with c.cd('regression-tests.api'):
619 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}')
620 else:
621 raise Failure('unknown product')
622
623 backend_regress_tests = dict(
624 bind = [
625 'bind-both',
626 'bind-dnssec-both',
627 'bind-dnssec-nsec3-both',
628 'bind-dnssec-nsec3-optout-both',
629 'bind-dnssec-nsec3-narrow',
630 # FIXME 'bind-dnssec-pkcs11'
631 ],
632 geoip = [
633 'geoip',
634 'geoip-nsec3-narrow'
635 ],
636 lua2 = ['lua2', 'lua2-dnssec'],
637 tinydns = ['tinydns'],
638 remote = [
639 'remotebackend-pipe',
640 'remotebackend-unix',
641 'remotebackend-http',
642 'remotebackend-zeromq',
643 'remotebackend-pipe-dnssec',
644 'remotebackend-unix-dnssec',
645 'remotebackend-http-dnssec',
646 'remotebackend-zeromq-dnssec'
647 ],
648 lmdb = [
649 'lmdb-nodnssec-both',
650 'lmdb-both',
651 'lmdb-nsec3-both',
652 'lmdb-nsec3-optout-both',
653 'lmdb-nsec3-narrow'
654 ],
655 gmysql = [
656 'gmysql',
657 'gmysql-nodnssec-both',
658 'gmysql-nsec3-both',
659 'gmysql-nsec3-optout-both',
660 'gmysql-nsec3-narrow',
661 'gmysql_sp-both'
662 ],
663 gpgsql = [
664 'gpgsql',
665 'gpgsql-nodnssec-both',
666 'gpgsql-nsec3-both',
667 'gpgsql-nsec3-optout-both',
668 'gpgsql-nsec3-narrow',
669 'gpgsql_sp-both'
670 ],
671 gsqlite3 = [
672 'gsqlite3',
673 'gsqlite3-nodnssec-both',
674 'gsqlite3-nsec3-both',
675 'gsqlite3-nsec3-optout-both',
676 'gsqlite3-nsec3-narrow'
677 ],
678 godbc_sqlite3 = ['godbc_sqlite3-nodnssec'],
679 godbc_mssql = [
680 'godbc_mssql',
681 'godbc_mssql-nodnssec',
682 'godbc_mssql-nsec3',
683 'godbc_mssql-nsec3-optout',
684 'godbc_mssql-nsec3-narrow'
685 ],
686 ldap = [
687 'ldap-tree',
688 'ldap-simple',
689 'ldap-strict'
690 ],
691 geoip_mmdb = ['geoip'],
692 )
693
694 godbc_mssql_credentials = {"username": "sa", "password": "SAsa12%%"}
695
696 godbc_config = f'''
697 [pdns-mssql-docker]
698 Driver=FreeTDS
699 Trace=No
700 Server={auth_backend_ip_addr}
701 Port=1433
702 Database=pdns
703 TDS_Version=7.1
704
705 [pdns-mssql-docker-nodb]
706 Driver=FreeTDS
707 Trace=No
708 Server={auth_backend_ip_addr}
709 Port=1433
710 TDS_Version=7.1
711
712 [pdns-sqlite3-1]
713 Driver = SQLite3
714 Database = pdns.sqlite3
715
716 [pdns-sqlite3-2]
717 Driver = SQLite3
718 Database = pdns.sqlite32
719 '''
720
721 def setup_godbc_mssql(c):
722 with open(os.path.expanduser("~/.odbc.ini"), "a") as f:
723 f.write(godbc_config)
724 c.sudo('sh -c \'echo "Threading=1" | cat /usr/share/tdsodbc/odbcinst.ini - | tee -a /etc/odbcinst.ini\'')
725 c.sudo('sed -i "s/libtdsodbc.so/\/usr\/lib\/x86_64-linux-gnu\/odbc\/libtdsodbc.so/g" /etc/odbcinst.ini')
726 c.run(f'echo "create database pdns" | isql -v pdns-mssql-docker-nodb {godbc_mssql_credentials["username"]} {godbc_mssql_credentials["password"]}')
727 # FIXME: Skip 8bit-txt-unescaped test
728 c.run('touch ${PWD}/regression-tests/tests/8bit-txt-unescaped/skip')
729
730 def setup_godbc_sqlite3(c):
731 with open(os.path.expanduser("~/.odbc.ini"), "a") as f:
732 f.write(godbc_config)
733 c.sudo('sed -i "s/libsqlite3odbc.so/\/usr\/lib\/x86_64-linux-gnu\/odbc\/libsqlite3odbc.so/g" /etc/odbcinst.ini')
734
735 def setup_ldap_client(c):
736 c.sudo('DEBIAN_FRONTEND=noninteractive apt-get install -y ldap-utils')
737 c.sudo(f'sh -c \'echo "{auth_backend_ip_addr} ldapserver" | tee -a /etc/hosts\'')
738
739 @task
740 def test_auth_backend(c, backend):
741 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'
742
743 if backend == 'remote':
744 ci_auth_install_remotebackend_test_deps(c)
745
746 if backend == 'authpy':
747 c.sudo(f'sh -c \'echo "{auth_backend_ip_addr} kerberos-server" | tee -a /etc/hosts\'')
748 with c.cd('regression-tests.auth-py'):
749 c.run(f'{pdns_auth_env_vars} WITHKERBEROS=YES ./runtests')
750 return
751
752 if backend == 'godbc_sqlite3':
753 setup_godbc_sqlite3(c)
754 with c.cd('regression-tests'):
755 for variant in backend_regress_tests[backend]:
756 c.run(f'{pdns_auth_env_vars} GODBC_SQLITE3_DSN=pdns-sqlite3-1 ./start-test-stop 5300 {variant}')
757 return
758
759 if backend == 'godbc_mssql':
760 setup_godbc_mssql(c)
761 with c.cd('regression-tests'):
762 for variant in backend_regress_tests[backend]:
763 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}')
764 return
765
766 if backend == 'ldap':
767 setup_ldap_client(c)
768
769 if backend == 'geoip_mmdb':
770 with c.cd('regression-tests'):
771 for variant in backend_regress_tests[backend]:
772 c.run(f'{pdns_auth_env_vars} geoipdatabase=../modules/geoipbackend/regression-tests/GeoLiteCity.mmdb ./start-test-stop 5300 {variant}')
773 return
774
775 with c.cd('regression-tests'):
776 if backend == 'lua2':
777 c.run('touch trustedkeys') # avoid silly error during cleanup
778 for variant in backend_regress_tests[backend]:
779 c.run(f'{pdns_auth_env_vars} ./start-test-stop 5300 {variant}')
780
781 if backend == 'gsqlite3':
782 if os.getenv('SKIP_IPV6_TESTS'):
783 pdns_auth_env_vars += ' context=noipv6'
784 with c.cd('regression-tests.nobackend'):
785 c.run(f'{pdns_auth_env_vars} ./runtests')
786 c.run('/opt/pdns-auth/bin/pdnsutil test-algorithms')
787 return
788
789 @task
790 def test_ixfrdist(c):
791 with c.cd('regression-tests.ixfrdist'):
792 c.run('IXFRDISTBIN=/opt/pdns-auth/bin/ixfrdist ./runtests')
793
794 @task
795 def test_dnsdist(c):
796 c.run('chmod +x /opt/dnsdist/bin/*')
797 c.run('ls -ald /var /var/agentx /var/agentx/master')
798 c.run('ls -al /var/agentx/master')
799 with c.cd('regression-tests.dnsdist'):
800 c.run('DNSDISTBIN=/opt/dnsdist/bin/dnsdist ./runtests')
801
802 @task
803 def test_regression_recursor(c):
804 c.run('/opt/pdns-recursor/sbin/pdns_recursor --version')
805 c.run('PDNSRECURSOR=/opt/pdns-recursor/sbin/pdns_recursor RECCONTROL=/opt/pdns-recursor/bin/rec_control ./build-scripts/test-recursor')
806
807 @task
808 def test_bulk_recursor(c, threads, mthreads, shards):
809 # We run an extremely small version of the bulk test, as GH does not seem to be able to handle the UDP load
810 with c.cd('regression-tests'):
811 c.run('curl -LO http://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip')
812 c.run('unzip top-1m.csv.zip -d .')
813 c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*')
814 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 ./timestamp ./recursor-test 5300 100 {threads} {mthreads} {shards}')
815
816 @task
817 def install_swagger_tools(c):
818 c.run('npm install -g api-spec-converter')
819
820 @task
821 def swagger_syntax_check(c):
822 c.run('api-spec-converter docs/http-api/swagger/authoritative-api-swagger.yaml -f swagger_2 -t openapi_3 -s json -c')
823
824 @task
825 def install_coverity_tools(c, project):
826 token = os.getenv('COVERITY_TOKEN')
827 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)
828
829 @task
830 def coverity_clang_configure(c):
831 c.sudo(f'/usr/local/bin/cov-configure --template --comptype clangcc --compiler clang++-{clang_version}')
832
833 @task
834 def coverity_make(c):
835 c.run('/usr/local/bin/cov-build --dir cov-int make -j8 -k')
836
837 @task
838 def coverity_tarball(c, tarball):
839 c.run(f'tar caf {tarball} cov-int')
840
841 @task
842 def coverity_upload(c, email, project, tarball):
843 token = os.getenv('COVERITY_TOKEN')
844 c.run(f'curl --form token={token} \
845 --form email="{email}" \
846 --form file=@{tarball} \
847 --form version="$(./builder-support/gen-version)" \
848 --form description="master build" \
849 https://scan.coverity.com/builds?project={project}', hide=True)
850
851 # this is run always
852 def setup():
853 if '/usr/lib/ccache' not in os.environ['PATH']:
854 os.environ['PATH']='/usr/lib/ccache:'+os.environ['PATH']
855
856 setup()