diff --git a/internal/ota/ota.go b/internal/ota/ota.go index 589aba2e..534c6976 100644 --- a/internal/ota/ota.go +++ b/internal/ota/ota.go @@ -186,6 +186,14 @@ func (s *State) doUpdate(ctx context.Context, params UpdateParams) error { } if s.rebootNeeded { + if appUpdate.customVersionUpdate || systemUpdate.customVersionUpdate { + scopedLogger.Info().Msg("disabling auto-update due to custom version update") + if _, err := s.setAutoUpdate(false); err != nil { + scopedLogger.Warn().Err(err).Msg("Failed to disable auto-update") + } + return nil + } + scopedLogger.Info().Msg("System Rebooting due to OTA update") redirectUrl := fmt.Sprintf("/settings/general/update?version=%s", systemUpdate.version) diff --git a/internal/ota/rpc.go b/internal/ota/rpc.go index 84976025..30f132ea 100644 --- a/internal/ota/rpc.go +++ b/internal/ota/rpc.go @@ -156,6 +156,7 @@ func remoteMetadataToComponentStatus( componentStatus.available = componentStatus.version != componentStatus.localVersion if componentStatus.available { componentStatus.availableReason = fmt.Sprintf("custom version %s is not equal to local version %s", constraint, componentStatus.localVersion) + componentStatus.customVersionUpdate = true } } else if !componentExists { componentStatus.available = false diff --git a/internal/ota/state.go b/internal/ota/state.go index 1bb12033..2bb7055e 100644 --- a/internal/ota/state.go +++ b/internal/ota/state.go @@ -38,6 +38,7 @@ type UpdateStatus struct { Remote *UpdateMetadata `json:"remote"` SystemUpdateAvailable bool `json:"systemUpdateAvailable"` AppUpdateAvailable bool `json:"appUpdateAvailable"` + WillDisableAutoUpdate bool `json:"willDisableAutoUpdate"` // only available for debugging and won't be exported SystemUpdateAvailableReason string `json:"-"` @@ -59,6 +60,7 @@ type componentUpdateStatus struct { pending bool available bool availableReason string // why the component is available or not available + customVersionUpdate bool version string localVersion string url string @@ -98,6 +100,9 @@ type HwRebootFunc func(force bool, postRebootAction *PostRebootAction, delay tim // ResetConfigFunc is a function that resets the config type ResetConfigFunc func() error +// SetAutoUpdateFunc is a function that sets the auto-update state +type SetAutoUpdateFunc func(enabled bool) (bool, error) + // GetHTTPClientFunc is a function that returns the HTTP client type GetHTTPClientFunc func() HttpClient @@ -125,6 +130,7 @@ type State struct { getLocalVersion GetLocalVersionFunc onStateUpdate OnStateUpdateFunc resetConfig ResetConfigFunc + setAutoUpdate SetAutoUpdateFunc } func toUpdateStatus(appUpdate *componentUpdateStatus, systemUpdate *componentUpdateStatus, error string) *UpdateStatus { @@ -145,6 +151,7 @@ func toUpdateStatus(appUpdate *componentUpdateStatus, systemUpdate *componentUpd SystemUpdateAvailableReason: systemUpdate.availableReason, AppUpdateAvailable: appUpdate.available, AppUpdateAvailableReason: appUpdate.availableReason, + WillDisableAutoUpdate: appUpdate.customVersionUpdate || systemUpdate.customVersionUpdate, Error: error, } } @@ -180,6 +187,7 @@ type Options struct { ReleaseAPIEndpoint string ResetConfig ResetConfigFunc SkipConfirmSystem bool + SetAutoUpdate SetAutoUpdateFunc } // NewState creates a new OTA state @@ -198,6 +206,7 @@ func NewState(opts Options) *State { componentUpdateStatuses: components, releaseAPIEndpoint: opts.ReleaseAPIEndpoint, resetConfig: opts.ResetConfig, + setAutoUpdate: opts.SetAutoUpdate, } if !opts.SkipConfirmSystem { go s.confirmCurrentSystem() diff --git a/ota.go b/ota.go index 19ef20fd..595933aa 100644 --- a/ota.go +++ b/ota.go @@ -31,6 +31,7 @@ func initOta() { GetLocalVersion: GetLocalVersion, HwReboot: hwReboot, ResetConfig: rpcResetConfig, + SetAutoUpdate: rpcSetAutoUpdateState, OnStateUpdate: func(state *ota.RPCState) { triggerOTAStateUpdate(state) }, @@ -82,6 +83,7 @@ func getUpdateStatus(includePreRelease bool) (*ota.UpdateStatus, error) { DeviceID: GetDeviceID(), IncludePreRelease: includePreRelease, }) + // to ensure backwards compatibility, // if there's an error, we won't return an error, but we will set the error field if err != nil { @@ -91,6 +93,11 @@ func getUpdateStatus(includePreRelease bool) (*ota.UpdateStatus, error) { updateStatus.Error = err.Error() } + // otaState doesn't have the current auto-update state, so we need to get it from the config + if updateStatus.WillDisableAutoUpdate { + updateStatus.WillDisableAutoUpdate = config.AutoUpdateEnabled + } + otaLogger.Info().Interface("updateStatus", updateStatus).Msg("Update status") return updateStatus, nil diff --git a/ui/localization/messages/da.json b/ui/localization/messages/da.json index f2773dee..1a41e0cc 100644 --- a/ui/localization/messages/da.json +++ b/ui/localization/messages/da.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "Systemet er opdateret", "general_update_updating_description": "Sluk ikke enheden. Denne proces kan tage et par minutter.", "general_update_updating_title": "Opdatering af din enhed", + "general_update_will_disable_auto_update_description": "Du nedgraderer i øjeblikket til en tidligere version. Automatisk opdatering vil blive deaktiveret, når opdateringen er fuldført, for at forhindre utilsigtede opdateringer.", "getting_remote_session_description": "Henter beskrivelse af fjernsessionsforsøg {attempt}", "hardware_backlight_settings_error": "Kunne ikke indstille baggrundsbelysningsindstillinger: {error}", "hardware_backlight_settings_get_error": "Kunne ikke hente indstillinger for baggrundsbelysning: {error}", diff --git a/ui/localization/messages/de.json b/ui/localization/messages/de.json index f855ab88..e37b7be0 100644 --- a/ui/localization/messages/de.json +++ b/ui/localization/messages/de.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "Das System ist auf dem neuesten Stand", "general_update_updating_description": "Bitte schalten Sie Ihr Gerät nicht aus. Dieser Vorgang kann einige Minuten dauern.", "general_update_updating_title": "Aktualisieren Ihres Geräts", + "general_update_will_disable_auto_update_description": "Sie führen derzeit ein Downgrade auf eine ältere Version durch. Die automatische Aktualisierung wird nach Abschluss des Updates deaktiviert, um versehentliche Aktualisierungen zu verhindern.", "getting_remote_session_description": "Versuch, eine Beschreibung der Remote-Sitzung abzurufen {attempt}", "hardware_backlight_settings_error": "Fehler beim Festlegen der Hintergrundbeleuchtungseinstellungen: {error}", "hardware_backlight_settings_get_error": "Die Einstellungen für die Hintergrundbeleuchtung konnten nicht abgerufen werden: {error}", diff --git a/ui/localization/messages/en.json b/ui/localization/messages/en.json index a52d1629..26be6bcf 100644 --- a/ui/localization/messages/en.json +++ b/ui/localization/messages/en.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "System is up to date", "general_update_updating_description": "Please don't turn off your device. This process may take a few minutes.", "general_update_updating_title": "Updating your device", + "general_update_will_disable_auto_update_description": "You're currently downgrading to a previous version. Auto-update will be disabled after the update is completed to prevent accidental updates.", "getting_remote_session_description": "Getting remote session description attempt {attempt}", "hardware_backlight_settings_error": "Failed to set backlight settings: {error}", "hardware_backlight_settings_get_error": "Failed to get backlight settings: {error}", diff --git a/ui/localization/messages/es.json b/ui/localization/messages/es.json index bb3e5500..d4987c9a 100644 --- a/ui/localization/messages/es.json +++ b/ui/localization/messages/es.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "El sistema está actualizado", "general_update_updating_description": "No apagues tu dispositivo. Este proceso puede tardar unos minutos.", "general_update_updating_title": "Actualizar su dispositivo", + "general_update_will_disable_auto_update_description": "Estás instalando una versión anterior. La actualización automática se desactivará una vez finalizada la actualización para evitar actualizaciones accidentales.", "getting_remote_session_description": "Obtener un intento de descripción de sesión remota {attempt}", "hardware_backlight_settings_error": "No se pudieron configurar los ajustes de la retroiluminación: {error}", "hardware_backlight_settings_get_error": "No se pudieron obtener los ajustes de la retroiluminación: {error}", diff --git a/ui/localization/messages/fr.json b/ui/localization/messages/fr.json index d44f21b0..2d1f2fe4 100644 --- a/ui/localization/messages/fr.json +++ b/ui/localization/messages/fr.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "Le système est à jour", "general_update_updating_description": "Veuillez ne pas éteindre votre appareil. Ce processus peut prendre quelques minutes.", "general_update_updating_title": "Mise à jour de votre appareil", + "general_update_will_disable_auto_update_description": "Vous allez revenir à une version antérieure. La mise à jour automatique sera désactivée une fois l'opération terminée afin d'éviter toute mise à jour accidentelle.", "getting_remote_session_description": "Obtention d'{attempt} description de session à distance", "hardware_backlight_settings_error": "Échec de la définition des paramètres de rétroéclairage : {error}", "hardware_backlight_settings_get_error": "Échec de l'obtention des paramètres de rétroéclairage : {error}", diff --git a/ui/localization/messages/it.json b/ui/localization/messages/it.json index 30880f9c..b5d0007b 100644 --- a/ui/localization/messages/it.json +++ b/ui/localization/messages/it.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "Il sistema è aggiornato", "general_update_updating_description": "Non spegnere il dispositivo. Questo processo potrebbe richiedere alcuni minuti.", "general_update_updating_title": "Aggiornamento del dispositivo", + "general_update_will_disable_auto_update_description": "Stai eseguendo il downgrade a una versione precedente. L'aggiornamento automatico verrà disattivato al termine dell'aggiornamento per evitare aggiornamenti accidentali.", "getting_remote_session_description": "Tentativo di ottenimento della descrizione della sessione remota {attempt}", "hardware_backlight_settings_error": "Impossibile impostare le impostazioni della retroilluminazione: {error}", "hardware_backlight_settings_get_error": "Impossibile ottenere le impostazioni della retroilluminazione: {error}", diff --git a/ui/localization/messages/nb.json b/ui/localization/messages/nb.json index 1e8e1831..6f8b1ba3 100644 --- a/ui/localization/messages/nb.json +++ b/ui/localization/messages/nb.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "Alt er oppdatert", "general_update_updating_description": "Ikke slå av enheten. Denne prosessen kan ta noen minutter.", "general_update_updating_title": "Oppdaterer enheten din", + "general_update_will_disable_auto_update_description": "Du nedgraderer for øyeblikket til en tidligere versjon. Automatisk oppdatering vil bli deaktivert etter at oppdateringen er fullført for å forhindre utilsiktede oppdateringer.", "getting_remote_session_description": "Henter beskrivelse av ekstern øktforsøk {attempt}", "hardware_backlight_settings_error": "Kunne ikke angi innstillinger for bakgrunnsbelysning: {error}", "hardware_backlight_settings_get_error": "Klarte ikke å hente bakgrunnsbelysningsinnstillinger: {error}", diff --git a/ui/localization/messages/sv.json b/ui/localization/messages/sv.json index 1be9bb79..2af36228 100644 --- a/ui/localization/messages/sv.json +++ b/ui/localization/messages/sv.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "Systemet är uppdaterat", "general_update_updating_description": "Stäng inte av enheten. Den här processen kan ta några minuter.", "general_update_updating_title": "Uppdaterar din enhet", + "general_update_will_disable_auto_update_description": "Du nedgraderar för närvarande till en tidigare version. Automatisk uppdatering inaktiveras efter att uppdateringen är klar för att förhindra oavsiktliga uppdateringar.", "getting_remote_session_description": "Hämtar beskrivning av fjärrsession försök {attempt}", "hardware_backlight_settings_error": "Misslyckades med att ställa in bakgrundsbelysning: {error}", "hardware_backlight_settings_get_error": "Misslyckades med att hämta inställningar för bakgrundsbelysning: {error}", diff --git a/ui/localization/messages/zh.json b/ui/localization/messages/zh.json index 46ee0b75..cc1cbc35 100644 --- a/ui/localization/messages/zh.json +++ b/ui/localization/messages/zh.json @@ -302,6 +302,7 @@ "general_update_up_to_date_title": "系统已更新", "general_update_updating_description": "正在更新,请勿关闭设备。该过程可能需要数分钟。", "general_update_updating_title": "更新您的设备", + "general_update_will_disable_auto_update_description": "您目前正在降级到之前的版本。更新完成后,自动更新功能将被禁用,以防止意外更新。", "getting_remote_session_description": "获取远程会话描述尝试 {attempt}", "hardware_backlight_settings_error": "无法设置背光设置: {error}", "hardware_backlight_settings_get_error": "无法获取背光设置: {error}", diff --git a/ui/src/routes/devices.$id.settings.general.update.tsx b/ui/src/routes/devices.$id.settings.general.update.tsx index c69d2140..cef41f2c 100644 --- a/ui/src/routes/devices.$id.settings.general.update.tsx +++ b/ui/src/routes/devices.$id.settings.general.update.tsx @@ -468,6 +468,11 @@ function UpdateAvailableState({ {m.general_update_application_type()}: {versionInfo?.local?.appVersion} {versionInfo?.remote?.appVersion} ) : null} + {versionInfo?.willDisableAutoUpdate ? ( +

+ {m.general_update_will_disable_auto_update_description()} +

+ ) : null}