Repository navigation
fix(drivers): recover to the release's driver over a kept selection #1434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| "ftw": patch | ||
| --- | ||
|
|
||
| When a release's newer driver runs instead of a kept older selection, a failed | ||
| trial of another version now returns the device to the release's driver. Before, | ||
| the recovery restarted a file that no longer ran and left the device stopped, or | ||
| made the kept older version run. The kept version now offers "Use this" under | ||
| Settings › Devices, so the owner can go back to it. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -303,19 +303,27 @@ func (s *Server) handleDeviceRepositoryVersions(w http.ResponseWriter, r *http.R | |
| logicalPath = candidate.Driver.Path | ||
| } | ||
| } | ||
| release, chosen := "", "" | ||
| // A selection the release's newer copy has overtaken is kept but does | ||
| // not run, so the picker offers it like any version on disk. | ||
| release, chosen, superseded := "", "", "" | ||
| if logicalPath != "" { | ||
| release = s.deps.DriverRepository.ReleaseVersion(logicalPath) | ||
| for _, installed := range versions { | ||
| if installed.Active && s.deps.DriverRepository.Chosen(logicalPath, installed.Version) { | ||
| if !installed.Active { | ||
| continue | ||
| } | ||
| if s.deps.DriverRepository.Chosen(logicalPath, installed.Version) { | ||
| chosen = installed.Version | ||
| } | ||
| if !s.deps.DriverRepository.Runs(installed) { | ||
| superseded = installed.Version | ||
| } | ||
| } | ||
| } | ||
| writeJSON(w, 200, map[string]any{ | ||
| "driver_id": r.PathValue("id"), "installed": versions, "available": available, | ||
| "logical_path": logicalPath, "release_version": release, "chosen_version": chosen, | ||
| "release_source": s.bundledSource(), | ||
| "superseded_version": superseded, "release_source": s.bundledSource(), | ||
| }) | ||
| } | ||
|
|
||
|
|
@@ -362,8 +370,11 @@ func (s *Server) handleDeviceRepositoryActivate(w http.ResponseWriter, r *http.R | |
| if restartErr != nil { | ||
| recoveryErr := error(nil) | ||
| if original != nil { | ||
| // A rollback restores the selection and the choice that went | ||
| // with it. Activating the original again would pin a kept | ||
| // version the release had overtaken, and run it instead. | ||
| var recovered state.DriverRepoInstall | ||
| recovered, recoveryErr = s.deps.DriverRepository.ActivateInstalled(driverID, original.Version, original.SHA256) | ||
| recovered, recoveryErr = s.deps.DriverRepository.Rollback(activated.LogicalPath) | ||
| if recoveryErr == nil { | ||
| _, recoveryErr = s.restartManagedDriversExpected(context.Background(), recovered, restartState.ExpectedIdentities) | ||
| } | ||
|
|
@@ -524,7 +535,10 @@ func (s *Server) restartManagedDriversExpected(ctx context.Context, artifact sta | |
| rel := filepath.FromSlash(strings.TrimPrefix(artifact.LogicalPath, "drivers/")) | ||
| activePath := filepath.Join(s.managedDriverDir(), rel) | ||
| targetPath := activePath | ||
| if artifact.InstalledPath == "" { | ||
| // No managed file runs at this path either when nothing is selected | ||
| // (UseBundled) or when the release's newer copy overtakes the selection; | ||
| // the release's own file runs then. | ||
| if _, err := os.Stat(activePath); artifact.InstalledPath == "" || err != nil { | ||
| var err error | ||
| targetPath, err = s.bundledDriverFor(artifact.DriverID, artifact.LogicalPath) | ||
|
Comment on lines
+541
to
543
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If the effective symlink is absent or unreadable for any reason other than intentional supersession—for example, AGENTS.md reference: AGENTS.md:L22-L23 Useful? React with 👍 / 👎. |
||
| if err != nil { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When activating a retained version whose manifest renamed the driver file, the original remains active under its old logical path, so the newly activated path has no
PreviousInstalledPath. If its runtime restart then fails, thisRollback(activated.LogicalPath)returnsdriver has no previous managed artifactand no configuration/runtime restoration occurs, leaving the device stopped. Filename changes are an explicitly supported switching flow, so this case needs to deactivate the failed path and restore/restart the captured original, as the install recovery path already does.AGENTS.md reference: AGENTS.md:L24-L25
Useful? React with 👍 / 👎.