Uh oh!
There was an error while loading. Please reload this page.
ADFA-4898: surface a failed proot module install and let the user retry it - #490
Open
luisguzman-adfa wants to merge 8 commits into
Open
ADFA-4898: surface a failed proot module install and let the user retry it#490luisguzman-adfa wants to merge 8 commits into
luisguzman-adfa wants to merge 8 commits into
Conversation
…ry it A module runrole failure was already detected (added to failedModules) but folded into a success-shaped DONE — no surface, no retry — so a failed install looked like a silent success and could not be re-run. - ModuleQueueState: hasFailures() / didFail(module) expose the failure on the DONE terminal (no new phase, so every existing "queue finished" consumer is unchanged; only the surfaces that care read it). - Module management (ModuleHubFragment): a module that failed in the last batch shows a "Couldn't install" pill and a Retry button (no schedule checkbox in that state); refreshes live via the module-queue observer. - Notification: a batch that ends with failures leaves a dismissible "install failed" notification (distinct id from the foreground one) that opens Module management. - InstallService.retryModules(ctx, modules): re-fires ACTION_START_MODULES for the failed module(s) — user action only, no auto-retry; for maps it re-attaches this session's retained layer selection (EXTRA_MAPS_*). runrole --reinstall re-converges when the module is healthy upstream. Reuses existing strings (k2go_mod_phase_failed, k2go_home_retry) — no new translations. Off-device / non-module flows unchanged. Follow-ups (same ticket, separate slices — each needs its own device round): movement- based stall detection, cancel with confirmation + immediate retry, and a "failed" state on the finishing-setup screen.
…er amber on a failed module Retry lived on the hub row and the finishing screen flipped to a green "Adding your content" when a module runrole had failed — reading a failed batch as success. Move recovery to where the user looks for it, keep the failure honest, no new copy. - SetupProgressActivity: a module batch that reaches its terminal with a failed runrole (server already up) keeps the same amber "installing" header instead of the green "Adding your content"; the failure and Retry surface per-module below, not in this batch-level header. - ModuleDetailFragment: a failed module (per-module didFail(key); installed outranks it) shows a persistent "Couldn't install" chip and turns the two actions into Retry (re-fires just this module, user-confirmed, busy-gated, then bounces to the live hub) + Back — the slot-reuse this switch already does for Recover. - ModuleHubFragment: drop the per-row Retry button; the "Couldn't install" pill is the entry into the detail, so a batch where one of many modules failed never sprays Retry across the list. - ModuleInstallFragment: route the progress line's failed check through the shared ModuleQueueState.didFail(key) instead of a hand-rolled failedModules.contains, so every surface shares one predicate.
… action The failed-state Retry was on the module detail but not on the live install card (the animation + log screen) — exactly where the user watches the runrole fail. Add it there and factor the action so it isn't duplicated. - ModuleRetry: one busy-gated, single-module retry action, called by both the live install card and the module detail so the two can't drift. - ModuleInstallFragment: a filled Retry under the status line, shown only while this module reads "failed" and self-hiding on re-fire (the card observes the queue live). Clears the terminal latch on RUNNING so the status resumes following the log after a retry. - ModuleDetailFragment: route its Retry through the shared ModuleRetry action.
…index has its rows
retryModules fired ACTION_START_MODULES raw and never saved the ModuleBatch, so a
retry brought up the install index empty ("Finishing setup" with no rows) while the
queue ran in the background. The wishlist drain got this right; the retry path
duplicated the "fire the service" half and dropped the "save the batch" half.
- ModuleProvisioner.startBatch: one entry point that saves the ordered batch and
hands the keys to InstallService. drain() and retryModules() both go through it,
so a batch can't start without the rows the index needs.
- InstallService.retryModules: delegates to startBatch (maps keeps its retained
per-layer selection as extras) instead of building the intent itself.…eat/ADFA-4898-runrole-failure-retry
…g the Run-in-background/Back template The Retry button sat mid-card, disconnected from the "Back" the host pins at the bottom. Move it into the host's existing two-button detail bar so Retry and Back are one primary/secondary pair, and drop the bespoke in-card button. - SetupProgressActivity.configureDetailBar(): reconfigures the one existing detail template — filled primary (k2go_sp_back) over outlined secondary (k2go_sp_detail_finish). A failed module shows Retry (primary) + Back (secondary); every other detail keeps Back (primary) + Run in background (secondary, LIVE only). Recomputed each render, so a Retry that returns the module to RUNNING restores the normal bar. Retry uses the shared ModuleRetry action and stays on the live card. - ModuleInstallFragment / fragment_k2go_module_install.xml: remove the in-card Retry button (now host-owned); keep the terminal-latch reset so the status resumes following the log after a retry.
…ot the hub Retrying from a module detail (reached from Module management) called onBackPressed, dropping the user on the "Add modules" hub, which during an install only shows "Adding content" with no route to the progress. Route to the install index instead — the same destination a normal install reaches via openModuleIndex — so the re-fired batch shows its rows, progress and log. The start action (ModuleRetry) is unchanged; only the detail's post-retry navigation moves.
…eat/ADFA-4898-runrole-failure-retry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A proot module install (a runrole that runs with the server stopped) that fails is
now surfaced honestly and can be retried per-module — no auto-retry. Before, a failed
runrole could read as a clean success and there was no way to re-run just the module
that failed.
Changes
ModuleQueueState.didFail(key)/hasFailures()on the DONEterminal — one predicate every surface reads (hub pill, module detail, live install
card, finishing header) so they can't drift.
InstallServicetreats a non-zero or[ERROR]runrole exit (incl. exit 137 / PPK kill) as a failure, records it, and postsa dismissible "Couldn't install" notification.
SetupProgressActivity): a batch that ends with a failed modulekeeps the amber "installing" header instead of flipping to green "Adding your content"
(which read a failure as success). No new copy.
(no per-row button); the module detail and the live install card offer Retry. On the
detail it is the primary of a Retry/Back pair; on the live card it reuses the host's
existing Run-in-background/Back button template (Retry primary + Back secondary),
recomputed live so it shows on failure and clears when the module returns to RUNNING.
ModuleRetry.fire(view, key)— busy-gated, single-module — is theonly start path, called by every surface. It goes through
ModuleProvisioner.startBatch,the single "save the ordered batch + start the service" method now shared with the
wishlist drain, so a retry always records the
ModuleBatchthe install index renders(a raw start left the index empty). Retrying from the detail lands on the install index,
where the re-fired batch shows its rows, progress and log.
Not in scope
No auto-retry (only a user action starts one), no movement-based stall detection, and no
cancel/confirm — follow-ups on this ticket.
Verification
Device: forced a runrole failure (network cut during calibre-web / kolibri). Confirmed the
amber finishing header, the "Couldn't install" pill, Retry on the detail and the live card,
the failure notification, and that Retry re-runs only the failed module and re-converges
(kolibri re-run repeatedly from ~34% with no corruption — the ansible role's idempotency
holds).