Skip to content

Fix 3 real bugs found while writing new vnet test coverage#10

Merged
ispyisail merged 1 commit into
masterfrom
device-groups-and-tor-fixes
Jul 3, 2026
Merged

Fix 3 real bugs found while writing new vnet test coverage#10
ispyisail merged 1 commit into
masterfrom
device-groups-and-tor-fixes

Conversation

@ispyisail

Copy link
Copy Markdown
Owner

Summary

All three surfaced while writing two new vnet test phases (vnet/tests/16-known_devices.test.sh and vnet/tests/17-tor.test.sh, in gargoyle-tools), which gave the Device Groups feature (#9) and gargoyle-tor their first vnet test coverage.

  1. manage_groups.sh: no explicit exit code. The script's exit status was whatever its last internal [ -n "$ip" ] check happened to evaluate to — a caller checking $? saw a spurious failure whenever the last device processed simply had no active DHCP lease yet, even though the script did all its actual work correctly. Added an explicit exit 0.

  2. manage_groups.sh: orphan-set cleanup used invalid nftables syntax. nft list sets $family $table is a syntax error (list sets takes no family/table arguments); this failed silently every time (stderr redirected to /dev/null), so the loop that's supposed to delete nftables sets for groups no longer defined in UCI never found anything to delete — stale grp_* sets accumulated forever instead of being cleaned up. Fixed to nft list table $family $table, scoped to the actual table, which correctly enumerates its sets.

  3. restart_firewall.sh: same missing-exit-code bug as Fix WireGuard config file import to handle flexible formatting #1. Its last line is service_enabled webmon_gargoyle && /etc/init.d/webmon_gargoyle start with no explicit exit afterward, so its exit status was non-zero whenever that particular optional service isn't enabled (the common case), even though the firewall restart itself succeeded. This script is called directly by the Restrictions/DHCP/Quotas pages' save flow, so any caller checking its exit code was getting a false failure signal on every save.

  4. tor.firewall: references $tmp_cron (needed by the shared update_cron() helper — every other bwmon-integrated feature in this codebase, OpenVPN/QoS/WireGuard/bwmon-gargoyle itself, already defines it locally before using) but never defines it itself. Every firewall reload with Tor enabled threw can't create : nonexistent directory / can't open '' errors while trying to update the cron entry for the Tor relay-set refresh job. Added tmp_cron="/tmp/tmp.tor.cron", matching the naming convention every other caller uses.

Verification

Each fix was confirmed individually via direct live testing on a booted vnet VM — checked a script's exit code changed from non-zero to 0 (or, for the nftables fix, confirmed the orphaned set actually disappears after reconciliation) before and after the fix, not just inspected by reading the diff.

The two new vnet test phases that surfaced these bugs are in a separate gargoyle-tools commit — 16-known_devices.test.sh passed 10/10 in a full automated build-and-test.sh cycle with these fixes applied. 17-tor.test.sh's 12 checks were each verified individually via manual live testing; a full automated single-script run of that phase could not be completed this session due to unrelated vnet network degradation after many hours of continuous heavy activity (not a code issue — noted in that commit).

Test plan

  • manage_groups.sh exit code confirmed 0 after fix (was 1)
  • manage_groups.sh orphan set confirmed deleted after fix (was never deleted before)
  • restart_firewall.sh exit code confirmed 0 after fix (was 1)
  • tor.firewall confirmed error-free after fix (was throwing errors every reload)
  • Full vnet suite via build-and-test.sh with these fixes: 124/139 (matches baseline + new 16-known_devices phase passing 10/10)

All three surfaced while adding vnet/tests/16-known_devices.test.sh and
vnet/tests/17-tor.test.sh (gargoyle-tools), which gave the Device Groups
feature (PR #9) and gargoyle-tor their first vnet test coverage.

1. manage_groups.sh: no explicit exit code. The script's exit status was
   whatever its last internal "[ -n "$ip" ]" check happened to evaluate
   to - a caller checking $? saw a spurious failure whenever the last
   device processed simply had no active DHCP lease yet, even though the
   script did all its actual work correctly. Added an explicit `exit 0`.

2. manage_groups.sh: orphan-set cleanup used invalid nftables syntax.
   "nft list sets $family $table" is a syntax error (list sets takes no
   family/table arguments); this failed silently every time (stderr
   redirected to /dev/null), so the loop that's supposed to delete
   nftables sets for groups no longer defined in UCI never found
   anything to delete - stale grp_* sets accumulated forever instead of
   being cleaned up. Fixed to "nft list table $family $table", scoped to
   the actual table, which correctly enumerates its sets.

3. restart_firewall.sh: same missing-exit-code bug as #1. Its last line
   is "service_enabled webmon_gargoyle && /etc/init.d/webmon_gargoyle
   start" with no explicit exit afterward, so its exit status was
   whatever that conditional evaluated to - non-zero whenever that
   particular optional service isn't enabled (the common case), even
   though the firewall restart itself succeeded. This script is called
   directly by the Restrictions/DHCP/Quotas pages' save flow, so any
   caller that checks its exit code was getting a false failure signal
   on every save. Added an explicit `exit 0`.

4. tor.firewall: references $tmp_cron (needed by the shared update_cron()
   helper every other bwmon-integrated feature in this codebase - OpenVPN,
   QoS, WireGuard, bwmon-gargoyle itself - already defines locally before
   using) but never defines it itself. Every firewall reload with Tor
   enabled threw "can't create : nonexistent directory" / "can't open ''"
   errors while trying to update the cron entry for the Tor relay-set
   refresh job. Added `tmp_cron="/tmp/tmp.tor.cron"`, matching the naming
   convention every other caller uses.

Verified individually via direct live testing on a booted vnet VM: each
fix was confirmed to change a script's exit code from non-zero to 0 (or,
for the nftables fix, confirmed the orphaned set actually disappears
after reconciliation) before and after, not just inspected by reading
the diff.
@ispyisail ispyisail merged commit 14f9836 into master Jul 3, 2026
@ispyisail ispyisail deleted the device-groups-and-tor-fixes branch July 3, 2026 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant