From 1e9dcc19861e8de8977c9480389461636438e5dc Mon Sep 17 00:00:00 2001 From: Siyuan Date: Fri, 31 Oct 2025 17:37:25 +0000 Subject: [PATCH] feat: allow configuration to be reset during update --- internal/ota/ota.go | 8 ++++++++ internal/ota/state.go | 6 ++++++ jsonrpc.go | 2 +- ota.go | 6 ++++-- ui/src/routes/devices.$id.settings.advanced.tsx | 4 ++++ ui/src/routes/devices.$id.settings.general.update.tsx | 2 ++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/internal/ota/ota.go b/internal/ota/ota.go index 9e40e840..194c8959 100644 --- a/internal/ota/ota.go +++ b/internal/ota/ota.go @@ -177,6 +177,13 @@ func (s *State) doUpdate(ctx context.Context, params UpdateParams) error { if s.rebootNeeded { scopedLogger.Info().Msg("System Rebooting due to OTA update") + if params.ResetConfig { + scopedLogger.Info().Msg("Resetting config") + if err := s.resetConfig(); err != nil { + return s.componentUpdateError("Error resetting config", err, &scopedLogger) + } + } + postRebootAction := &PostRebootAction{ HealthCheck: "/device/status", RedirectUrl: fmt.Sprintf("/settings/general/update?version=%s", systemUpdate.version), @@ -198,6 +205,7 @@ type UpdateParams struct { Components []string `json:"components,omitempty"` IncludePreRelease bool `json:"includePreRelease"` CheckOnly bool `json:"checkOnly"` + ResetConfig bool `json:"resetConfig"` } func (s *State) getUpdateStatus( diff --git a/internal/ota/state.go b/internal/ota/state.go index 0406b926..a11a50f9 100644 --- a/internal/ota/state.go +++ b/internal/ota/state.go @@ -91,6 +91,9 @@ type RPCState struct { // HwRebootFunc is a function that reboots the hardware type HwRebootFunc func(force bool, postRebootAction *PostRebootAction, delay time.Duration) error +// ResetConfigFunc is a function that resets the config +type ResetConfigFunc func() error + // GetHTTPClientFunc is a function that returns the HTTP client type GetHTTPClientFunc func() *http.Client @@ -117,6 +120,7 @@ type State struct { reboot HwRebootFunc getLocalVersion GetLocalVersionFunc onStateUpdate OnStateUpdateFunc + resetConfig ResetConfigFunc } // SetTargetVersion sets the target version for a component @@ -199,6 +203,7 @@ type Options struct { OnProgressUpdate OnProgressUpdateFunc HwReboot HwRebootFunc ReleaseAPIEndpoint string + ResetConfig ResetConfigFunc } // NewState creates a new OTA state @@ -215,6 +220,7 @@ func NewState(opts Options) *State { getLocalVersion: opts.GetLocalVersion, componentUpdateStatuses: components, releaseAPIEndpoint: opts.ReleaseAPIEndpoint, + resetConfig: opts.ResetConfig, } go s.confirmCurrentSystem() return s diff --git a/jsonrpc.go b/jsonrpc.go index e206617a..7e2540ce 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -1153,7 +1153,7 @@ var rpcHandlers = map[string]RPCHandler{ "getUpdateStatus": {Func: rpcGetUpdateStatus}, "getUpdateStatusChannel": {Func: rpcGetUpdateStatusChannel}, "tryUpdate": {Func: rpcTryUpdate}, - "tryUpdateComponents": {Func: rpcTryUpdateComponents, Params: []string{"components", "includePreRelease", "checkOnly"}}, + "tryUpdateComponents": {Func: rpcTryUpdateComponents, Params: []string{"components", "includePreRelease", "checkOnly", "resetConfig"}}, "cancelDowngrade": {Func: rpcCancelDowngrade}, "getDevModeState": {Func: rpcGetDevModeState}, "setDevModeState": {Func: rpcSetDevModeState, Params: []string{"enabled"}}, diff --git a/ota.go b/ota.go index dd761bdc..d85ce84b 100644 --- a/ota.go +++ b/ota.go @@ -30,6 +30,7 @@ func initOta() { }, GetLocalVersion: GetLocalVersion, HwReboot: hwReboot, + ResetConfig: rpcResetConfig, OnStateUpdate: func(state *ota.RPCState) { triggerOTAStateUpdate(state) }, @@ -144,14 +145,15 @@ func rpcTryUpdate() error { return rpcTryUpdateComponents(tryUpdateComponents{ AppTargetVersion: "", SystemTargetVersion: "", - }, config.IncludePreRelease, false) + }, config.IncludePreRelease, false, false) } -func rpcTryUpdateComponents(components tryUpdateComponents, includePreRelease bool, checkOnly bool) error { +func rpcTryUpdateComponents(components tryUpdateComponents, includePreRelease bool, checkOnly bool, resetConfig bool) error { updateParams := ota.UpdateParams{ DeviceID: GetDeviceID(), IncludePreRelease: includePreRelease, CheckOnly: checkOnly, + ResetConfig: resetConfig, } logger.Info().Interface("components", components).Msg("components") diff --git a/ui/src/routes/devices.$id.settings.advanced.tsx b/ui/src/routes/devices.$id.settings.advanced.tsx index 39fe73d3..6df14bec 100644 --- a/ui/src/routes/devices.$id.settings.advanced.tsx +++ b/ui/src/routes/devices.$id.settings.advanced.tsx @@ -189,6 +189,8 @@ export default function SettingsAdvancedRoute() { }, includePreRelease: devChannel, checkOnly: true, + // no need to reset config for a check only update + resetConfig: false, }; send("tryUpdateComponents", params, (resp: JsonRpcResponse) => { if ("error" in resp) { @@ -199,6 +201,8 @@ export default function SettingsAdvancedRoute() { } const pageParams = new URLSearchParams(); pageParams.set("downgrade", "true"); + // TODO: implement this + pageParams.set("resetConfig", "true"); pageParams.set("components", updateTarget == "both" ? "app,system" : updateTarget); // Navigate to update page diff --git a/ui/src/routes/devices.$id.settings.general.update.tsx b/ui/src/routes/devices.$id.settings.general.update.tsx index 2f38af3f..00e4ba05 100644 --- a/ui/src/routes/devices.$id.settings.general.update.tsx +++ b/ui/src/routes/devices.$id.settings.general.update.tsx @@ -46,6 +46,8 @@ export default function SettingsGeneralUpdateRoute() { }, includePreRelease: true, checkOnly: false, + // TODO: implement this + resetConfig: false, }); setModalView("updating"); }, [send, setModalView, updateComponents]);