mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
refactor(auto-update): retire per-stack gate, drive auto-update from schedules only (#1233)
* refactor(auto-update): retire per-stack gate, drive auto-update from schedules only
The per-stack Auto-update toggle in the stack sidebar context menu wrote a
gate row to `stack_auto_update_settings`, but actual updates only ran when a
`scheduled_tasks` row with `action='update'` fired. On a fresh install the
toggle was inert: detection ran every 6h, nothing was applied.
The same context menu already exposes `Schedule task`, which opens
ScheduledOperationsView pre-filled for the stack where the user can pick
`Auto-update Stack` and any cron. Keeping the toggle alongside that flow
duplicated the same action and turned the gate table into a parallel store
of "is a covering schedule active" derivable from `scheduled_tasks` itself.
Drop the gate model entirely:
- Backend: remove the `stack_auto_update_settings` table and its four
accessors, the three routes under /api/stacks/*/auto-update, the per-stack
skip in /api/auto-update/execute and SchedulerService.executeUpdate's
fleet branch, and the clearStackAutoUpdateSetting call on stack delete.
Dashboard `autoUpdate` count derives from scheduled_tasks (action='update'
rows pinned to the node, total/enabled split).
- Frontend: drop the Auto-update entry from the sidebar context menu and its
optimistic toggle plumbing. Drop autoUpdateSettings state, the
/stacks/auto-update-settings fetch, and the auto-update-settings-changed
WebSocket branch. Slim useSidebarActivitySummary (just nextRunAt; no
enabled/total counts). AutoUpdateReadinessView's per-card autoUpdateEnabled
now means "a covering enabled action='update' schedule exists" (per-stack
row or fleet row on this node, earliest next_run_at wins, per-stack row
wins on ties), with the gate-fetch removed.
- New: scheduledTasksRouter broadcasts scope: 'scheduled-tasks' on POST,
PUT, PATCH /toggle, and DELETE so useConfigurationStatus and
useNextAutoUpdateRun refetch under the 250ms debounce instead of waiting
for the 60s poll. The broadcast is wrapped so a broken subscriber socket
cannot turn a successful mutation into a 500.
- Docs: rewrite the "Per-stack control" section of auto-update-policies.mdx
to describe the schedule-based model; update the matching troubleshooting
entry. The misleading fleet-update help text in ScheduledOperationsView
is corrected to reflect that every stack on the node is covered.
Tier parity: the surviving auto-update path (Schedule task -> Auto-update
Stack / All Stacks) is gated `requirePaid + requireAdmin` backend and
`isPaid + isAdmin` frontend, matching the gate the deleted routes carried.
The pre-commit grep returns no tier-related diff outside this PR's scope.
No data migration is provided: greenfield rules apply, and the leftover
table on already-shipped instances is harmless because no code reads or
writes it after this PR.
* docs: sweep remaining references to the per-stack auto-update toggle
The previous commit retired the per-stack Auto-update gate in favor of
configuring auto-update purely through scheduled tasks. This commit
removes the now-stale mentions of that toggle across the operator docs:
- docs/features/sidebar.mdx: drop the Auto-update entry from the Inspect
group description, the matching screenshot alt-text, and the Skipper
Note that listed it. Schedule task now carries the cross-link to
Auto-Update Policies.
- docs/features/stack-management.mdx: drop the Auto-update list item;
refresh the Schedule task entry to mention the Auto-update Stack action.
- docs/features/dashboard.mdx: rename the Configuration Status row from
"Auto-update stacks" to "Auto-update schedules" with the new value
shape, and rewrite the troubleshooting accordion to describe the
scheduled-tasks invalidation path.
- docs/features/scheduled-operations.mdx: rewrite the Auto-update All
Stacks row and helper text to reflect that every stack on the node is
covered (no per-stack opt-out from this surface anymore).
- docs/features/multi-node.mdx: rewrite the Updates column definition to
derive the Auto/Off flag from enabled Auto-update Stack / Auto-update
All Stacks schedules instead of the removed per-stack policy.
The auto-update-policies.mdx rewrite in the previous commit already
covered the main reference page. The sidebar-context-menu.png screenshot
will be refreshed on release once the new menu is live in production;
the alt text is updated in this commit so it accurately describes the
shipping state.
No website edits needed: the Auto-Update Policies feature card description
("Schedule automatic image pulls and redeployments per stack on your own
cadence") and the feature matrix labels ("Auto-update stack schedule",
"Auto-update all stacks schedule") remain accurate under the new model.
* fix(stacks): drop orphaned requireAdmin import after auto-update route removal
CI's backend lint step flagged this PR's earlier deletion of the three
/api/stacks/*/auto-update routes: those handlers were the only callers of
`requireAdmin` inside routes/stacks.ts, leaving the named import on line 15
unreferenced. `requirePaid` and `effectiveTier` from the same line are still
in use elsewhere in the file and stay.
tsc --noEmit does not flag unused named imports; ESLint's no-unused-vars
does. Local backend lint reproduces and now reports 0 errors against the
existing 334-warning baseline.
This commit is contained in:
@@ -58,27 +58,12 @@ Blocked updates still surface in scheduled check runs so you stay informed, but
|
||||
|
||||
## Per-stack control
|
||||
|
||||
Auto-updates can be disabled on a per-stack basis from the stack's context menu. This lets you keep the global schedule active while opting specific stacks out of unattended updates, such as databases, self-built images, or any stack pinned to a fixed tag.
|
||||
Auto-update is opt-in per stack. A stack participates in unattended updates only when an enabled scheduled task covers it. To leave a stack out (databases, self-built images, anything pinned to a fixed tag), simply do not create a schedule for it.
|
||||
|
||||
### Disabling auto-updates for a stack
|
||||
|
||||
1. Right-click the stack in the sidebar, or open the kebab menu (three dots).
|
||||
2. In the **Inspect** group, click **Auto-update: Enabled** to toggle it off. The label changes to **Auto-update: Disabled** and the icon switches to a slash-circle.
|
||||
3. The setting persists across restarts. The readiness board shows an **Auto: Off** pill on that card, and the **Apply now** button is disabled with the tooltip "Auto-updates are disabled for this stack. Update it from its actions menu."
|
||||
|
||||
<Note>
|
||||
Per-stack auto-update control requires a **Skipper** or **Admiral** license.
|
||||
</Note>
|
||||
|
||||
### What disabling means
|
||||
|
||||
- **Scheduled and fleet-wide auto-update runs skip the stack entirely.** No registry call is made, and no image update is applied automatically.
|
||||
- **Image update detection still runs.** The sidebar dot and the readiness card still reflect whether an update is available. You are informed; the system just does not apply it for you.
|
||||
- **Manual updates are unaffected.** You can still click **Update** in the lifecycle menu (or **Deploy**) to apply an update on demand. Per-stack control governs only the automated path.
|
||||
|
||||
### Re-enabling
|
||||
|
||||
Open the same menu and click **Auto-update: Disabled** to toggle it back on. The next scheduled run will include the stack again.
|
||||
- **Per-stack schedule.** Create a **Auto-update Stack** task targeting that stack alone. Only this stack is updated when the cron fires.
|
||||
- **Fleet-wide schedule.** Create a **Auto-update All Stacks** task targeting a node. Every stack on that node is checked and updated when new images are available. If you do not want every stack covered, create per-stack schedules instead.
|
||||
- **Stack list dot.** Image-update *detection* runs every six hours regardless of whether any schedule is configured. The sidebar dot and the readiness board still show available updates so you can decide what to do with them.
|
||||
- **Manual updates are always available.** The lifecycle **Update** action on a stack applies an update on demand, independent of any scheduled task.
|
||||
|
||||
## Scheduling auto-updates
|
||||
|
||||
@@ -124,7 +109,7 @@ The preview is recomputed each time the readiness board loads, so it reflects th
|
||||
Image update detection runs every six hours on each node and the readiness board uses the same cached status. Trigger **Recheck** to force a fresh check across every reachable node.
|
||||
</Accordion>
|
||||
<Accordion title='Scheduled auto-update runs are not applying to a specific stack'>
|
||||
The stack likely has auto-updates disabled. Open the stack's kebab menu or right-click context menu and check the **Inspect** group. If the item reads **Auto-update: Disabled**, click it to re-enable. Once re-enabled, the next scheduled run will include the stack, or you can trigger an immediate run from the Auto-Update view.
|
||||
No schedule covers that stack. Open **Schedules** in the top nav, create a new **Auto-update Stack** task targeting the stack (or an **Auto-update All Stacks** task on its node), and pick a cron. The next firing will include the stack, or you can trigger an immediate run from the row.
|
||||
</Accordion>
|
||||
<Accordion title='Banner says "X of Y nodes reachable"'>
|
||||
One or more nodes that are marked online in your fleet did not respond within the request timeout. Pending updates from those nodes are not shown until they come back. Check the node's status from the Fleet view and the network path between this Sencho instance and the unreachable node.
|
||||
|
||||
@@ -98,7 +98,7 @@ The Automation block only renders on Skipper or Admiral.
|
||||
| Row | What it shows |
|
||||
|-----|---------------|
|
||||
| **Auto-heal policies** | `<enabled> / <total> active` for crash-recovery policies across all stacks; reads `None` when no policies exist |
|
||||
| **Auto-update stacks** | `<enabled> / <total>` count of stacks enrolled in automated image-update checks; reads `None` when none are enrolled |
|
||||
| **Auto-update schedules** | `<enabled> / <total> active` count of `Auto-update Stack` / `Auto-update All Stacks` rows configured for this node; reads `None` when none are configured |
|
||||
| **Webhooks** (Skipper) | Active inbound deploy webhooks tied to Git Sources or stacks, formatted `<n> actives` |
|
||||
| **Scheduled tasks** (Admiral) | Active scheduled operations (backups, restarts, scripts), formatted `<n> actives` |
|
||||
|
||||
@@ -220,7 +220,7 @@ When you switch the active node from the node switcher, the dashboard resets eve
|
||||
Pilot-agent nodes connect outbound to the primary over a reverse tunnel, so there is no synchronous request-response loop to measure. The Heartbeat card uses the tunnel's last heartbeat to set the dot color, and intentionally renders `n/a` in the latency column. If the dot is red, check the agent container's logs for the first `[Pilot]` line and confirm the agent can reach the primary URL it is dialing. See [Pilot agent](/features/pilot-agent).
|
||||
</Accordion>
|
||||
<Accordion title="Configuration Status still shows the old value after I changed a setting">
|
||||
The card refreshes every 60 seconds on its own schedule. Toggling a stack's **Auto-update** setting also dispatches a live invalidation that the card picks up within a second. Other settings changes (cloud backup provider switch, SSO provider change, alert rule edit, agent toggle) update on the next 60-second tick. If the row stays stale after a minute, hard-reload the dashboard tab to force a fresh fetch.
|
||||
The card refreshes every 60 seconds on its own schedule. Creating, editing, toggling, or deleting a scheduled task also dispatches a live invalidation that the card picks up within a second. Other settings changes (cloud backup provider switch, SSO provider change, alert rule edit, agent toggle) update on the next 60-second tick. If the row stays stale after a minute, hard-reload the dashboard tab to force a fresh fetch.
|
||||
</Accordion>
|
||||
<Accordion title="The masthead shows a 'metrics stale' chip next to the node name">
|
||||
The chip appears after three consecutive failures of the live metrics endpoints (`/api/stats` or `/api/system/stats`), which usually means the Docker socket is unreachable from this Sencho instance or the metrics service has stopped. The dashboard keeps polling on every cycle; the chip describes the freshness of the visible numbers, not the polling cadence. The chip clears on the first successful response once both endpoints are within the threshold. Check the Docker daemon status on the active node first, then the Sencho container logs for `[Dashboard]` lines if the chip persists.
|
||||
|
||||
@@ -167,7 +167,7 @@ The Nodes table surfaces routing, status, and per-node automation at a glance fo
|
||||
| **Status** | `Online`, `Offline`, or `Unknown` badge. |
|
||||
| **Labels** | Per-node label palette. On Skipper and Admiral the cell shows the picker (an empty cell reads `No labels` with an Add label control); on Community the cell shows a single dash. |
|
||||
| **Schedules** | Number of active scheduled tasks targeting this node, plus a `next X` countdown to the next run. Click the count or the calendar icon in the Actions column to filter the Schedules view to that node. |
|
||||
| **Updates** | `Auto` if at least one auto-update policy is enabled on the node; `Off` otherwise. A pulsing dot and count appear when stacks have pending image updates. |
|
||||
| **Updates** | `Auto` if at least one enabled `Auto-update Stack` or `Auto-update All Stacks` schedule targets the node; `Off` otherwise. A pulsing dot and count appear when stacks have pending image updates. |
|
||||
| **Actions** | **View Schedules**, **Test Connection**, **Edit Node**, and **Delete Node** icon buttons. The local row hides Delete because the local node cannot be removed. |
|
||||
|
||||
Clicking the schedules-link icon opens the Schedules view filtered to the selected node. From there you can create, edit, or manage scheduled tasks scoped to that node. The filter bar shows which node you are viewing, with a Clear filter control to return to the full list.
|
||||
|
||||
@@ -60,7 +60,7 @@ The All tasks toggle swaps the lane track for a sortable table.
|
||||
|---|---|---|
|
||||
| **Restart Stack** | A specific stack (optionally specific services) on a specific node | Restarts all or selected containers in the stack. |
|
||||
| **Auto-update Stack** | A specific stack on a specific node | Checks each image in the stack for a newer tag and recreates the stack if any image has an update. See [Auto-Update Policies](/features/auto-update-policies) for the companion review board. |
|
||||
| **Auto-update All Stacks** | A specific node | Runs the auto-update check across every stack on the node that has auto-updates enabled. Stacks with auto-updates turned off are skipped. |
|
||||
| **Auto-update All Stacks** | A specific node | Runs the auto-update check across every stack on the node. Pair with **Auto-update Stack** rows when you want different cadences for specific stacks. |
|
||||
| **Fleet Snapshot** | The whole fleet | Creates a versioned, fleet-wide snapshot of every node's compose files and `.env` files. See [Fleet Backups](/features/fleet-backups). |
|
||||
| **System Prune** | The selected node | Prunes containers, images, networks, and volumes (any subset), optionally filtered by a Docker label. |
|
||||
| **Vulnerability Scan** | A specific node | Runs Trivy against every image on the node and persists the results. Requires Trivy to be installed on the target node ([Installing Trivy](/operations/trivy-setup)). |
|
||||
@@ -88,7 +88,7 @@ Common fields:
|
||||
Conditional fields per action:
|
||||
|
||||
- **Stack actions** (Restart Stack, Auto-update Stack, Backup Stack Files, Stop / Take Down / Start Stack) add a **Node** combobox and a **Stack** combobox. Restart Stack additionally renders a **Services** checkbox grid sourced from the stack's compose services, so you can scope the restart to a subset instead of restarting the entire stack.
|
||||
- **Auto-update All Stacks** adds a **Node** combobox with the helper text "Only stacks with auto-updates enabled on this node will be updated."
|
||||
- **Auto-update All Stacks** adds a **Node** combobox with the helper text "Every stack on the selected node will be checked and updated when new images are available."
|
||||
- **Vulnerability Scan** adds a **Node** combobox with the helper text "Every image on the selected node will be scanned."
|
||||
- **System Prune** adds a **Prune Targets** group (Containers, Images, Networks, Volumes; all selected by default) and a **Label Filter** input for scoping the prune to resources matching a Docker label.
|
||||
|
||||
|
||||
@@ -79,17 +79,17 @@ Click rows to toggle their selection. The toolbar header shows a running count.
|
||||
|
||||
Right-click any stack (or open the kebab that appears on hover) for its context menu. Items are grouped by purpose:
|
||||
|
||||
- **Inspect**: **Alerts**, **Auto-Heal**, the **Auto-update** toggle, **Check updates**, and **Open App** (the last only appears when the stack is running and exposes a port).
|
||||
- **Inspect**: **Alerts**, **Auto-Heal**, **Check updates**, and **Open App** (the last only appears when the stack is running and exposes a port).
|
||||
- **Organize**: **Labels** (a submenu listing every label on the node, with a check next to each label the stack already carries) and **Pin to top** / **Unpin**.
|
||||
- **Lifecycle**: **Deploy** (when stopped), **Stop**, **Restart**, **Update** (when running), and **Schedule task**.
|
||||
- **Lifecycle**: **Deploy** (when stopped), **Stop**, **Restart**, **Update** (when running), and **Schedule task** (opens the Schedules view pre-filled for this stack, where **Auto-update Stack** sets up unattended updates on your own cadence).
|
||||
- **Destructive**: **Delete**.
|
||||
|
||||
<Note>
|
||||
**Auto-Heal**, the **Auto-update** toggle, and **Schedule task** require a **Skipper** or **Admiral** license.
|
||||
**Auto-Heal** and **Schedule task** require a **Skipper** or **Admiral** license.
|
||||
</Note>
|
||||
|
||||
<Frame>
|
||||
<img src="/images/sidebar/sidebar-context-menu.png" alt="Right-click context menu on a running plex stack with four sections. INSPECT lists Alerts, Auto-Heal, Auto-update: Enabled, Check updates, and Open App. ORGANIZE lists Labels with a submenu arrow and Pin to top. LIFECYCLE lists Stop, Restart, Update, and Schedule task. DESTRUCTIVE lists Delete in red." />
|
||||
<img src="/images/sidebar/sidebar-context-menu.png" alt="Right-click context menu on a running plex stack with four sections. INSPECT lists Alerts, Auto-Heal, Check updates, and Open App. ORGANIZE lists Labels with a submenu arrow and Pin to top. LIFECYCLE lists Stop, Restart, Update, and Schedule task. DESTRUCTIVE lists Delete in red." />
|
||||
</Frame>
|
||||
|
||||
## Keyboard shortcuts
|
||||
|
||||
@@ -330,7 +330,6 @@ Click the kebab on a stack row in the sidebar to open its context menu. The menu
|
||||
|
||||
- **Alerts** (`A`): open the alert rule editor for this stack. See [Alerts and Notifications](/features/alerts-notifications).
|
||||
- **Auto-Heal** (`H`): configure auto-recovery for this stack (Skipper+). See [Auto-Heal Policies](/features/auto-heal-policies).
|
||||
- **Auto-update** (`Enabled` or `Disabled`): toggle automatic updates for this stack (Skipper+). See [Auto-Update Policies](/features/auto-update-policies).
|
||||
- **Check updates** (`U`): force an image update check now.
|
||||
- **Open App** (`↗`): open the stack's web interface in a new tab. Shown only when the stack is running and exposes a web port.
|
||||
|
||||
@@ -344,7 +343,7 @@ Click the kebab on a stack row in the sidebar to open its context menu. The menu
|
||||
- **Stop** (`⌘.`): shown when running.
|
||||
- **Restart** (`⌘R`): shown when running.
|
||||
- **Update** (`⌘↑`): pulls the latest image tags and redeploys.
|
||||
- **Schedule task**: open the scheduler for this stack (Skipper+). See [Scheduled Operations](/features/scheduled-operations).
|
||||
- **Schedule task**: open the scheduler pre-filled for this stack (Skipper+); pick **Auto-update Stack** to set up unattended image updates on your own cadence. See [Scheduled Operations](/features/scheduled-operations) and [Auto-Update Policies](/features/auto-update-policies).
|
||||
- **Deploy** (`⌘↵`): shown when stopped, in place of Stop and Restart.
|
||||
|
||||
**destructive**
|
||||
|
||||
Reference in New Issue
Block a user