Skip to content

Add Windows automatic discovery support with WSDD#4491

Draft
madbrain76 wants to merge 9 commits intohome-assistant:masterfrom
madbrain76:fix-enable-windows-automatic-discovery
Draft

Add Windows automatic discovery support with WSDD#4491
madbrain76 wants to merge 9 commits intohome-assistant:masterfrom
madbrain76:fix-enable-windows-automatic-discovery

Conversation

@madbrain76
Copy link
Copy Markdown
Contributor

@madbrain76 madbrain76 commented Mar 14, 2026

This patch allows the HAOS system to automatically show up in the "Network" tab on Windows hosts.

To minimize impact, I chose to make the the new service startup failure non-fatal. It will just log a warning in this case. I can change it back. I could make it fatal if that's preferred.

Summary by CodeRabbit

  • New Features

    • Added Windows automatic discovery support (WSDD) for seamless device discovery on Windows networks.
  • Chores

    • Bundled WSDD into the runtime image and startup services.
    • Bumped app version to 12.7.0.
  • Stability

    • Improved service lifecycle handling so WSDD termination won’t cause the container to fail unexpectedly.
    • Added network interface detection with graceful warnings when no interfaces are enabled.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 28452636-bd6d-44ec-bafd-fd1d434e8680

📥 Commits

Reviewing files that changed from the base of the PR and between 851c85b and edd535d.

📒 Files selected for processing (1)
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run

📝 Walkthrough

Walkthrough

Adds Windows automatic discovery support by installing wsdd, bumps addon version to 12.7.0, and adds s6-overlay service files, run/finish scripts, and a network-interfaces helper to select enabled interfaces for wsdd.

Changes

Cohort / File(s) Summary
Changelog & config
samba/CHANGELOG.md, samba/config.yaml
Add ## 12.7.0 changelog entry ("Add Windows automatic discovery support with WSDD") and update version from 12.6.1 to 12.7.0.
Container image
samba/Dockerfile
Install wsdd alongside samba in the APK install step.
s6 service metadata
samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/type, samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/dependencies.d/init-smbd, samba/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/wsdd
Add service type (longrun) and empty dependency/user registration files for wsdd.
wsdd service scripts
samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run, samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/finish
Add run to determine enabled interfaces, hostname, and workgroup and exec wsdd with -i/-n/-w; add finish to log exit code/signal and handle SIGTERM path that may halt container.
Network interfaces helper & integration
samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/network-interfaces.sh, samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/run
Add get_enabled_interfaces() helper and source it from init-smbd/run, replacing inline interface enumeration with a single helper call.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant s6 as s6 (supervisor)
    participant init as init-smbd/run
    participant helper as network-interfaces.sh
    participant bashio as bashio (config/network)
    participant wsdd as wsdd daemon

    s6->>init: start init-smbd/run
    init->>helper: source + get_enabled_interfaces()
    helper->>bashio: query interfaces & enabled state
    bashio-->>helper: enabled interfaces list
    helper-->>init: return interfaces array
    init->>s6: continue startup (prepare wsdd args)
    s6->>wsdd: exec wsdd with -i (interfaces), -n (hostname), -w (workgroup)
    wsdd-->>s6: exit (code, signal)
    s6->>s6: run wsdd/finish logic (log, maybe halt)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Add Windows automatic discovery support with WSDD' directly and clearly describes the main feature addition - implementing Windows automatic discovery using the WSDD service.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

You can customize the tone of the review comments and chat replies.

Configure the tone_instructions setting to customize the tone of the review comments and chat replies. For example, you can set the tone to Act like a strict teacher, Act like a pirate and more.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/finish`:
- Around line 17-20: The finish script currently propagates a non-zero exit code
for signaled wsdd exits even when the container exit was previously healthy;
change the conditional that writes to
/run/s6-linux-init-container-results/exitcode so it only sets the propagated
signal exit (echo $((128 + exit_code_signal))) when other services already
indicated a non-zero container exit (i.e., require exit_code_container -ne 0) or
otherwise skip writing entirely for wsdd signal exits; update the conditional
around exit_code_service/exit_code_container/exit_code_signal in the wsdd finish
script accordingly so optional wsdd signal exits don’t taint the addon’s final
exit status.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b64f7bdb-1d82-410d-bded-eafb5b86ec3f

📥 Commits

Reviewing files that changed from the base of the PR and between 8437215 and 3627d20.

📒 Files selected for processing (8)
  • samba/CHANGELOG.md
  • samba/Dockerfile
  • samba/config.yaml
  • samba/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/wsdd
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/dependencies.d/init-smbd
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/finish
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/type

@home-assistant home-assistant bot marked this pull request as draft March 17, 2026 16:34
@home-assistant
Copy link
Copy Markdown

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@madbrain76 madbrain76 marked this pull request as ready for review March 19, 2026 10:26
@home-assistant home-assistant bot requested a review from agners March 19, 2026 10:26
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run (1)

20-21: Add a defensive fallback for empty workgroup.

If Line 20 resolves to an empty value, wsdd starts with -w "". Consider a safe default to avoid misconfiguration-driven startup issues.

Proposed hardening
 workgroup=$(bashio::config 'workgroup')
+if bashio::var.is_empty "${workgroup}"; then
+    bashio::log.warning "Can't read workgroup, using default."
+    workgroup="WORKGROUP"
+fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run` around lines 20 - 21, The
workgroup variable read via workgroup=$(bashio::config 'workgroup') can be empty
and produce a wsdd invocation like -w ""—add a defensive fallback after that
assignment: check if variable is empty (e.g., test -z "$workgroup") and if so
assign a sensible default (e.g., WORKGROUP or a configurable DEFAULT_WORKGROUP),
then use that variable when starting wsdd; update the run script's wsdd
invocation to rely on this validated workgroup variable (reference: workgroup
variable and the wsdd start invocation in the run script).
samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/network-interfaces.sh (1)

12-12: Prefer line-safe iteration over word-splitting for interface enumeration.

Line 12 iterates using for interface in $(...), which applies word-splitting and globbing to the output. While Linux interface names typically don't contain problematic characters, using while IFS= read -r is safer and follows Bash best practices.

Refactor suggestion
-    for interface in $(bashio::network.interfaces); do
-        interface_enabled=$(bashio::network.enabled "${interface}")
-        if bashio::var.true "${interface_enabled}"; then
-            _out_interfaces+=("${interface}")
-        fi
-    done
+    while IFS= read -r interface; do
+        interface_enabled=$(bashio::network.enabled "${interface}")
+        if bashio::var.true "${interface_enabled}"; then
+            _out_interfaces+=("${interface}")
+        fi
+    done < <(bashio::network.interfaces)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/network-interfaces.sh` at line
12, The for-loop using command substitution over bashio::network.interfaces
should be replaced with a line-safe reader loop: read each interface into the
variable interface using a while IFS= read -r loop that consumes the output of
bashio::network.interfaces (via a pipe or process substitution) to avoid
word-splitting and globbing; update the loop that references interface so its
body behavior remains identical (keep any commands that follow unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/network-interfaces.sh`:
- Line 12: The for-loop using command substitution over
bashio::network.interfaces should be replaced with a line-safe reader loop: read
each interface into the variable interface using a while IFS= read -r loop that
consumes the output of bashio::network.interfaces (via a pipe or process
substitution) to avoid word-splitting and globbing; update the loop that
references interface so its body behavior remains identical (keep any commands
that follow unchanged).

In `@samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run`:
- Around line 20-21: The workgroup variable read via workgroup=$(bashio::config
'workgroup') can be empty and produce a wsdd invocation like -w ""—add a
defensive fallback after that assignment: check if variable is empty (e.g., test
-z "$workgroup") and if so assign a sensible default (e.g., WORKGROUP or a
configurable DEFAULT_WORKGROUP), then use that variable when starting wsdd;
update the run script's wsdd invocation to rely on this validated workgroup
variable (reference: workgroup variable and the wsdd start invocation in the run
script).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb280353-25b6-44a0-8fd6-ed6b9b3a01a5

📥 Commits

Reviewing files that changed from the base of the PR and between 3627d20 and 91c42c0.

📒 Files selected for processing (6)
  • samba/CHANGELOG.md
  • samba/config.yaml
  • samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/network-interfaces.sh
  • samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/run
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/finish
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run
✅ Files skipped from review due to trivial changes (2)
  • samba/config.yaml
  • samba/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/finish

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run (2)

35-37: Simplify log formatting to avoid trailing whitespace

$(printf '%s ' ...) leaves a trailing space and splits message construction across two args. A single string is cleaner and more predictable.

Proposed diff
-bashio::log.info \
-    "Starting the WSDD daemon on interfaces: $(printf '%s ' "${interfaces[@]}")" \
-    "for ${workgroup}/${hostname}"
+bashio::log.info \
+    "Starting the WSDD daemon on interfaces: ${interfaces[*]} for ${workgroup}/${hostname}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run` around lines 35 - 37, The log
call splits the message across two arguments and uses printf '%s ' which leaves
a trailing space; replace the two-argument call and the printf with a single
quoted string that joins the interfaces without trailing whitespace (e.g. use
"${interfaces[*]}") so update the bashio::log.info invocation to a single string
like: bashio::log.info "Starting the WSDD daemon on interfaces: ${interfaces[*]}
for ${workgroup}/${hostname}".

21-21: Add an empty-value guard for workgroup to match hostname validation

Line 21 reads workgroup from config without validating it, unlike hostname which has a guard on lines 17–20. If a user sets workgroup to an empty string, line 39 will invoke wsdd with -w "", which is invalid and can trigger restart churn. The schema does not enforce a non-empty value (it is defined as plain str). Add a guard defaulting to WORKGROUP when empty, consistent with the hostname fallback pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run` at line 21, The workgroup value
read into the variable workgroup via bashio::config should be guarded for empty
strings like the hostname handling: detect if workgroup is empty or unset and
default it to the constant WORKGROUP before use, so that the wsdd invocation
(which passes -w "$workgroup") never receives an empty argument; update the run
script's workgroup assignment to perform the empty-value check and assignment
similar to the hostname guard to prevent invalid `-w ""` calls and restart
churn.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run`:
- Around line 35-37: The log call splits the message across two arguments and
uses printf '%s ' which leaves a trailing space; replace the two-argument call
and the printf with a single quoted string that joins the interfaces without
trailing whitespace (e.g. use "${interfaces[*]}") so update the bashio::log.info
invocation to a single string like: bashio::log.info "Starting the WSDD daemon
on interfaces: ${interfaces[*]} for ${workgroup}/${hostname}".
- Line 21: The workgroup value read into the variable workgroup via
bashio::config should be guarded for empty strings like the hostname handling:
detect if workgroup is empty or unset and default it to the constant WORKGROUP
before use, so that the wsdd invocation (which passes -w "$workgroup") never
receives an empty argument; update the run script's workgroup assignment to
perform the empty-value check and assignment similar to the hostname guard to
prevent invalid `-w ""` calls and restart churn.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e9cb2dc1-5a62-4066-a265-f26566a1a51b

📥 Commits

Reviewing files that changed from the base of the PR and between 91c42c0 and 851c85b.

📒 Files selected for processing (2)
  • samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/run
  • samba/rootfs/etc/s6-overlay/s6-rc.d/wsdd/run
🚧 Files skipped from review as they are similar to previous changes (1)
  • samba/rootfs/etc/s6-overlay/s6-rc.d/init-smbd/run

if [[ "${exit_code_container}" -eq 0 ]]; then
echo $((128 + exit_code_signal)) > /run/s6-linux-init-container-results/exitcode
fi
exec /run/s6/basedir/bin/halt
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This part feels a bit overengineered to me, but I am fine with it. I mostly meant we should not shutdown the container on regular failure, but what coderabbit suggested was a bit more elaborate 😅

exec /run/s6/basedir/bin/halt
elif [[ "${exit_code_service}" -eq 256 ]]; then
bashio::log.warning \
"Optional service ${service} exited by signal ${exit_code_signal}; continuing without Windows discovery."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In this...

"Optional service ${service} exited by signal ${exit_code_signal}; continuing without Windows discovery."
elif [[ "${exit_code_service}" -ne 0 ]]; then
bashio::log.warning \
"Optional service ${service} failed; continuing without Windows discovery."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

... and this case s6 will simply restart the service again. If we want it to remain stopped we need to exit the finish script with exit code 125 (permanent failure). And I'd make use of that here, since that is what the warning suggests is what we want to happen.

@home-assistant home-assistant bot marked this pull request as draft March 25, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants