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