def __init__(self, result=None, reason=None, template=None): template = template or self.TEMPLATE if result is None: result = Result(exited=1, hide=self.HIDE_NOTHING) if not result.hide: # -- HINT: WEIRD-TWEAK needed for output. # REQUIRES: Non-empty string or non-empty list/tuple. # SEE ALSO: invoke.program:Program.run() exception handling. result.hide = self.HIDE_NOTHING UnexpectedExit.__init__(self, result, reason or "FAILED") self.template = template
def _check_homebrew_exists(res): if res.return_code == kCommandNotFound: raise Exit( '`brew` executable not found. Please install HomeBrew: https://brew.sh' ) elif res.return_code != kSuccess: raise UnexpectedExit(res)
def ci_dnsdist_configure(c): sanitizers = ' '.join('--enable-' + x for x in os.getenv('SANITIZERS').split('+')) res = c.run( '''CFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int" \ CXXFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int -Wp,-D_GLIBCXX_ASSERTIONS" \ ./configure \ CC='clang-12' \ CXX='clang++-12' \ --enable-option-checking=fatal \ --enable-unit-tests \ --enable-dnstap \ --enable-dnscrypt \ --enable-dns-over-tls \ --enable-dns-over-https \ --enable-systemd \ --prefix=/opt/dnsdist \ --with-gnutls \ --with-libsodium \ --with-lua=luajit \ --with-libcap \ --with-nghttp2 \ --with-re2 ''' + sanitizers, warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res)
def ci_auth_configure(c): res = c.run( '''CFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int" \ CXXFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int -Wp,-D_GLIBCXX_ASSERTIONS" \ ./configure \ CC='clang-12' \ CXX='clang++-12' \ --enable-option-checking=fatal \ --with-modules='bind geoip gmysql godbc gpgsql gsqlite3 ldap lmdb lua2 pipe remote tinydns' \ --enable-systemd \ --enable-tools \ --enable-unit-tests \ --enable-backend-unit-tests \ --enable-fuzz-targets \ --enable-experimental-pkcs11 \ --enable-remotebackend-zeromq \ --with-lmdb=/usr \ --with-libsodium \ --prefix=/opt/pdns-auth \ --enable-ixfrdist \ --enable-asan \ --enable-ubsan''', warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res)
def sign_nuget(ctx, path, certfile, certpass): if certfile and certpass: print("Signing {}\n".format(path)) else: print("Not signing: {}\n".format(path)) return cmd = "nuget sign {file} -CertificatePath {certfile} -CertificatePassword {certpass} -Timestamper {timestamp_server} -NonInteractive".format( file=path, certfile=certfile, certpass=certpass, timestamp_server=timestamp_server) ## is harder to debug, but suppress stdin/stdout/stderr echo (hide = true) so we ## don't print the password try: ctx.run(cmd, hide=True) except UnexpectedExit as e: error = "(UE) Failed to sign nuget package {file}\n".format(file=path) print(error) e.result.command = "redacted" raise UnexpectedExit(e.result, e.reason) except Failure as e: error = "(F) Failed to sign nuget package {file}\n".format(file=path) print(error) e.result.command = "redacted" raise Failure(e.result, e.reason) except Exit as e: error = "(E) Failed to sign nuget package {file}\n".format(file=path) print(error) raise
def sign_binary(ctx, path, certfile, certpass): if certfile and certpass: print("Signing {}\n".format(path)) else: print("Not signing: {}\n".format(path)) return cmd = "signtool sign /f {certfile} /p {certpass} /t {timestamp_server} {file}".format( certfile=certfile, certpass=certpass, timestamp_server=timestamp_server, file=path) ## is harder to debug, but suppress stdin/stdout/stderr echo (hide = true) so we ## don't print the password try: ctx.run(cmd, hide=True) except UnexpectedExit as e: error = "(UE) Failed to sign file {file}\n".format(file=path) print(error) e.result.command = "redacted" raise UnexpectedExit(e.result, e.reason) except Failure as e: error = "(F) Failed to sign file {file}\n".format(file=path) print(error) e.result.command = "redacted" raise Failure(e.result, e.reason) except Exit as e: error = "(E) Failed to sign file {file}\n".format(file=path) print(error) raise
def deploy(ctx): branch = ctx.run("git rev-parse --abbrev-ref HEAD").stdout.strip() if branch != "master": print("Aborted: Only deploy master.") raise UnexpectedExit() ctx.run("docker save -o /tmp/strutbox.tar strutbox/web") ctx.run("scp -C /tmp/strutbox.tar strut.zone:") ctx.run("ssh strut.zone sudo ./deploy.sh") ctx.run("rm -f /tmp/strutbox.tar")
def build(ctx, force=False): dirty = False rv = ctx.run("git diff --quiet", warn=True) dirty = rv.failed if dirty and not force: print("Aborted: HEAD is dirty.") raise UnexpectedExit(rv) rev = ctx.run("git rev-parse HEAD").stdout.strip() if dirty: rev = f"{rev}-dirty" ctx.run( f"docker build --build-arg BUILD_REVISION={rev} --pull --rm -t strutbox/web ." )
def git_get_default_branch_from_remote(c, repo: Path, remote="origin"): if repo.samefile(c.cwd): result = c.run(f"git remote set-head -a {remote}", hide=True) else: with c.cd(repo): result = c.run(f"git remote set-head -a {remote}", hide=True) stdout = result.stdout.strip() # expecting message to be like 'origin/HEAD set to main' prefix = f"{remote}/HEAD set to " if stdout.startswith(prefix): branch_name = stdout[len(prefix):] else: raise UnexpectedExit( result, f"unable to parse output from `git remote set-head -a {remote}`") return branch_name
def ci_rec_configure(c): res = c.run( ''' CFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int" \ CXXFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int -Wp,-D_GLIBCXX_ASSERTIONS" \ ./configure \ CC='clang-12' \ CXX='clang++-12' \ --enable-option-checking=fatal \ --enable-unit-tests \ --enable-nod \ --enable-systemd \ --prefix=/opt/pdns-recursor \ --with-libsodium \ --with-lua=luajit \ --with-libcap \ --with-net-snmp \ --enable-dns-over-tls \ --enable-asan \ --enable-ubsan''', warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res)
def ci_dnsdist_run_unit_tests(c): res = c.run('make check', warn=True) if res.exited != 0: c.run('cat test-suite.log') raise UnexpectedExit(res)
def ci_auth_run_unit_tests(c): res = c.run('make check', warn=True) if res.exited != 0: c.run('cat pdns/test-suite.log') c.run('cat modules/remotebackend/test-suite.log') raise UnexpectedExit(res)
def ci_dnsdist_configure(c, features): additional_flags = '' if features == 'full': features_set = '--enable-dnstap \ --enable-dnscrypt \ --enable-dns-over-tls \ --enable-dns-over-https \ --enable-systemd \ --prefix=/opt/dnsdist \ --with-gnutls \ --with-libsodium \ --with-lua=luajit \ --with-libcap \ --with-nghttp2 \ --with-re2 ' else: features_set = '--disable-dnstap \ --disable-dnscrypt \ --disable-ipcipher \ --disable-systemd \ --without-cdb \ --without-ebpf \ --without-gnutls \ --without-libedit \ --without-libsodium \ --without-lmdb \ --without-net-snmp \ --without-nghttp2 \ --without-re2 ' additional_flags = '-DDISABLE_COMPLETION \ -DDISABLE_PROMETHEUS \ -DDISABLE_PROTOBUF \ -DDISABLE_BUILTIN_HTML \ -DDISABLE_CARBON \ -DDISABLE_SECPOLL \ -DDISABLE_DEPRECATED_DYNBLOCK \ -DDISABLE_LUA_WEB_HANDLERS \ -DDISABLE_NON_FFI_DQ_BINDINGS \ -DDISABLE_POLICIES_BINDINGS \ -DDISABLE_PACKETCACHE_BINDINGS \ -DDISABLE_DOWNSTREAM_BINDINGS \ -DDISABLE_COMBO_ADDR_BINDINGS \ -DDISABLE_CLIENT_STATE_BINDINGS \ -DDISABLE_QPS_LIMITER_BINDINGS \ -DDISABLE_SUFFIX_MATCH_BINDINGS \ -DDISABLE_NETMASK_BINDINGS \ -DDISABLE_DNSNAME_BINDINGS \ -DDISABLE_DNSHEADER_BINDINGS \ -DDISABLE_RECVMMSG \ -DDISABLE_WEB_CONFIG \ -DDISABLE_RULES_ALTERING_QUERIES \ -DDISABLE_ECS_ACTIONS \ -DDISABLE_TOP_N_BINDINGS' sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) cflags = '-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int' cxxflags = cflags + ' -Wp,-D_GLIBCXX_ASSERTIONS ' + additional_flags res = c.run('''CFLAGS="%s" \ CXXFLAGS="%s" \ ./configure \ CC='clang-12' \ CXX='clang++-12' \ --enable-option-checking=fatal \ --enable-unit-tests \ --prefix=/opt/dnsdist %s %s''' % (cflags, cxxflags, features_set, sanitizers), warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res)