v0.4.0: add update.sh

Fetch a newer release and apply it, preserving the nested-snapshot opt-in setting.

  bash update.sh              # to the newest release, with a confirmation
  bash update.sh --check      # show what would happen; change nothing
  bash update.sh --rollback   # undo the last update

Deliberately NOT automated. This patch injects Python into middlewared and
re-applies itself at every boot, so an unattended pull would let any bad upstream
commit reach a box with no human in the loop and take effect on the next reboot.
v0.0.4 shipped exactly such a bug and took every app on the box down. The manual
step is the safety gate.

Design decisions worth keeping:

- Defaults to the newest RELEASE TAG, not main. main can be mid-refactor; a tag is
  the tested artifact. --main exists but says so loudly.
- Tags ordered by version, not date. Date order silently downgrades the box the
  first time a hotfix is tagged out of band: a v0.3.6 cut after v0.4.0 would sort
  as "newest".
- Refuses to run over a dirty working tree rather than merging across hand-edited
  or scp'd files. (Verified: the guard fires.)
- Shows the commits and release notes you do not have, read from the TARGET's
  CHANGELOG via tools/release_notes.py -- not a second copy of the extractor.
- Records the previous revision BEFORE moving, so --rollback works even if
  install.sh dies halfway.
- Repairs .git ownership, which past `sudo git pull`s leave root-owned and which
  then breaks every later non-root git command.

update.sh is covered by the version-drift check, so it cannot go stale the way
create_task.py's __version__ did.

Tested end to end in a throwaway clone: detects v0.3.2 -> v0.3.5, lists missing
commits, handles already-up-to-date, and the dirty-tree guard fires.

132 tests, ruff and shellcheck clean.
This commit is contained in:
flan
2026-07-13 16:20:37 +00:00
parent 45f957af23
commit 347c415aa7
9 changed files with 290 additions and 23 deletions
+17 -16
View File
@@ -341,27 +341,28 @@ Refresh your browser. S3 and B2 credentials now appear in the
## Updating
To update to a new version of the patch:
```bash
cd /mnt/tank/truenas-truecloud-patch
# If install.sh was previously run as root, the .git directory may be owned
# by root. Fix it first, or just pull as root:
sudo git pull # easiest option
# — or —
sudo chown -R $(whoami) .git && git pull
bash install.sh
bash update.sh # to the newest release, with a confirmation
bash update.sh --check # show what would happen; change nothing
bash update.sh --rollback # undo the last update
```
`install.sh` clears any stale kill switch, re-applies the updated patches,
and restarts middlewared. Run `python3 patch/create_task.py verify` afterwards
to confirm the patches loaded successfully.
It preserves your nested-snapshot opt-in setting, shows you the commits and
release notes you don't have yet, and asks before changing anything. It records
the previous revision *before* moving, so `--rollback` works even if `install.sh`
dies halfway.
Check [CHANGELOG.md](CHANGELOG.md) to see what changed between versions.
**Run it by hand. Never from cron or a systemd timer.** This patch injects Python
into `middlewared` and re-applies itself at every boot, so an unattended pull would
let any bad upstream commit reach your box with no human in the loop and take
effect on the next reboot. v0.0.4 shipped exactly such a bug and took every app on
the box down. The manual step *is* the safety gate — if you want convenience, watch
the [releases](https://github.com/sudolulo/truenas-truecloud-patch/releases) feed,
don't automate the pull.
---
It updates to the newest **release tag**, not `main` — `main` can be mid-refactor,
and a tag is the tested artifact. `--main` exists if you want unreleased code, and
says so loudly.
## Creating a task via CLI