Upgrade and roll back¶
For an installation from the self-hosting bundle. An upgrade takes the server to the release in a newer bundle and keeps every person, Device and session; a rollback takes it back to the release the last upgrade replaced, or to an older one you name.
Every command here runs from the folder of the release that runs now, as
the user who owns its .env (mode 0600, so only its owner can read it) and
may run docker. Another user who may run docker is refused, because it
cannot read the file: the upgrade says cannot read <folder>/.env, ..., and
the rollback says <folder>/.env records no FLEETVIEW_VERSION. An upgrade backs the database up first, and
a rollback restores that backup: Back up, restore and
uninstall says how backups are taken, kept and
restored.
Installing a later release¶
One command takes the server to the release in a newer bundle and keeps
every person, Device and session. The uploaded licence, Settings and roles
are kept too, so nothing is uploaded or set again. Before you upgrade, read
the new release's Requires of you section in the Changelog.
Download the new
winner-ai-server-<X.Y.Z>.tar.gz anywhere outside the installed folder,
then, from the installed release's folder (winner-install/winner-ai-server-<old X.Y.Z>
for the first upgrade), as the user who owns its .env, giving the path
you downloaded it to:
./scripts/upgrade-server.sh /path/to/winner-ai-server-<X.Y.Z>.tar.gz
There is nothing to verify by hand: the installed release checks the new
bundle's signature against the release key it carries, then every file, and
refuses anything else. ./scripts/upgrade-server.sh --help lists its steps
in order. It unpacks the new release beside the installed one, in
winner-install-<X.Y.Z>/winner-ai-server-<X.Y.Z>, carries .env across
(the telemetry secret with it), runs the new release's host and .env
checks and pulls its Docker Hub images, then backs up the database with
scripts/backup-server.sh. Until that backup has passed its restore test,
nothing that runs is touched. Only then does it load and start the new
release, which migrates the database, and wait for it to answer with every
migration applied:
upgrade-server: step 1 of 10: check the new bundle: ...
upgrade-server: the new bundle is v<X.Y.Z>, signed by the release key, every file as signed
upgrade-server: upgrading v<old X.Y.Z> in <old folder> to v<X.Y.Z> in <new folder>
...
upgrade-server: the database is backed up at <folder the archive is in>/pre-upgrade-v<old X.Y.Z>-<UTC stamp>.sql.gz
...
upgrade-server: every migration v<X.Y.Z> holds is applied
upgrade-server: the web server runs the new bundle's binary
upgrade-server: the edge serves ports 80 and 443
upgrade-server: the org schemas hold only what agentsview creates
upgrade-server: upgraded v<old X.Y.Z> -> v<X.Y.Z>; the previous release stays in <old folder> for a rollback, its images loaded
When usage counts are off, or the telemetry secret is not set, a line before
the last says usage counts are off or the telemetry secret is not set; the
upgrade was not reported.
By default the backup goes in the folder the new bundle's archive is in.
--backup <file> writes the backup somewhere else; like any backup it must
be outside both release folders. The new release's folder is where you run
docker compose from now on: its .env names the compose files and the
release. Keep the previous folder and its images, and never prune images:
they are what a failed upgrade, and a rollback, start again.
winner-install-<X.Y.Z>/winner-upgrade.record records the release replaced,
its folder and the backup's path, for the rollback.
Laptops after an upgrade. Nothing runs on a laptop. Each one keeps
pushing with the agentsview and winner it has until winner update
brings it to the versions the new release runs. A Mac or Linux laptop whose
winner login ran without --no-service runs it on its own each day
(Running on its own), except a Linux
laptop without systemd, which gets only the crontab lines winner login
printed, to add by hand. On any other laptop its owner runs
winner update.
On the server, point your nightly backup line at the new release's folder (Schedule it and copy it off the server), and rehearse a restore again (Rehearse a restore).
Auth0 after an upgrade or a rollback. The tenant's post-login Action is deployed by hand, so neither command changes it. Compare it with the copy in the release that now runs, as The post-login Action says, and deploy that copy if they differ.
A slow upgrade is not a failed one. A release that moves the collector
version rebuilds every organisation's schema on its first start, which can
take half an hour, and the control plane does not answer until it is done;
the command says so about once a minute. If it is still migrating after
thirty minutes (UPGRADE_WAIT_SECONDS), it puts nothing back, says
still migrating after 1800s; this is slow, not failed, and exits 3. Watch
it with docker compose logs -f backend in the new release's folder, and
when it is done, run ./scripts/upgrade-server.sh --finish there.
When it refuses, before it starts the new release, it prints one
upgrade-server: FAIL: line saying nothing was changed, removes the new
folder, and the installed release runs as before. A refusal once the backup
has passed, docker load failing included, also says the backup at <file>
stays:
| What it says | What to do |
|---|---|
SHA256SUMS.sig is signed by another key (...), ... was made in the licence namespace, or SHA256SUMS does not match its signature in SHA256SUMS.sig: ... |
The archive is not a release Winner AI signed for you, or it was changed. Download it again; if it still says so, ask your Winner AI contact |
these files of the new bundle do not match SHA256SUMS: ..., the new bundle holds files SHA256SUMS does not name: ..., or ... holds a link or a special file |
The archive changed after it was signed. Download it again |
no .env in <folder>; ..., cannot read <folder>/.env, ... or <folder>/.env records no FLEETVIEW_VERSION; ... |
Run it from the installed release's folder, as the user who owns its .env |
<tool> is not installed, and the new bundle cannot be checked without it |
Install the tool it names (ssh-keygen, sha256sum, tar or od), and run it again |
the new bundle carries no scripts/<name>.sh to finish the upgrade with, or to roll it back |
The archive is not a whole release. Download it again |
this server already runs v<X.Y.Z> |
Nothing to do |
the new bundle is v<X.Y.Z>, older than v<old X.Y.Z> which this server runs; migrations do not reverse, ... |
The upgrade command never installs an older bundle over a newer release. To go back to the release the last upgrade replaced, roll back (Going back to the previous release); to an older release, roll back with --bundle naming its folder and --backup the backup taken before the upgrade from it |
winner-install-<X.Y.Z> already exists; ... |
An earlier attempt left that folder, and it may hold a release that ran. Read winner-install-<X.Y.Z>/winner-upgrade.record first. state=migrating: the upgrade was slow, not failed; run ./scripts/upgrade-server.sh --finish in its release folder. state=started: it was interrupted while the new release started; do what that run printed, as When it fails after the start below says. state=done: that release is installed, so run from its folder. No record: nothing started from it; move it aside, and run it again |
the backup: ... |
Choose another --backup path; the reason says why this one was refused |
<folder>/.env names COMPOSE_FILE=<files>, not the bundle's docker-compose.yml:docker-compose.prod.yml:docker-compose.bundle.yml, COMPOSE_FILE in <folder>/.env names <path>, which is not an absolute path to a file, or ... inside a release folder |
The upgrade command moves a production install only, never a trial (A trial from the bundle), whose .env names no production overlay. On a production install, put COMPOSE_FILE in that .env back to the bundle's three files, with any file of your own after them as an absolute path outside both release folders, and run it again |
<old folder> has no scripts/backup-server.sh to back the database up with |
The installed release's folder is incomplete: run it from the folder the installer or the last upgrade left running |
this host is missing what v<X.Y.Z> needs (above) |
Fix each check-host: FAIL: line above it, and run it again |
v<X.Y.Z>'s scripts/check-env.sh refused .env (above) |
The new release needs a change to .env: make it in the installed release's .env, and run it again |
<image> is neither in the new bundle nor a pinned Docker Hub image |
A compose file of your own, named in COMPOSE_FILE after the bundle's three, adds an image that is not pinned by @sha256: on Docker Hub. Pin it by digest, and run it again |
could not pull <image> from Docker Hub: ... |
As at install (step 5): wait, and run it again |
the running release does not answer as v<old X.Y.Z> ... or the database of the release in <folder> is not running |
Start the installed release (docker compose up -d in its folder) and run it again |
<image>, which v<old X.Y.Z> runs, is no longer loaded, ... |
An image of the installed release was removed. One of ours: load its images.tar again (docker load -i images.tar in its folder). A Docker Hub image, named by @sha256: and not in images.tar: pull it again by that name (docker pull <image>) |
the backup failed: ... |
Fix what the backup's own line names (Take a backup) |
the backup did not report a passed restore test: ... |
The pre-upgrade backup was written but its restore test did not pass; the line quotes the backup's last line. Fix what it names, and run it again |
docker load could not load the new images.tar: ... or docker load left no ... |
The line gives Docker's own reason. Fix it, and run it again; the backup it took stays |
When it fails after the start, it puts the previous release's containers back from its own folder and prints one line saying why, the command that restores the database as it was before the upgrade, and where it kept the attempt:
upgrade-server: FAIL: the upgrade to v<X.Y.Z> failed: the migration did not complete: ...; v<old X.Y.Z>'s containers are running again
upgrade-server: to restore the database as it was before the upgrade, in <old folder> run: scripts/restore-server.sh <backup>
upgrade-server: the new release and its record are kept in <parent>/winner-install-<X.Y.Z>.failed-<UTC stamp>
If the containers cannot be put back, the first line ends v<old X.Y.Z>'s
containers could not be put back: <reason> instead: start the previous
release yourself with docker compose up -d in its folder, then read on.
Ctrl-C, or a TERM signal, after the start puts nothing back. It prints
interrupted while v<X.Y.Z> was starting; nothing was put back, the
docker compose up -d that puts the previous release back, with its
folder, and the same restore command. From step 2 until the start, an
interrupt is a refusal like any other.
Migrations do not reverse, so a failed one may leave the database in a state the previous release does not expect: if it misbehaves, run the restore command it printed (Restore), which takes the database back to the backup, and send the failure line to your Winner AI contact. When the new release carried another collector version, a line before the restore command says so: the previous release has just run its older collector over organisations' schemas the new release may have rebuilt, so run the restore before your team uses it.
Why an older release is refused¶
Migrations only go forward. The control plane migrates the database to its
own release when it starts, so an older release would start on tables it
does not know. The upgrade command therefore refuses a bundle older than
the release this server runs, before its long check of images.tar, and
the installer (scripts/install-server.sh) refuses one over a newer
release that runs. The only way back is the rollback, below: it restores
the pre-upgrade backup first, and starts the previous release only once
that restore has passed. The installer sees only a stack that runs: over a
stopped one it does not know which release last ran, and an older bundle
is not refused.
The upgrade command's refusal begins:
upgrade-server: FAIL: the new bundle is v<X.Y.Z>, older than v<old X.Y.Z> which this server runs; migrations do not reverse, ...
Going back to the previous release¶
Migrations do not reverse, so the release an upgrade replaced never starts
on the database the newer one migrated. The rollback command puts both
back: the database as it was before the upgrade, from the backup the
upgrade took, then the previous release. From the folder of the release
that runs now, as the user who owns its .env:
./scripts/rollback-server.sh
It reads winner-upgrade.record beside that folder for the previous
release's folder and the pre-upgrade backup (--bundle <folder> and
--backup <file> name others, and both are needed without a record). It
checks the previous folder's signature and every file as the upgrade
checks a new bundle, refuses a backup that is partial or marked failed, and
changes nothing until you type the previous release back:
rollback-server: rolling back v<X.Y.Z> in <folder> to v<old X.Y.Z> in <old folder>
rollback-server: everything written since the upgrade at <time> will be replaced by <backup>: people, Devices, settings and the sessions laptops pushed
rollback-server: the database as it is now is backed up first, to <folder of the backup>/pre-rollback-v<X.Y.Z>-<UTC stamp>.sql.gz
rollback-server: a laptop enrolled since must run `winner login` again; a Device revoked since comes back unable to log in and must be revoked again
Type v<old X.Y.Z> to roll back to it:
--pre-rollback-backup <path> writes that backup somewhere else; like any
backup it must be outside both release folders. --yes skips the question.
It then restores the backup with scripts/restore-server.sh
(Restore), which keeps
laptops out while it replays, and starts the previous release only once
the restore has passed. It is done when that release answers with every
migration applied:
rollback-server: the newer release and its record are kept in <parent>/winner-install-<X.Y.Z>.rolled-back-<UTC stamp>; never run docker compose there
rollback-server: rolled back v<X.Y.Z> -> v<old X.Y.Z>; the database is as it was at <time>
rollback-server: the database as it was before the rollback is in <pre-rollback backup>
rollback-server: run docker compose from <old folder> from now on; point your nightly backup line at it
rollback-server: a laptop enrolled since the upgrade must run `winner login` again; a Device revoked since cannot log in and must be revoked again from the roster
With --backup naming another backup than the record's, or without a
record, the two lines that give the upgrade's time name the backup
instead: the first says everything written since <backup> was taken will
be replaced by it, the last the database is as it was when <backup> was
taken.
The newer folder is kept as winner-install-<X.Y.Z>.rolled-back-<UTC stamp>
when the upgrade made it, and the first line says so; without a record it
stays where it is, and the first line reads the newer release stays in
<folder>; never run docker compose there. Never run
docker compose there. A laptop enrolled since the upgrade lost
its access in the restore and must run winner login again, and a Device
revoked since comes back unable to log in: revoke it again from the roster.
Sessions laptops pushed between the upgrade and the rollback are gone from
the archive, and laptops do not push them again: they are only
in the pre-rollback backup. When the two releases pin different collector
versions, the last line says so: a laptop that ran winner update against
the newer release runs the newer collector, which fails every push until
its next winner update takes it back down.
A refusal prints one rollback-server: FAIL: line saying nothing was
changed. A restore that fails before it replays changes nothing either.
One that fails once it has started replaying leaves laptops fenced out and
the stack stopped, and prints the two commands to choose from:
scripts/restore-server.sh <pre-rollback backup> in the newer release's
folder, which puts the newer release back as it was, or
scripts/rollback-server.sh there again, which restores the pre-upgrade
backup once more. A failure after the restore has passed leaves the
database fenced, so no laptop writes to a database half way between two
releases, and says which step failed: fix it, then run
./scripts/rollback-server.sh --finish in the same folder. A rollback cut
off during its restore (a dropped SSH session or a reboot) is taken up by
running ./scripts/rollback-server.sh again, which restores once more under
the fence it finds. An upgrade that failed, or was cut off before it
finished, has nothing to roll back: from the folder of the release it
started from, the command refuses even where an earlier upgrade's record
says done, and names the restore that undoes the attempt from that
attempt's own pre-upgrade backup. To roll back the upgrade before it
anyway, name its previous folder with --bundle and its backup with
--backup.