diff --git a/Makefile b/Makefile index 8848eb3..abffbac 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,12 @@ # # Targets: # build - build ngx_http_ipng_stats_module.so out-of-tree. +# build-asan - build an ASan/UBSan-instrumented full nginx + module. # pkg-deb - build a .deb via dpkg-buildpackage for the current release. -# robot-test - build .deb, then run Robot Framework end-to-end tests -# in containerlab (requires docker + containerlab). +# robot-test - run Robot Framework end-to-end tests in containerlab. +# Reuses build/ artifacts — run `make pkg-deb build-asan` +# once beforehand, then iterate on `make robot-test`. +# Requires docker + containerlab. # install-deps - install build and test dependencies via apt. # clean - remove build artifacts and the fetched nginx source tree. # help - print this help. @@ -39,6 +42,7 @@ help: @echo " into build/nginx-asan/ for local crash-hunting." @echo " make pkg-deb Build a Debian package via dpkg-buildpackage." @echo " make robot-test Run Robot Framework e2e tests (all suites)." + @echo " Reuses artifacts; bootstrap with 'make pkg-deb build-asan' first." @echo " make install-deps Install build and test dependencies (apt)." @echo " make clean Remove build artifacts." @echo "" @@ -224,19 +228,54 @@ tests/.venv: tests/requirements.txt python3 -m venv tests/.venv tests/.venv/bin/pip install -q -r tests/requirements.txt +# robot-test intentionally does NOT rebuild the .deb or the ASan +# nginx. A full rebuild every `make robot-test` makes the iterate- +# on-test loop painfully slow. Instead we fail fast with an +# actionable message if either artifact is missing. +# +# Bootstrap once: make pkg-deb build-asan +# Then iterate: make robot-test # reuses both artifacts robot-test: tests/.venv + @if ! ls $(BUILD_DIR)/libnginx-mod-http-ipng-stats_*.deb >/dev/null 2>&1; then \ + echo "error: no module .deb in $(BUILD_DIR)/ — run 'make pkg-deb' first" >&2; \ + exit 1; \ + fi + @if [ ! -x $(BUILD_DIR)/nginx-asan/sbin/nginx ]; then \ + echo "error: no ASan nginx in $(BUILD_DIR)/nginx-asan/ — run 'make build-asan' first" >&2; \ + exit 1; \ + fi tests/rf-run.sh docker $(TEST) # ---------------------------------------------------------------------- # install-deps: install build and test dependencies # ---------------------------------------------------------------------- +# install-deps covers everything needed for `make build`, `make build-asan`, +# `make pkg-deb`, and `make robot-test` (apart from docker + containerlab, +# which have their own installers). `nginx-dev` transitively pulls the +# nginx build-deps (libpcre2-dev, libssl-dev, libxslt1-dev, libgeoip-dev, +# libperl-dev, libexpat-dev, libgd-dev, zlib1g-dev, debhelper-compat, +# po-debconf) so we don't need to list them here — keep this list to the +# things nginx-dev does NOT already bring in. +# +# `apt source nginx` (used by fetch-nginx-src and build-asan) requires a +# deb-src line in /etc/apt/sources.list — verified separately below. install-deps: sudo apt-get update -qq sudo apt-get install -y \ - nginx-dev dpkg-dev debhelper \ + build-essential \ + nginx-dev \ + dpkg-dev debhelper \ python3 python3-venv \ - curl + curl ca-certificates + @echo "" + @echo "Checking that deb-src is enabled (needed by 'apt source nginx')..." + @if ! grep -qE '^[[:space:]]*deb-src' /etc/apt/sources.list /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources 2>/dev/null; then \ + echo "warning: no 'deb-src' lines found in apt sources." >&2; \ + echo " Enable them (e.g. uncomment in /etc/apt/sources.list) and rerun:" >&2; \ + echo " sudo apt-get update" >&2; \ + exit 1; \ + fi @echo "" @echo "Build dependencies installed. For 'make robot-test' you also need:" @echo " - docker: https://docs.docker.com/engine/install/debian/" diff --git a/debian/rules b/debian/rules index 88f221e..5ce79bc 100755 --- a/debian/rules +++ b/debian/rules @@ -39,8 +39,23 @@ override_dh_auto_clean: override_dh_clean: # `dh_clean` recurses from the package root to remove junk files - # (editor backups, autom4te caches, etc.). `make build-asan` - # produces build/nginx-asan/{fastcgi,proxy,scgi,uwsgi}_temp owned - # by "nobody" with mode 0700, which the current user can't - # traverse — so we exclude anything under build/ from dh_clean. + # (editor backups, autom4te caches, etc.). Two obstacles under + # build/: + # 1. `make build-asan` produces build/nginx-asan/{fastcgi,proxy, + # scgi,uwsgi,client_body}_temp owned by "nobody" with mode + # 0700 after the ASan nginx has been run (the 02-asan robot + # suite bind-mounts build/nginx-asan/ RW into a container, + # and nginx chowns its temp dirs on master startup). The + # current user can't traverse them, which makes dh_clean's + # `find` abort with EACCES. + # 2. We don't want to delete anything under build/ anyway — it + # holds the ASan build artifacts from a prior `make build-asan`. + # Clear the unreadable temp dirs first (rm -rf only needs write + # access to the parent, which we have), then tell dh_clean to + # exclude build/ entirely. + rm -rf $(CURDIR)/build/nginx-asan/client_body_temp \ + $(CURDIR)/build/nginx-asan/fastcgi_temp \ + $(CURDIR)/build/nginx-asan/proxy_temp \ + $(CURDIR)/build/nginx-asan/scgi_temp \ + $(CURDIR)/build/nginx-asan/uwsgi_temp dh_clean -X build/