feat(cli): apply coordinated updates during maintenance
This commit is contained in:
21 files changed
+990
-457
No files matched your search
@@ -31,19 +31,19 @@ A grep across `*.md` and `*.go` returns both sets; only the Go ones are seams.
|
||||
update` passes nil deliberately. The notification is the panel instead:
|
||||
`felis-update-check.timer` runs `felis update --record` daily on the host, which
|
||||
stores the report under `platform_settings.update_report`, and **Admin → Updates →
|
||||
Component versions** shows it with the command that applies each update.
|
||||
- `internal/updates/seams.go:43` — `Applier`. Nothing applies an update anywhere. A
|
||||
nil applier is not silent — `Run` records `errNoApplier` against every planned
|
||||
apply, so a mis-scheduled apply is loud rather than lost.
|
||||
Component versions** shows it with the read-only command that prepares an update.
|
||||
- `internal/updates/seams.go:43` — `Applier`. No unattended runner adapts this interface.
|
||||
The host CLI implements explicit `felis update --apply` separately, using the target
|
||||
installer after window checks and backup. A nil applier in the read-only runner
|
||||
still records `errNoApplier` against a mistakenly scheduled apply.
|
||||
- `internal/updater/gatherer_integration.go:22` — the two current-version seams
|
||||
`NewSysGatherer` leaves nil, for the in-cluster path: the k8s read of the
|
||||
control-plane Deployment image, and the Velocity jar inspection. Both are answered
|
||||
on the host path (see "Built" below), so this gap is specific to a caller that has
|
||||
a cluster client instead of the node.
|
||||
- `internal/api/handlers_updates.go` — the maintenance window is advisory: no
|
||||
in-cluster runner applies updates. `felis update` reads the stored window, prints
|
||||
where now sits against it and warns before an apply outside it; the runner itself
|
||||
still runs with a zero window, so no path can claim an apply is under way.
|
||||
- `internal/api/handlers_updates.go` — no in-cluster runner applies updates. The host
|
||||
`felis update --apply` now consumes the stored window and refuses outside it unless
|
||||
explicit `--now` starts manual maintenance. The check/record runner remains read-only.
|
||||
- `internal/submit/blobstore.go` — CLOSED 2026-09-22. The uploads PVC still cannot
|
||||
cross namespaces, so the transport went through the API instead of a mount: the
|
||||
derived context ref is now the internal-face URL
|
||||
|
||||
+6
-9
@@ -4185,15 +4185,12 @@ paths:
|
||||
operationId: getUpdateWindow
|
||||
summary: Read the SysAdmin-set auto-update maintenance window (admin).
|
||||
description: >-
|
||||
Advisory: Felis applies no update on its own. `felis update` on the
|
||||
host reads this window, reports where now sits against it, and warns
|
||||
before an apply outside it.
|
||||
The single platform-wide maintenance window during which Felis may apply a
|
||||
Scheduled component's update to itself (decision core internal/updates). An
|
||||
unset window — never set, or explicitly cleared — reads back as
|
||||
{start:null,end:null}. API+persistence only: nothing consumes the window
|
||||
until the INTEGRATION runner and executors are wired, so setting it changes
|
||||
no behavior yet.
|
||||
Felis applies no update on its own. `felis update` checks versions and
|
||||
prints an explicit apply command. `felis update --apply` reads this
|
||||
platform-wide [start,end) window before backup and before installation,
|
||||
refusing outside it unless `--now` explicitly starts manual maintenance.
|
||||
An unreadable window is always a refusal, including with `--now` or
|
||||
`--force`. An unset window reads back as {start:null,end:null}.
|
||||
x-felis-face: [external]
|
||||
x-felis-tier: admin
|
||||
security: [{ sessionCookie: [] }]
|
||||
|
||||
+41
-10
@@ -501,8 +501,8 @@ store=/var/lib/rancher/k3s/storage
|
||||
|
||||
## 4. Upgrading the pieces around Felis
|
||||
|
||||
A rerun of the installer upgrades Felis itself (§15). The components it installs keep
|
||||
the version they were installed with unless noted:
|
||||
The host updater reuses the installer to reconcile Felis itself and its core components
|
||||
(§15). The components it installs keep the version they were installed with unless noted:
|
||||
|
||||
| Component | How a rerun treats it | Upgrade |
|
||||
|---|---|---|
|
||||
@@ -513,23 +513,54 @@ the version they were installed with unless noted:
|
||||
| PostgreSQL | follows the image the release pins | a minor release comes with a Felis release, and the rerun restarts felis-postgres on it (a few seconds without the API); a major version is a dump and restore (below) |
|
||||
| Docker, git, nftables | distribution packages | the package manager |
|
||||
|
||||
`felis update` is a read-only check. It reports upstream availability, resolves the
|
||||
Felis target, downloads and syntax-checks its matching installer, and prints an explicit
|
||||
apply command. The upstream table is advisory: applying uses the target's compatible
|
||||
pins, rather than installing each component's newest upstream version independently.
|
||||
`--k3s`, `--cloudflared`, `--jre` and `--postgres` narrow the report; applying any core
|
||||
selector reconciles the whole platform bundle. `--all` also enables the release-pinned
|
||||
k3s and cloudflared upgrades. Minecraft user server images stay pinned.
|
||||
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/FelisMC/Felis/main/deploy/bootstrap.sh \
|
||||
| sudo FELIS_UPGRADE_DEPS=1 bash
|
||||
sudo felis update # newest stable release; no installation
|
||||
sudo felis update --all # also plan pinned host dependency upgrades
|
||||
sudo felis update --version v0.2.0 # inspect a named published release
|
||||
sudo felis update --dev # inspect the latest main commit
|
||||
sudo felis update --ref <commit-or-tag> # inspect a specific source tree
|
||||
```
|
||||
|
||||
`sudo felis update` reports Felis, Velocity, k3s, cloudflared, the JRE and PostgreSQL
|
||||
against their newest releases; `--k3s`, `--cloudflared`, `--jre` and `--postgres` narrow
|
||||
it to one. PostgreSQL is read from the felis-postgres container and compared within its
|
||||
major, since a minor release arrives with a Felis release, and a major past its end of life
|
||||
gets a note naming the current one.
|
||||
Review the target, full commit, scope and restart impact, then run the exact `--apply`
|
||||
command printed by the check. A source apply uses the full SHA, while a release apply
|
||||
also includes `--expect-commit` so a moved tag is refused. `--apply --dev` is supported
|
||||
for deliberately resolving main at execution time; the printed command pins the commit
|
||||
you inspected instead.
|
||||
|
||||
Set the maintenance window in **Admin → Updates** first. Application reads that window
|
||||
before backup and again before installation: unset, future or expired windows refuse
|
||||
application. `--apply --now` explicitly starts one-off manual maintenance instead;
|
||||
an unreadable window is always refused. The daily `--record` timer never applies.
|
||||
`--force` reinstalls the same version or permits an intentional Felis downgrade; it
|
||||
never bypasses the window, backup or component compatibility guards.
|
||||
|
||||
Before installation the running binary takes a database + `/etc/felis` + MinecraftServer
|
||||
specification backup; failure stops the update. Worlds are covered separately by server
|
||||
backups (§16), not this control-plane snapshot. Application then streams the existing
|
||||
installer's progress, reconciles the CLI, API/operator/panel, manifests/RBAC, plugins,
|
||||
proxy and system images, and verifies the installed binary's version. Installer rollout
|
||||
checks still gate success. A failed installer can leave some components changed: retain
|
||||
the pre-update backup and follow troubleshooting §15/§16; schema rollback is not automatic.
|
||||
PostgreSQL major changes require dump/restore, and k3s upgrades cannot skip a minor version.
|
||||
|
||||
Older host binaries whose `update -h` has no `--apply` need one installer run to acquire
|
||||
this updater. Published assets are checksum-verified; older releases without the required
|
||||
installer options must be selected through `--ref` for a source build instead.
|
||||
|
||||
The installer also sets up `felis-update-check.timer`, which runs `felis update --record`
|
||||
once a day around 05:30 (and at boot after a missed run). `--record` stores the result
|
||||
in `platform_settings`, and the panel's **Admin → Updates → Component versions** card
|
||||
shows it: each component's installed and newest version, and for the ones with a newer
|
||||
release the `sudo felis update --<component>` line that prints how to apply it. Felis
|
||||
applies nothing on its own; the installer re-run above is the apply path. The card turns
|
||||
applies nothing on its own; the explicit `--apply` command above is the apply path. The card turns
|
||||
red when the newest record is older than 26 hours, meaning the timer stopped:
|
||||
|
||||
```sh
|
||||
|
||||
+12
-8
@@ -2136,14 +2136,18 @@ annotated Service endpoints picks them up as is.
|
||||
|
||||
## 15. Control-plane upgrades, and rolling back a bad one
|
||||
|
||||
There is no in-place updater: an upgrade is re-running the installer
|
||||
(`curl -fsSL <installer URL> | sudo bash`), which imports the release's images
|
||||
(or rebuilds them on the host, operations §1 "Where the binary and the images come
|
||||
from") and re-applies the bundle. `felis update --panel` prints that command with the
|
||||
script read at the newest release's tag, so the installer and the binary it
|
||||
downloads come from the same release. (`sudo felis setup` is not this path; on a completed
|
||||
install it only opens the config console.) The channel is not persisted across
|
||||
the re-run, so pass `FELIS_VERSION_BOOTSTRAP=dev` on a host that tracks main.
|
||||
`felis update` checks only; it prints a target and explicit `--apply` command. The host
|
||||
updater downloads the installer from the target's resolved full commit, backs up the
|
||||
database and deployment state, then uses that installer to reconcile the CLI, core
|
||||
services, plugins and system images. See operations §4 for `--version`, `--ref`, `--dev`
|
||||
and `--all`. Use the exact printed command to retain the reviewed target. Application
|
||||
requires an active maintenance window or explicit `--now`; `--force` never skips the
|
||||
backup, an unreadable window or compatibility guards.
|
||||
|
||||
A host whose `felis update -h` lacks `--apply` still needs one installer run
|
||||
(`curl -fsSL <installer URL> | sudo bash`) to acquire the new CLI. `sudo felis setup`
|
||||
on a completed install opens the configuration console, so it is not an upgrade path.
|
||||
The updater reuses the same checksum, image import/build and rollout checks as that installer.
|
||||
Two properties of the control plane matter when you do:
|
||||
|
||||
- Both Deployments use strategy **Recreate** (single replica, no leader election:
|
||||
|
||||
Reference in new issue
Block a user