Per-drive SMB share name suffix - #189
Merged
Merged
Conversation
The share is now usb_backup_<suffix> (serial tail, or vid+pid when the stick has no serial; SMB-safe [a-z0-9]) mirroring the sendspin client naming, stable per medium across replugs. The drawer shows the live name; existing HA entries need their share field updated once. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Mount adoption can associate the running share with a different drive’s derived name.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds stable per-drive SMB share names derived from USB identity and exposes them in storage state and the UI.
Changes:
- Derives and configures per-drive share names.
- Propagates share names through server state and broadcasts.
- Updates UI display and test coverage.
File summaries
| File | Description |
|---|---|
lib/universal_proxy/storage/smbd.ex |
Implements share-name derivation and configuration. |
lib/universal_proxy/storage/server.ex |
Integrates names into storage lifecycle and state. |
lib/universal_proxy/storage.ex |
Extends default storage state. |
lib/universal_proxy_web/components/storage.ex |
Displays the live share name. |
test/support/storage_stub.ex |
Updates stub state shape. |
test/universal_proxy/storage/smbd_test.exs |
Tests derivation and configuration. |
test/universal_proxy/storage/server_test.exs |
Tests server integration. |
test/universal_proxy/storage_test.exs |
Updates default-state assertions. |
test/universal_proxy_web/live/overview_live_test.exs |
Tests UI rendering and fallback. |
Review details
- Files reviewed: 9/9 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Naming used the pre-adoption list head, so a mount adopted mid-pass could start the share under another drive's name; resolution now goes through the mounted_ref/owns_device chain like share_folder does. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The implementation matches the documented derivation rules, covers the full state flow, and resolves the prior drive-selection issue.
Review details
- Files reviewed: 9/9 changed files
- Comments generated: 0 new
- Review effort level: Balanced
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rationale
The USB backup SMB share was always named the global
usb_backup, so only one drive at a time could ever have a share (or, worse, two different sticks in sequence would collide on the same share name/credentials at the OS/mDNS level Home Assistant sees). This mirrors the sendspin-client naming work (#172,sendspin_dual_role_mdns_collision) by giving the share a stable per-drive suffix instead.Derivation rules
Share name =
usb_backup_<suffix>, mirroringStorage.Server's drive-key stability semantics:[a-z0-9].vendor_id/product_idas lowercase 4-digit hex, concatenated (e.g.09306545).~r/^[a-z0-9]{2,16}$/— a conservative, SMB-safe charset.What changed
UniversalProxy.Storage.Smbd.share_name/1/share_suffix/1— the new pure derivation, with doctests.Smbd.config/1takes an optional:share_nameparam (default stays bare"usb_backup"for backward compatibility); the[…]section header uses it.Storage.Serverderives the mounted drive's share name every convergence pass (mirroring howshare_folderis refreshed), threads it intoprepare_runtime/2's params, and includesshare_namein the broadcast state payload.share_namefrom the payload, falling back to plainusb_backuptext if it's evernil.UniversalProxy.ESPHome.EntityProviderdoesn't reference the share name anywhere, so it's untouched.HA-entry migration note
Any existing Home Assistant backup-location entry pointing at
\\<host>\usb_backupwill need its share field updated to the new per-drive name (visible in the drawer, or derivable from the drive's serial/vid/pid) after this ships — the old bare name no longer exists once a drive is re-provisioned.Gate results
mix format— cleanmix compile --warnings-as-errors— cleantest/universal_proxy/storage/,storage_test.exs,overview_live_test.exs): 393 passed (6 doctests, 387 tests)mise run test: 1634 passed (8 doctests, 1626 tests), 3 excludedmise exec -- sh -c 'MIX_TARGET=host MIX_ENV=dev mix dialyzer'— passed successfully, 0 errors🤖 Generated with Claude Code