fix(garm): sync app status with unit status#266
Merged
Conversation
The charm's own status writes used self.unit.status directly, which updates only the unit status. Only the paas_charm base's update_app_and_unit_status also sets self.app.status (on the leader), and restart()'s config-unchanged fast path returns before super().restart() ever calls it. So in steady state the application status froze on whatever the framework last set it to (e.g. a stale "Waiting for pebble ready" from an earlier can_connect blip) while the unit status stayed live and correct. Route the six status writes in restart()'s readiness gates and _reconcile_runners through update_app_and_unit_status so the app status tracks the unit status.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a status-reporting mismatch in the garm charm by routing status updates through the shared update_app_and_unit_status() helper, ensuring the leader’s application status is refreshed alongside the unit status (preventing stale app-level status in steady-state fast paths).
Changes:
- Converted key
garmreadiness-gate status writes inrestart()to useupdate_app_and_unit_status()so the leader updatesapp.statusas well asunit.status. - Converted
_reconcile_runners()success/failure status writes to useupdate_app_and_unit_status()for consistent app/unit status updates. - Added unit tests covering the previously failing scenarios where app status could remain stale after
_reconcile_runners()and arestart()readiness gate.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
docs/changelog.md |
Documents the user-visible fix to prevent stale application status for the garm charm. |
charms/garm/src/charm.py |
Routes six status writes through update_app_and_unit_status() in restart() and _reconcile_runners(). |
charms/garm/tests/unit/test_charm.py |
Adds tests that reproduce and prevent regressions of stale app status on the leader. |
florentianayuwono
approved these changes
Jul 6, 2026
The app-status sync fix makes the leader's application status track the unit status, so on integration GARM's application status now honestly reflects the pending _reconcile_runners() (waiting/GARM sync) instead of a stale active set once by paas_charm. Loosen test_garm_charm_reaches_active to accept active or waiting, and drop the now-obsolete split-state note.
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 free
to 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 this PR does
Routes the
garmcharm's own status writes through the base class'supdate_app_and_unit_status()instead of assigningself.unit.statusdirectly, so the leader's application status stays in sync with the unit status.Why we need it
The charm set
self.unit.statusdirectly on its readiness gates and in_reconcile_runners()— a unit-only write. Onlyupdate_app_and_unit_status()sets the leader'sself.app.status, andrestart()'s config-unchanged fast path returns beforesuper().restart()ever calls it. So in steady state the application status was never refreshed and froze on a stale value — observed in production aswaiting "Waiting for pebble ready"on the App line while the unit wasactiveand healthy.Test plan: garm
tox -e unit(185 passed), including two new tests (confirmed failing before the fix) covering the_reconcile_runnerssuccess path and arestart()readiness gate;lint,static(pyright),fmtclean.Review focus: the six converted status writes (three readiness gates in
restart(), three in_reconcile_runners()). No behaviour change beyond additionally setting the app status on the leader. No breaking changes, no new dependencies.Checklist
CONTRIBUTING.mdhas been updated upon changes to the contribution/development process (e.g. changes to the way tests are run) — n/adocs/changelog.mdwith user-relevant changesterraform fmtpasses andtflintreports no errors — n/aAGENTS.md— n/a.copilot-collections.yamlor.github/instructions/: I re-checked theAGENTS.md"12-factor divergences" guidance — n/a