-
Notifications
You must be signed in to change notification settings - Fork 0
Updates
warden can tell you when a newer version exists, and a hub can ask every machine in a fleet to go and fetch it.
$ warden update
warden 0.4.0 is out, this is 0.3.0
https://github.com/vxnsin/warden/releases/tag/v0.4.0
installed as uv tool - ~/.local/share/uv/tools/warden-ports
to update: uv tool upgrade warden-ports
`warden update --apply` runs it here.A running warden asks GitHub for the newest release every six hours and keeps the answer in memory, so the command returns instantly and nothing waits on the network. If it has no answer it says why rather than guessing:
0.1.0; vxnsin/warden has published no releases yet
Nothing is ever compared to a version that is not a version: a tag like
nightly is ignored, and a pre-release is not treated as newer than the release
it precedes.
Turn the check off entirely with WARDEN_UPDATE_CHECK=false. It is the only
thing warden sends anywhere, it fails silently when the machine is offline, and
it never blocks a command.
From where the process actually lives. Guessing wrong between uv tool upgrade
and pip install -U installs a second copy beside the one you are running, and
then a version number stops meaning anything.
| Where warden is | What it says |
|---|---|
uv/tools/warden-ports |
uv tool upgrade warden-ports |
pipx/venvs/warden-ports |
pipx upgrade warden-ports |
a project .venv with a uv.lock beside it |
uv sync --upgrade-package warden-ports |
a project .venv without one |
<that interpreter> -m pip install --upgrade warden-ports |
| a checkout |
git pull && uv sync — printed, never run |
| a container |
docker pull ghcr.io/vxnsin/warden:latest — printed, never run |
| anywhere else | <this interpreter> -m pip install --upgrade warden-ports |
The last two are advice rather than commands warden will run: one is two
commands and a shell, the other has to happen outside the container it is
about. warden update --apply prints them and stops.
warden doctor says the same thing, so a machine that is behind explains
itself without being asked twice.
warden publishes as warden-ports — warden on PyPI is an unrelated
project. A copy installed as warden is told to replace itself rather than
upgrade:
installed as `warden`, which is a different project on PyPI; this one
publishes as `warden-ports`
to update: uv tool uninstall warden && uv tool install warden-ports
Upgrading that name would fetch somebody else's program. Replacing it also
clears a stale copy shadowing the new one on PATH, which is how a machine
ends up reporting a version it stopped running weeks ago.
$ warden update --apply
Update the warden at http://127.0.0.1:7010? [y/N]: y
Successfully installed warden-ports-0.4.0This runs the command that machine would print — or the one it is configured
with, if WARDEN_UPDATE_COMMAND is set. What is written down always wins:
somebody who wrote a command knows something about the machine that no amount
of looking would find.
From the hub:
$ warden update --fleet --yes --url http://hub:7010
NODE RESULT DETAIL
build-01 updated Successfully installed warden-0.2.0
db-03 refused updating over the API is switched off - set
WARDEN_ALLOW_REMOTE_UPDATE=true on this warden to allow it
hub updated Successfully installed warden-0.2.0
web-02 updated Successfully installed warden-0.2.0Every node is asked and every answer is reported. One machine refusing, or being unreachable, does not stop the others and does not fail the command — you get a row per node saying what happened to it.
This is the part worth being careful about, so it is worth stating plainly.
POST /v1/update means "update yourself". It carries no payload. What
updating means on a given machine comes from that machine's own
WARDEN_UPDATE_COMMAND and from nowhere else.
The alternative — letting the hub send a command to run — would make warden a way to execute anything, anywhere in the fleet. One leaked cluster token would then be worth every machine it can reach. As it stands, the worst a leaked token can do is ask machines to run the update they were already configured to run.
Two switches have to be on before anything happens at all, and both live on the machine being asked:
| Setting | Without it |
|---|---|
WARDEN_ALLOW_REMOTE_UPDATE=true |
403, "updating over the API is switched off" |
WARDEN_UPDATE_COMMAND |
only where the machine has no single command of its own - a checkout, a container |
WARDEN_ALLOW_REMOTE_UPDATE defaults to off, so a warden you have not
deliberately configured for this refuses and says so. WARDEN_UPDATE_COMMAND
is no longer required: a machine that knows how it was installed knows what to
run. One where that is not a single command still has to be told.
It runs without a shell, so it is one program with arguments rather than a pipeline. Put anything longer in a script and point at the script.
Installed from PyPI, which is the usual case:
WARDEN_UPDATE_COMMAND="/usr/local/bin/update-warden.sh"#!/bin/sh
set -e
uv tool upgrade warden-ports
systemctl --user restart wardenFrom a checkout, if the machine runs your own copy:
#!/bin/sh
set -e
cd /opt/warden
git pull --ff-only
uv tool install . --force
systemctl --user restart wardenThe restart is your job. warden does not restart itself: it cannot report the result of a command that ends the process running it. Whatever you configure should finish by restarting the service, and the row you get back is the output of the command up to that point.
Note also that the machine has to be able to reach wherever it pulls from. A node that can talk to the hub but not to your git host will refuse with whatever git said, which is the point of passing the output back.
| Variable | Default | Meaning |
|---|---|---|
WARDEN_UPDATE_CHECK |
true |
Ask GitHub whether a newer release exists |
WARDEN_UPDATE_REPO |
vxnsin/warden |
Which repository to ask about |
WARDEN_UPDATE_INTERVAL |
21600 |
Seconds between checks, at least 300 |
WARDEN_ALLOW_REMOTE_UPDATE |
false |
Let a caller ask this warden to update itself |
WARDEN_UPDATE_COMMAND |
empty | What updating means here, when how it was installed is not enough |
| Method | Path | Token | Purpose |
|---|---|---|---|
GET |
/v1/update |
either | Whether a newer warden exists |
POST |
/v1/update |
either | Ask this warden to update itself |
POST |
/v1/fleet/update |
API | Ask every warden in the fleet to update itself |
"Either" means the API token or the cluster token: a hub does this on its rounds,
an operator does it by hand, and WARDEN_ALLOW_REMOTE_UPDATE is the gate that
actually decides.
warden — nothing binds a port without asking ·
uv tool install warden-ports
Repository · Issues · Releases · PyPI · MIT
Getting started
While it runs
Several machines
Reference