@@ -467,9 +467,10 @@ jobs:
467467 # syntactic + presence-of-fail-loud-branches validation. Catches
468468 # regressions in unit-file syntax, shim shell logic, and the
469469 # install.sh CLI surface.
470- # Phase 5.9-e: build all four wolf-*.deb on a clean ubuntu-latest
471- # runner. Catches build-time issues across the per-component
472- # debian/ artifacts authored in 5.9-a/b/c/d that the per-slice
470+ # Phase 5.9-e: build all five wolf-*.deb on a clean ubuntu-latest
471+ # runner (wolf-search joined in slice 6-f.2, ADR 0032). Catches
472+ # build-time issues across the per-component debian/ artifacts
473+ # authored in 5.9-a/b/c/d + 6-f.2 that the per-slice
473474 # static checks (bash -n, syntax-only validation) can't reach.
474475 # Runs natively on the runner (vs Docker-in-Docker) — faster, no
475476 # nested-container quirks.
@@ -511,7 +512,7 @@ jobs:
511512 python3 python3-pip python3-venv python3-build \
512513 nodejs npm \
513514 ca-certificates
514- - name : Build all four .debs
515+ - name : Build all five .debs
515516 run : dpkg-buildpackage -b -us -uc
516517 - name : Stage .debs inside the workspace for upload
517518 # dpkg-buildpackage drops .deb files in the parent of the
@@ -522,8 +523,8 @@ jobs:
522523 mv ../wolf*.deb packaging/build/debs/
523524 ls -la packaging/build/debs/
524525 count=$(ls packaging/build/debs/wolf*.deb 2>/dev/null | wc -l)
525- if [ "$count" -lt 4 ]; then
526- echo "FAIL: expected 4 .debs, got $count"
526+ if [ "$count" -lt 5 ]; then
527+ echo "FAIL: expected 5 .debs, got $count"
527528 exit 1
528529 fi
529530 echo "OK: $count .debs produced"
@@ -632,7 +633,9 @@ jobs:
632633 # NodeSource). add-apt-repository ppa:deadsnakes can hang on a slow
633634 # launchpad/keyserver — with no timeout it wedges at GitHub's 6-hour
634635 # default. Cap it so an infra hang fails fast in minutes, not hours.
635- timeout-minutes : 15
636+ # 25 (was 15): wolf-search's postinst clones SearXNG + pip-installs
637+ # its deps over the network (~3-5 min on a runner) — slice 6-f.2.
638+ timeout-minutes : 25
636639 steps :
637640 - uses : actions/checkout@v6
638641 - name : Download .debs from smoke-deb
@@ -683,16 +686,21 @@ jobs:
683686 sudo apt-get install -y python3.13 python3.13-venv nodejs
684687 python3.13 --version
685688 node --version
686- - name : Install all four wolf-*.debs
689+ - name : Install all five wolf-*.debs
687690 # apt install resolves the inter-package deps automatically
688691 # (wolf-server depends on wolf-database, the meta wolf
689- # depends on all three components, etc.).
692+ # depends on all three components, etc.). wolf-search's
693+ # Depends (uwsgi, git, libxslt-dev, ...) come from stock
694+ # noble; its postinst clones SearXNG at the Wolf-verified
695+ # pin + builds the venv — real network install, by design
696+ # (ADR 0032: the postinst IS the official install recipe).
690697 run : |
691698 ls -la debs/
692699 sudo apt install -y \
693700 ./debs/wolf-database_*.deb \
694701 ./debs/wolf-server_*.deb \
695702 ./debs/wolf-dashboard_*.deb \
703+ ./debs/wolf-search_*.deb \
696704 ./debs/wolf_*.deb
697705 - name : Verify service users + group created by postinst
698706 run : |
@@ -752,11 +760,12 @@ jobs:
752760 /usr/bin/wolf-cert --help 2>&1 | head -5
753761 echo "OK: shims executable + CLIs respond"
754762 - name : Verify systemd units are loaded
755- # Don't start them (needs operator-driven init); just
756- # confirm systemd recognises the units so they could be
757- # started.
763+ # Don't start the three core components (needs operator-driven
764+ # init); just confirm systemd recognises the units so they
765+ # could be started. wolf-search gets a REAL start below — it
766+ # is the one component whose postinst leaves it fully runnable.
758767 run : |
759- for unit in wolf-database wolf-server wolf-dashboard; do
768+ for unit in wolf-database wolf-server wolf-dashboard wolf-search ; do
760769 systemctl status "$unit" --no-pager 2>&1 | head -3 || true
761770 # `is-enabled` returns "disabled" for fresh installs
762771 # (postinst doesn't auto-enable; operator does that
@@ -765,12 +774,59 @@ jobs:
765774 systemctl cat "$unit" >/dev/null 2>&1 \
766775 || { echo "FAIL: systemctl can't load $unit unit"; exit 1; }
767776 done
768- echo "OK: all 3 systemd units loaded + parseable"
777+ echo "OK: all 4 systemd units loaded + parseable"
778+ - name : Verify wolf-search postinst effects (slice 6-f.2)
779+ # The postinst = the official SearXNG recipe pinned to the
780+ # Wolf-verified commit. Verify each of its jobs actually
781+ # happened on this clean runner.
782+ run : |
783+ getent passwd searxng || { echo "FAIL: searxng user missing"; exit 1; }
784+ pin="747cec4c2304fc2e06ceb4a46dbe25bfb769db1e"
785+ head=$(sudo -u searxng git -C /usr/local/searxng/searxng-src rev-parse HEAD)
786+ [ "$head" = "$pin" ] \
787+ || { echo "FAIL: searxng-src at $head, expected pin $pin"; exit 1; }
788+ test -x /usr/local/searxng/searx-pyenv/bin/python \
789+ || { echo "FAIL: searx-pyenv venv missing"; exit 1; }
790+ perms=$(stat -c "%a %U %G" /etc/searxng/settings.yml)
791+ [ "$perms" = "640 root searxng" ] \
792+ || { echo "FAIL: settings.yml is '$perms', expected '640 root searxng'"; exit 1; }
793+ if sudo grep -q "ultrasecretkey" /etc/searxng/settings.yml; then
794+ echo "FAIL: secret_key placeholder not substituted"; exit 1
795+ fi
796+ test -f /etc/uwsgi/apps-available/searxng.ini \
797+ || { echo "FAIL: uwsgi ini missing"; exit 1; }
798+ if test -L /etc/uwsgi/apps-enabled/searxng.ini; then
799+ echo "FAIL: ini must NOT be in apps-enabled (double-run)"; exit 1
800+ fi
801+ test -x /usr/bin/wolf-search || { echo "FAIL: wolf-search shim missing"; exit 1; }
802+ /usr/bin/wolf-search help | grep -q "health" \
803+ || { echo "FAIL: wolf-search help doesn't list health"; exit 1; }
804+ echo "OK: searxng user + pinned checkout + venv + settings(640) + ini + shim"
805+ - name : Start wolf-search + end-to-end health check
806+ # Unlike the three core components, wolf-search needs no
807+ # operator-provisioned env — postinst leaves it runnable.
808+ # `wolf-search health` probes the exact JSON endpoint
809+ # wolf-server's SearxngProvider consumes; SearXNG answers
810+ # HTTP 200 regardless of upstream-engine luck, so this is
811+ # stable on a datacenter runner.
812+ run : |
813+ sudo systemctl start wolf-search
814+ for i in $(seq 1 12); do
815+ if /usr/bin/wolf-search health; then
816+ echo "OK: wolf-search healthy end-to-end (loopback 1307, JSON API 200)"
817+ exit 0
818+ fi
819+ sleep 5
820+ done
821+ echo "FAIL: wolf-search not healthy after 60s"
822+ sudo journalctl -u wolf-search --no-pager | tail -40
823+ exit 1
769824 - name : Smoke summary
770825 run : |
771826 echo "=== smoke-deb-install: PASS ==="
772827 echo "wolf-* packages installed cleanly on ubuntu-latest"
773828 echo "users / group / FHS dirs / venvs / shims / systemd units all verified"
829+ echo "wolf-search: postinst recipe verified + service started + health OK"
774830
775831 smoke-systemd :
776832 name : systemd + shims smoke (Phase 5.8-d)
0 commit comments