You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(updates): surface held packages distinctly with hold/unhold actions
Before this change, the OS Updates grid lumped held packages in with
the regular Updates list. Held entries — packages an operator has
explicitly pinned via apt-mark/dpkg — still appear in
`apt list --upgradable` when a newer version exists in the repos, but
apt will never upgrade them. Showing them in the active updates view
was misleading: "Update All" would silently skip them, the Security
count over-counted, and there was no UI to undo a hold from this page.
This change does four things across the agent, dashboard, and UI:
1. Agent — `Package` struct gains `IsHeld bool` with json tag
`is_held,omitempty`. `aptPackageManager.ListUpgradable` now calls
`apt-mark showhold` after parsing `apt list --upgradable` and marks
each matching package. Failures from apt-mark are non-fatal; the
listing falls back to IsHeld=false rather than erroring the whole
request, because the hold lookup is purely an enrichment step.
The pure-logic core (`applyHeldMarks`) is extracted so it can be
unit-tested without execing.
2. Dashboard — mirroring agent struct; `agent.Package` gains the same
`IsHeld` / `is_held` field so JSON round-trips intact.
3. UI — the pkg-view-filter dropdown gains a `Held` option between
`Updates` and `All Packages`. The `Updates` filter is now
`update_available=true AND is_held=false` (held rows belong in
their own tab, not the active-upgrades plan); the `Held` filter
shows only `is_held=true`. `Update All (N)` and the Security
button counts also exclude held packages so what's shown matches
what `apt upgrade` would actually do.
4. UI actions — a new `Hold` button mirrors the existing `Unhold`
button; both POST to the matching `/api/os-updates/packages/{hold,
unhold}` endpoints (which already existed). After a hold or unhold
the row is updated in place and the active filter is reapplied so
the row moves between the Updates and Held tabs without a refresh.
Tests:
- `TestApplyHeldMarks` covers the enrichment helper: held rows are
marked, non-held rows are left alone, empty inputs are safe, and
held names with no matching package are ignored.
Refs #45
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments