Skip to content

feat(w0-pr4): same-subnet ghost detector in both probe scripts - #1481

Merged
POWERFULMOVES merged 1 commit into
mainfrom
feat/w0-pr4-ghost-detector
May 15, 2026
Merged

POWERFULMOVES merged 1 commit into
mainfrom
feat/w0-pr4-ghost-detector

Conversation

@POWERFULMOVES

Copy link
Copy Markdown
Owner

Summary

  • Adds Get-NicCollisions (PowerShell) and detect_nic_collisions (bash) — both use the detection steps from SAME_SUBNET_GHOST_PATTERN.md
  • Wires nic_collisions: [{primary, ghost, subnet}] into JSON output of both scripts
  • Adds NIC Collision Check section to interactive reports with remediation pointer
  • Schema comments use <placeholder> format — no hardcoded IPs
  • Empty array on clean hosts; populated when a disconnected/ghost adapter shares a /24 with an active adapter

Rationale

Docker Desktop on Windows silently no-ops port binds when a ghost adapter owns the routing table entry for the LAN subnet. This detector surfaces the condition at onboarding time (pre-provision), before the operator spins up the Docker stack, giving them the fix path before the bug manifests.

Test plan

  • .\glances-autodetect.ps1 --json — verify nic_collisions field present, empty array on clean host
  • .\glances-autodetect.ps1 (interactive) — verify "NIC Collision Check" section shows "No same-subnet ghost adapters detected" in green
  • On a host with a disconnected secondary NIC in the LAN /24: verify collision entry appears with correct primary/ghost/subnet values
  • sudo bash glances-autodetect.sh --json — verify nic_collisions field present
  • sudo bash glances-autodetect.sh (interactive) — verify collision section renders
  • JSON schema: confirm no IP addresses in committed source, only <placeholder> format

Depends on

PR-3 (#1476) — base branch feat/w0-pr3-windows-glances-probe

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@POWERFULMOVES has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 58 minutes and 37 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bb3f17fc-8591-45d8-bd32-8513090e0772

📥 Commits

Reviewing files that changed from the base of the PR and between f26c477 and 0521a76.

📒 Files selected for processing (2)
  • deploy/provision/glances-autodetect.ps1
  • deploy/provision/glances-autodetect.sh
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/w0-pr4-ghost-detector

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5966bc8fde

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +236 to +239
$netKey = if ($pl -ge 24) {
"$($bytes[0]).$($bytes[1]).$($bytes[2]).0/$pl"
} elseif ($pl -ge 16) {
"$($bytes[0]).$($bytes[1]).0.0/$pl"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Derive subnet key using real IPv4 mask math

Get-NicCollisions builds netKey by zeroing whole octets instead of applying the exact prefix mask, so prefixes like /25, /23, or /20 collapse distinct networks into one key (for example, both halves of 192.168.1.0/25 map to the same key). This creates false nic_collisions on valid segmented networks and can send operators to unnecessary remediation steps.

Useful? React with 👍 / 👎.

Comment on lines +445 to +449
for subnet, members in entries.items():
if len(members) < 2: continue
primary = members[0]
for ghost in members[1:]:
print(f"{primary[0]}|{primary[1]}|{ghost[0]}|{ghost[1]}|{subnet}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Filter collision pairs by link state before labeling ghosts

The Linux detector marks members[0] as primary and every other member as ghost without checking whether each interface is actually down/disconnected, so hosts with two active NICs in the same subnet (or different ip output ordering) are still reported as ghost collisions. Because this path feeds both the warning text and nic_collisions JSON, it yields misleading diagnostics in normal multi-NIC configurations.

Useful? React with 👍 / 👎.

@POWERFULMOVES
POWERFULMOVES deleted the branch main May 15, 2026 21:56
@POWERFULMOVES POWERFULMOVES reopened this May 15, 2026
@POWERFULMOVES
POWERFULMOVES changed the base branch from feat/w0-pr3-windows-glances-probe to main May 15, 2026 21:59
@POWERFULMOVES
POWERFULMOVES force-pushed the feat/w0-pr4-ghost-detector branch from 5966bc8 to af0e071 Compare May 15, 2026 22:00
Add Get-NicCollisions (PS1) and detect_nic_collisions (bash) and wire
them fully into: JSON output (nic_collisions field), interactive report
(NIC Collision Check section with remediation link), and schema comments
(placeholder format, no hardcoded IPs).

Both scripts now emit nic_collisions: [{primary, ghost, subnet}] — empty
array on healthy hosts, populated when same-subnet ghost adapters are
detected per SAME_SUBNET_GHOST_PATTERN.md detection steps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@POWERFULMOVES
POWERFULMOVES force-pushed the feat/w0-pr4-ghost-detector branch from af0e071 to 0521a76 Compare May 15, 2026 22:01
@POWERFULMOVES
POWERFULMOVES merged commit b261649 into main May 15, 2026
10 checks passed
@POWERFULMOVES
POWERFULMOVES deleted the feat/w0-pr4-ghost-detector branch May 15, 2026 22:01
POWERFULMOVES added a commit that referenced this pull request May 19, 2026
…detector (#1537)

Addresses Codex P1 + P2 findings from PR #1535 (closed as superseded by
#1476+#1481). Same bugs apply to main's version, so fixing directly.

deploy/provision/glances-autodetect.ps1 (P1):
  Get-NicCollisions previously truncated network keys to whole-octet boundaries
  (/24, /16, /8) regardless of actual PrefixLength. This mis-grouped /23, /20,
  /25, etc. — missing real same-subnet adapter collisions on non-/24 networks
  and creating false ones on partial-octet masks. Now builds a true CIDR
  network mask via bitwise AND on each byte using the actual PrefixLength.

deploy/provision/glances-autodetect.sh (P2):
  The Python collision detector treated every additional IP in a subnet as a
  ghost regardless of interface identity. A single NIC with multiple IPv4
  addresses (IP aliasing / secondary IPs) was reported as a collision, even
  though no competing adapter exists. Now requires at least 2 distinct
  interfaces in the subnet group before flagging, and skips same-interface
  aliases inside the loop.

Verification (Linux fix, Python simulation):
  - same-iface alias only (eth0, eth0)            → 0 ghosts ✓
  - distinct-iface collision (eth0, eth1)         → 1 ghost  ✓
  - mixed: 1 alias + 1 ghost (eth0, eth0, eth1)   → 1 ghost  ✓

Cross-lane on behalf of W0 substrate (4090 / Z890 lane historically).

Co-authored-by: Shaela Bello <slbello@uncg.edu>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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