Skip to content

fix(tvOS): use writable local paths for prefs, auth config, and Go state - #191

Open
CicerBro wants to merge 4 commits into
netbirdio:mainfrom
CicerBro:pr/tvos-writable-paths
Open

fix(tvOS): use writable local paths for prefs, auth config, and Go state#191
CicerBro wants to merge 4 commits into
netbirdio:mainfrom
CicerBro:pr/tvos-writable-paths

Conversation

@CicerBro

@CicerBro CicerBro commented Aug 10, 2026

Copy link
Copy Markdown

What this fixes

Several tvOS failures share one root cause: App Group containers and related default paths are not usable the way they are on iOS.

  1. Preferences / device name — App-group UserDefaults do not work on tvOS (cfprefsd detaches), so shared prefs and the cached device name silently read as nil. DEBUG fallbacks under Application Support also fail because that directory is read-only in the sandbox.
  2. Management server / authNetBirdSDKNewAuth creates/updates netbird.cfg at the given path before SSO. That path came from the App Group container, so changing the management server failed with EPERM before UserDefaults/IPC fallbacks ran.
  3. Extension state persistence — The Go client was created with an empty state path, so the state manager wrote temp files into the extension CWD (read-only) and logged repeating EPERM errors about every 10 seconds.

Change

  • Use UserDefaults.standard on tvOS and writable Caches for DEBUG file-path fallbacks.
  • Point configFile() at caches as scratch space for NewAuth (persistence stays UserDefaults + IPC).
  • Point stateFile() at caches and pass it into NetBirdSDKNewClient so the Go state manager has a writable location.

Summary by CodeRabbit

  • Bug Fixes
    • Improved tvOS device-name persistence and synchronization.
    • Updated tvOS configuration and state storage to use writable cache locations.
    • Added safer fallback handling when cache directories are unavailable.
    • Prevented network services from starting without a valid writable state location.

App-group UserDefaults are non-functional on tvOS, so shared preferences
and the cached device name silently failed. Prefer UserDefaults.standard
and a writable Caches fallback in DEBUG.
NetBirdSDKNewAuth creates or updates netbird.cfg at the given path
before the SSO check runs. On tvOS the path came from the App Group
container, which is not writable, so changing the management server
failed with EPERM before the UserDefaults fallbacks could run. Point
configFile() at the caches directory on tvOS instead, mirroring the
stateFile() treatment — persistence on tvOS goes through UserDefaults
and IPC, not this file.
Empty state paths made the state manager write temp files into the
extension CWD, which is read-only and failed with EPERM every 10s.
Copilot AI lite review requested due to automatic review settings August 10, 2026 19:48
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a27124eb-6272-4df5-a288-9df58c3a872e

📥 Commits

Reviewing files that changed from the base of the PR and between 5e68621 and ac6352d.

📒 Files selected for processing (3)
  • NetbirdKit/Device.swift
  • NetbirdKit/Preferences.swift
  • NetbirdNetworkExtension/NetBirdAdapter.swift

📝 Walkthrough

Walkthrough

tvOS storage now uses writable Caches or temporary directories, with standard process-local defaults. Device-name persistence uses the shared defaults. Network extension initialization validates and passes the resolved state path to the SDK.

Changes

tvOS storage and device persistence

Layer / File(s) Summary
tvOS storage and device persistence
NetbirdKit/Preferences.swift, NetbirdKit/Device.swift
tvOS config and state paths now use writable Caches with temporary-directory fallback. tvOS defaults use UserDefaults.standard. Device-name persistence uses shared defaults.
Validated tvOS client initialization
NetbirdNetworkExtension/NetBirdAdapter.swift
Initialization stops when Preferences.stateFile() returns an empty path. The validated path is passed to NetBirdSDKNewClient.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant NetBirdAdapter
  participant Preferences
  participant UserDefaults
  participant NetBirdSDKNewClient

  NetBirdAdapter->>Preferences: request stateFile()
  Preferences-->>NetBirdAdapter: return writable state path
  NetBirdAdapter->>NetBirdSDKNewClient: initialize with state path
  Preferences->>UserDefaults: use standard defaults for tvOS
Loading

Possibly related PRs

Suggested reviewers: evgeniychepelev

Poem

A rabbit checks the cache with care,
Finds writable paths waiting there.
Device names hop into defaults,
The SDK starts with state it trusts.
tvOS paths now guide the way.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the tvOS path changes for preferences, authentication configuration, and Go state.
Description check ✅ Passed The description clearly explains the tvOS failures, root causes, and changes that address them.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copilot AI 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.

Pull request overview

Fixes tvOS-specific sandbox/path issues by switching preference storage and SDK file paths away from App Group locations that are not usable on tvOS, ensuring config/auth setup and Go state persistence have writable locations.

Changes:

  • Pass a writable state path into NetBirdSDKNewClient on tvOS to prevent Go state persistence failures.
  • Adjust Preferences to use tvOS-appropriate UserDefaults and to place config/state files in writable locations.
  • Update tvOS device-name caching to use the shared defaults abstraction.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
NetbirdNetworkExtension/NetBirdAdapter.swift Passes a state path into the tvOS SDK client initialization to avoid EPERM persistence errors.
NetbirdKit/Preferences.swift Updates tvOS defaults handling and redirects config/state paths to writable directories.
NetbirdKit/Device.swift Uses Preferences.sharedUserDefaults() for tvOS device-name persistence.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread NetbirdKit/Preferences.swift
Comment thread NetbirdKit/Preferences.swift
Comment thread NetbirdNetworkExtension/NetBirdAdapter.swift Outdated
Comment thread NetbirdKit/Device.swift Outdated
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.

3 participants