Skip to content

Improve devd scripts and bump version to 6.8#123

Merged
ericbsd merged 2 commits intomasterfrom
devd
Jan 21, 2026
Merged

Improve devd scripts and bump version to 6.8#123
ericbsd merged 2 commits intomasterfrom
devd

Conversation

@ericbsd
Copy link
Copy Markdown
Contributor

@ericbsd ericbsd commented Jan 21, 2026

  • Replace Popen with subprocess.run() for cleaner code and better resource handling across all devd scripts
  • Use proper raw string prefix (r"") for regex patterns
  • Remove deprecated close_fds parameter (default True in Python 3)
  • Change devd priority from 100 to 5 for faster event handling

auto-switch.py:

  • Create marker file /tmp/link-down-{nic} for coordination with link-up.py
  • Replace os.system() calls with subprocess.run()

link-up.py:

  • Simplify logic using marker file from auto-switch.py
  • Remove complex /tmp/network-{nic} state tracking
  • Use explicit service calls instead of shell command strings

setup-nic.py:

  • Use sysrc command instead of manual rc.conf file writing
  • Fix wlan configuration logic to check wlans_{nic} only once
  • Use appropriate pccard_ether action (startchildren for WiFi, start forEthernet)

Summary by Sourcery

Streamline devd-based NIC management scripts for link up/down handling and configuration, and bump the application version.

New Features:

  • Coordinate link-down and link-up handling using a temporary marker file to distinguish runtime link events from boot state.

Bug Fixes:

  • Correct regular expressions used to filter network interfaces and detect inet addresses in devd scripts.

Enhancements:

  • Simplify link-up handling logic to use explicit service calls and conditional netif restart instead of ad-hoc state files and shell command strings.
  • Refactor auto-switch and setup-nic scripts to use subprocess.run and sysrc for safer, more maintainable system interaction and configuration updates.
  • Adjust devd notification priority to a lower value for faster processing of network interface events.

Chores:

  • Bump the project version from 6.7 to 6.8.

- Replace Popen with subprocess.run() for cleaner code and better resource handling across all devd scripts
- Use proper raw string prefix (r"") for regex patterns
- Remove deprecated close_fds parameter (default True in Python 3)
- Change devd priority from 100 to 5 for faster event handling

auto-switch.py:
- Create marker file /tmp/link-down-{nic} for coordination with link-up.py
- Replace os.system() calls with subprocess.run()

link-up.py:
- Simplify logic using marker file from auto-switch.py
- Remove complex /tmp/network-{nic} state tracking
- Use explicit service calls instead of shell command strings

setup-nic.py:
- Use sysrc command instead of manual rc.conf file writing
- Fix wlan configuration logic to check wlans_{nic} only once
- Use appropriate pccard_ether action (startchildren for WiFi, start forEthernet)
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Jan 21, 2026

Reviewer's Guide

Refactors the devd helper scripts to use subprocess.run and more explicit service invocations, simplifies NIC/link state handling via a shared marker file, switches NIC setup to sysrc and proper pccard_ether actions, tightens regex usage, lowers devd notification priority to improve responsiveness, and bumps the package version to 6.8.

Sequence diagram for updated link state handling between auto-switch.py and link-up.py

sequenceDiagram
    participant devd
    participant networkmgr_conf
    participant auto_switch_py as auto-switch.py
    participant link_up_py as link-up.py
    participant netif_service as service_netif
    participant routing_service as service_routing
    participant dhclient_service as service_dhclient
    participant ifconfig_cmd as ifconfig
    participant sysrc_cmd as sysrc
    participant marker_file as tmp_link_down_nic

    devd->>networkmgr_conf: IFNET LINK_DOWN event
    networkmgr_conf->>auto_switch_py: exec auto-switch.py nic
    auto_switch_py->>ifconfig_cmd: ifconfig nic
    auto_switch_py->>sysrc_cmd: sysrc -n ifconfig_nic
    auto_switch_py->>auto_switch_py: evaluate link status and DHCP
    alt nic inactive and another nic active
        auto_switch_py->>netif_service: service netif stop nic
        auto_switch_py->>marker_file: create /tmp/link-down-nic
        alt nic uses DHCP
            auto_switch_py->>ifconfig_cmd: ifconfig other_nic
            auto_switch_py->>dhclient_service: service dhclient restart other_nic
        else nic uses static config
            auto_switch_py->>routing_service: service routing restart
        end
    else nic still active or no fallback
        auto_switch_py-->>devd: exit without changes
    end

    devd->>networkmgr_conf: IFNET LINK_UP event
    networkmgr_conf->>link_up_py: exec link-up.py nic
    alt marker file exists
        link_up_py->>marker_file: check /tmp/link-down-nic
        link_up_py->>ifconfig_cmd: ifconfig nic
        alt nic has no inet address
            link_up_py->>netif_service: service netif start nic
        end
        link_up_py->>routing_service: service routing restart
        link_up_py->>dhclient_service: service dhclient restart nic
        link_up_py->>marker_file: remove /tmp/link-down-nic
    else no marker file (boot or cold plug)
        link_up_py->>dhclient_service: service dhclient quietstart nic
    end
Loading

Flow diagram for updated setup-nic.py NIC configuration logic

flowchart TD
    A[start setup-nic.py with nic] --> B[Load rc_conf_content]
    B --> C[Check if nic matches wifi_driver_regex]
    C -->|wifi driver| D[Ensure wpa_supplicant.conf exists and permissions set]
    C -->|not wifi driver| K[Ethernet branch]

    D --> E[Check if wlans_nic entry exists in rc_conf_content]
    E -->|missing| F[For wlanNum in range 0..8]
    F --> G[Check if wlanN not in rc_conf_content]
    G -->|free wlanN| H[sysrc wlans_nic='wlanN']
    H --> I[sysrc ifconfig_wlanN='WPA DHCP']
    I --> J[Break loop]
    G -->|in use| F

    E -->|exists| L
    J --> L[Wifi configured]

    L --> M[Run /etc/pccard_ether nic startchildren]
    M --> N[exit]

    K --> O[Check if ifconfig_nic exists in rc_conf_content]
    O -->|missing| P[sysrc ifconfig_nic=DHCP]
    O -->|exists| Q
    P --> Q[Ethernet configured]

    Q --> R[Run /etc/pccard_ether nic start]
    R --> S[exit]
Loading

File-Level Changes

Change Details Files
Refactor link-up logic to use a link-down marker file and explicit service calls instead of ad‑hoc state files and shell command strings.
  • Replace Popen-based command execution with subprocess.run and drop close_fds where it is already the default.
  • Introduce a check for /tmp/link-down-{nic} to distinguish runtime link events from boot-time DHCP startup.
  • On marker presence, ensure interface has no inet address, bring netif up, then restart routing and dhclient explicitly via separate service calls.
  • On no marker, fall back to a lightweight dhclient quietstart to avoid unnecessary restarts.
  • Use raw string regex for NIC exclusion patterns.
src/link-up.py
Improve auto-switch behavior when a NIC goes down, using subprocess.run, a shared marker file, and safer regex patterns.
  • Replace Popen and os.system with subprocess.run, simplifying stdout handling via .stdout.
  • Fix and simplify the not_nics_regex and inet matching regexes using proper raw string syntax.
  • Create /tmp/link-down-{nic} when stopping a NIC so link-up.py can coordinate behavior.
  • When DHCP is enabled, iterate remaining NICs and restart dhclient only on an interface that is active/associated and has inet/inet6; otherwise just restart routing.
src/auto-switch.py
Change NIC setup to rely on sysrc and correct pccard_ether actions, while simplifying WLAN configuration probing.
  • Convert not_nics_regex to a raw string for correctness and consistency.
  • For WiFi NICs, only check wlans_{nic} once, then iterate wlan0–wlan8 to pick an unused wlanX, writing settings via sysrc instead of manually appending to rc.conf.
  • Call /etc/pccard_ether {nic} startchildren for WiFi NICs and /etc/pccard_ether {nic} start for Ethernet NICs.
  • For Ethernet NICs, create ifconfig_{nic}=DHCP using sysrc when not already present.
src/setup-nic.py
Adjust devd configuration priorities to make NIC events handled sooner.
  • Lower IFNET ATTACH, LINK_UP, LINK_DOWN notify blocks and wifi-driver attach block priority from 100 to 5 to run networkmgr helpers earlier in the devd queue.
src/networkmgr.conf
Bump project version to 6.8.
  • Update VERSION constant from 6.7 to 6.8.
setup.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • In link-up.py, the new subprocess.run(['ifconfig', nic], ...) call never requests a PIPE/captured output, so nic_ifconfig becomes None and the subsequent 'inet ' checks will fail; add stdout=PIPE (or capture_output=True) as done in the other scripts.
  • The updated not_nics_regex in auto-switch.py looks less strict than before (e.g., [0-9] instead of [0-9]+, and vm-[a-z] instead of vm-[a-z]+), which may cause valid interfaces to be filtered incorrectly; consider tightening this regex to match the previous intent.
  • In setup-nic.py, the sysrc call for Ethernet uses ifconfig_{nic}=DHCP without quotes while the WiFi-related sysrc calls use quoted values; align the Ethernet call (e.g., ifconfig_{nic}="DHCP") to avoid unexpected parsing differences.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In link-up.py, the new subprocess.run(['ifconfig', nic], ...) call never requests a PIPE/captured output, so nic_ifconfig becomes None and the subsequent 'inet ' checks will fail; add stdout=PIPE (or capture_output=True) as done in the other scripts.
- The updated not_nics_regex in auto-switch.py looks less strict than before (e.g., `[0-9]` instead of `[0-9]+`, and `vm-[a-z]` instead of `vm-[a-z]+`), which may cause valid interfaces to be filtered incorrectly; consider tightening this regex to match the previous intent.
- In setup-nic.py, the sysrc call for Ethernet uses ifconfig_{nic}=DHCP without quotes while the WiFi-related sysrc calls use quoted values; align the Ethernet call (e.g., ifconfig_{nic}="DHCP") to avoid unexpected parsing differences.

## Individual Comments

### Comment 1
<location> `src/link-up.py:22-26` </location>
<code_context>
     exit(0)

-nic_ifconfig = Popen(
+nic_ifconfig = run(
     ['ifconfig', nic],
     stdout=PIPE,
-    close_fds=True,
     universal_newlines=True
-).stdout.read()
+).stdout

-dhcp = Popen(
</code_context>

<issue_to_address>
**issue (bug_risk):** run() call for ifconfig never captures stdout, so nic_ifconfig will be None and the inet check will fail at runtime.

Because `run()` is called without `stdout=PIPE` (or `capture_output=True`), `CompletedProcess.stdout` will be `None`, and `'inet ' not in nic_ifconfig` will raise a `TypeError`. Add `stdout=PIPE` (and optionally `check=True`) to the `run()` call to match the previous `Popen` behavior of capturing output.
</issue_to_address>

### Comment 2
<location> `src/auto-switch.py:15-16` </location>
<code_context>

-not_nics_regex = r"(enc|lo|fwe|fwip|tap|plip|pfsync|pflog|ipfw|tun|sl|faith|wlan" \
-                    r"ppp|bridge|wg)[0-9]+(\s*)|vm-[a-z]+(\s*)"
+not_nics_regex = r"(enc|lo|fwe|fwip|tap|plip|pfsync|pflog|ipfw|tun|sl|faith|" \
+                    r"ppp|bridge|wg)[0-9]|vm-[a-z]"

-default_nic = Popen(
</code_context>

<issue_to_address>
**issue (bug_risk):** The updated not_nics_regex no longer matches full interface names correctly and is likely too permissive.

The previous pattern used `[0-9]+(\s*)` and `vm-[a-z]+(\s*)`, while the new one uses only `[0-9]` and `vm-[a-z]`. This now matches only single-digit suffixes / single-letter names, drops the optional trailing whitespace, and allows partial matches (e.g. only `lo1` from `lo10`). Restoring the `+` quantifier (and whitespace handling) or anchoring to the full interface name would avoid these incorrect and overly permissive matches.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

- Updated subprocess.run with `stdout=PIPE` for capturing output
- Removed unnecessary `close_fds` parameter (default True in Python 3)
@ericbsd ericbsd merged commit e2b3a3b into master Jan 21, 2026
1 check passed
@ericbsd ericbsd deleted the devd branch January 21, 2026 21:45
@github-project-automation github-project-automation bot moved this from To triage to Done in NetworkMGR Issue Traker Jan 21, 2026
@ericbsd ericbsd moved this from In Review to Done in Development Tracker Jan 21, 2026
@ericbsd ericbsd self-assigned this Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done
Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants