Skip to content

[client] Persist service install parameters across reinstalls#5732

Merged
lixmal merged 2 commits intomainfrom
client/persist-service-params
Mar 30, 2026
Merged

[client] Persist service install parameters across reinstalls#5732
lixmal merged 2 commits intomainfrom
client/persist-service-params

Conversation

@lixmal
Copy link
Copy Markdown
Collaborator

@lixmal lixmal commented Mar 30, 2026

Describe your changes

When users run netbird service uninstall followed by netbird service install (or use --reconfigure), custom flags like --log-level, --management-url, --disable-profiles, and --service-env were lost. Users had to remember and re-specify every flag.

This adds a service.json file in the state directory that saves install-time parameters and restores them on the next install/reconfigure when the corresponding flag is not explicitly set.

  • Save service parameters to <stateDir>/service.json after install and reconfigure
  • On install/reconfigure, load saved params and apply them to any flag not explicitly set by the user
  • Explicit flags always win over saved values (uses cobra's Changed() to detect)
  • Explicit clears work: --management-url "" or --disable-profiles=false persist the cleared state
  • Add netbird service reset-params command to remove the saved file
  • Env vars (--service-env) merge: saved keys carry over, explicit keys win on conflict
  • AST-based sync tests that fail if a new struct field isn't wired into save/apply/build functions

Issue ticket number and link

Stack

Checklist

  • Is a feature enhancement
  • Is it a bug fix
  • Is a typo/documentation fix
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

The feature is transparent to users: existing behavior is preserved, parameters are just remembered automatically.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

  • New Features

    • Added reset-params command to clear saved service install parameters.
    • Service install parameters (log level, daemon address, management URL, config, log files, env vars, disable flags) persist across runs and are automatically reapplied during install and reconfigure. Explicit CLI values take precedence when provided.
  • Behavior

    • Failures to load or save persistent parameters now emit warnings without aborting install/reconfigure.
  • Tests

    • Added unit tests validating persistence, flag application, and env-var merging.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Adds persistent service install parameters stored as JSON in the state directory, applies saved values to CLI flags only when flags were not explicitly changed, integrates load/save into install/reconfigure flows, and adds a reset-params command to remove saved parameters.

Changes

Cohort / File(s) Summary
Service Command Registration
client/cmd/service.go
Registers the new reset-params subcommand with the service command.
Service Installer Integration
client/cmd/service_installer.go
Calls loadAndApplyServiceParams(cmd) at the start of install and reconfigure; calls saveServiceParams(currentServiceParams()) after successful s.Install(); errors are warned to stderr but do not abort success path.
Service Parameter Core Logic
client/cmd/service_params.go
New non-mobile implementation adding serviceParams persistence to <state>/service.json, functions to load/save/apply params, flag-aware application (uses Flag.Changed()), env-var merge logic, reset-params command, and helpers like envMapToSlice.
Service Parameter Tests
client/cmd/service_params_test.go
New tests covering path derivation, save/load fidelity, missing/invalid-file behavior, currentServiceParams(), applyServiceParams() behavior with Flag.Changed(), boolean and empty-value handling, env-var merge behavior, and AST checks ensuring struct fields are wired into functions and installer usage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • pappz

Poem

🐰 I tuck configs safe in a JSON nest,

Old flags stay cozy, new flags take the best,
If mixes of env-vars cause a fuss,
Explicit wins — that's fair to us.
Delete my stash with a hop and a dance, and off I scurry, full of chance.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding persistence of service install parameters across reinstalls.
Description check ✅ Passed The description comprehensively explains the changes, includes a detailed checklist with the appropriate items checked, provides documentation rationale, and confirms CLA agreement.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch client/persist-service-params

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.

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

🧹 Nitpick comments (1)
client/cmd/service_installer.go (1)

122-124: Consider extracting repeated warning blocks into a small helper.

The same load/save warning pattern appears in both commands. A helper would reduce duplication and keep messaging consistent.

♻️ Optional refactor sketch
+func warnLoadServiceParams(cmd *cobra.Command, err error) {
+	if err != nil {
+		cmd.PrintErrf("Warning: failed to load saved service params: %v\n", err)
+	}
+}
+
+func warnSaveServiceParams(cmd *cobra.Command, err error) {
+	if err != nil {
+		cmd.PrintErrf("Warning: failed to save service params: %v\n", err)
+	}
+}
...
-		if err := loadAndApplyServiceParams(cmd); err != nil {
-			cmd.PrintErrf("Warning: failed to load saved service params: %v\n", err)
-		}
+		warnLoadServiceParams(cmd, loadAndApplyServiceParams(cmd))
...
-		if err := saveServiceParams(currentServiceParams()); err != nil {
-			cmd.PrintErrf("Warning: failed to save service params: %v\n", err)
-		}
+		warnSaveServiceParams(cmd, saveServiceParams(currentServiceParams()))

Also applies to: 143-145, 198-200, 237-239

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

In `@client/cmd/service_installer.go` around lines 122 - 124, Extract the repeated
"load/save warning" pattern into a small helper to reduce duplication: create a
function (e.g. handleServiceParamWarning(cmd *cobra.Command, action string, err
error) or printServiceParamWarn(cmd *cobra.Command, action string, err error))
that checks err and calls cmd.PrintErrf with a consistent message like "Warning:
failed to %s saved service params: %v\n", then replace the repeated blocks
around loadAndApplyServiceParams and the corresponding save calls (references:
loadAndApplyServiceParams, and the save-related calls at the other occurrences)
to call this helper instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@client/cmd/service_params.go`:
- Around line 21-23: Update the struct comment for serviceParams to refer to the
correct directory name: change the path wording from "<configDir>/service.json"
to use the resolved state directory (e.g., "<stateDir>/service.json" or mention
configs.StateDir) so the comment matches how the file is actually resolved; edit
the comment immediately above the serviceParams type to make this replacement.

---

Nitpick comments:
In `@client/cmd/service_installer.go`:
- Around line 122-124: Extract the repeated "load/save warning" pattern into a
small helper to reduce duplication: create a function (e.g.
handleServiceParamWarning(cmd *cobra.Command, action string, err error) or
printServiceParamWarn(cmd *cobra.Command, action string, err error)) that checks
err and calls cmd.PrintErrf with a consistent message like "Warning: failed to
%s saved service params: %v\n", then replace the repeated blocks around
loadAndApplyServiceParams and the corresponding save calls (references:
loadAndApplyServiceParams, and the save-related calls at the other occurrences)
to call this helper instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ffec0aab-2b57-4fbc-9b02-271385099d3c

📥 Commits

Reviewing files that changed from the base of the PR and between 13807f1 and 30f63e9.

📒 Files selected for processing (4)
  • client/cmd/service.go
  • client/cmd/service_installer.go
  • client/cmd/service_params.go
  • client/cmd/service_params_test.go

Comment thread client/cmd/service_params.go
@sonarqubecloud
Copy link
Copy Markdown

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 (1)
client/cmd/service_params.go (1)

195-200: Consider deterministic ordering for envMapToSlice output.

envMapToSlice currently relies on map iteration order, which can produce different serialization across runs. While environment variables are converted back to a map when used, deterministic ordering improves reproducibility and simplifies debugging.

♻️ Proposed refactor
 import (
 	"context"
 	"encoding/json"
 	"fmt"
 	"maps"
 	"os"
 	"path/filepath"
+	"sort"
@@
 func envMapToSlice(m map[string]string) []string {
-	s := make([]string, 0, len(m))
-	for k, v := range m {
+	keys := make([]string, 0, len(m))
+	for k := range m {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+
+	s := make([]string, 0, len(keys))
+	for _, k := range keys {
+		v := m[k]
 		s = append(s, k+"="+v)
 	}
 	return s
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@client/cmd/service_params.go` around lines 195 - 200, envMapToSlice relies on
Go map iteration order causing non-deterministic output; make it deterministic
by extracting map keys, sorting them (e.g., using sort.Strings), then building
the []string in that sorted key order; update the function envMapToSlice to
gather keys from the input map[string]string, sort the keys, and append
"key=value" pairs in sorted order so the returned slice is reproducible.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@client/cmd/service_params.go`:
- Around line 195-200: envMapToSlice relies on Go map iteration order causing
non-deterministic output; make it deterministic by extracting map keys, sorting
them (e.g., using sort.Strings), then building the []string in that sorted key
order; update the function envMapToSlice to gather keys from the input
map[string]string, sort the keys, and append "key=value" pairs in sorted order
so the returned slice is reproducible.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4e14c42f-92d1-4050-9d4a-29f683e30547

📥 Commits

Reviewing files that changed from the base of the PR and between 30f63e9 and 1388049.

📒 Files selected for processing (1)
  • client/cmd/service_params.go

@lixmal lixmal merged commit 04dcaad into main Mar 30, 2026
41 of 44 checks passed
@lixmal lixmal deleted the client/persist-service-params branch March 30, 2026 14:25
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.

2 participants