README: state and enforce the 24.10 minimum; document the compat preflight
TrueCloud Backup does not exist before 24.10, so on anything older the patch would attach to nothing and do nothing -- silently, while the user believed their backups were set up. install.sh now reads system.version and refuses, naming the reason. Also: the boot sequence now documents the preflight (and that an incompatible module is skipped for one boot, NOT kill-switched); the troubleshooting table covers the incompatibility warning; forge URLs point at Gitea.
This commit is contained in:
@@ -97,6 +97,14 @@ worse than no alert, because one day it carries a security fix.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- **The minimum supported TrueNAS is stated, and enforced: 24.10.** TrueCloud Backup
|
||||||
|
does not exist before it — `plugins/cloud_backup/` is simply absent — so the patch
|
||||||
|
had nothing to attach to and would have done nothing at all, silently, while the
|
||||||
|
user believed their backups were configured. `install.sh` now reads
|
||||||
|
`system.version` and refuses, naming the reason. A version it cannot *parse* is a
|
||||||
|
warning, not a refusal: declining to install over a string we failed to read would
|
||||||
|
be a worse failure than the one being prevented.
|
||||||
|
|
||||||
- **A stable release may not leave work stranded under `## Unreleased`.** Either it
|
- **A stable release may not leave work stranded under `## Unreleased`.** Either it
|
||||||
is finished and belongs in the release, or the release is premature. Candidates
|
is finished and belongs in the release, or the release is premature. Candidates
|
||||||
are exempt: an rc may legitimately have work queued behind it.
|
are exempt: an rc may legitimately have work queued behind it.
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
# truenas-truecloud-patch
|
# truenas-truecloud-patch
|
||||||
|
|
||||||
|
> ### Requires **TrueNAS SCALE 24.10 or newer**
|
||||||
|
>
|
||||||
|
> TrueCloud Backup — the feature this patch extends — **does not exist before
|
||||||
|
> 24.10**. There is nothing here to install on an older release, and `install.sh`
|
||||||
|
> will refuse.
|
||||||
|
>
|
||||||
|
> Verified on **24.10**, **25.04** and **25.10**. Not yet compatible with the
|
||||||
|
> unreleased **26.0** (see [TrueNAS compatibility](#truenas-compatibility)).
|
||||||
|
|
||||||
Extends TrueNAS SCALE's **TrueCloud Backup** feature to:
|
Extends TrueNAS SCALE's **TrueCloud Backup** feature to:
|
||||||
|
|
||||||
- work with S3-compatible providers and native Backblaze B2, instead of Storj only;
|
- work with S3-compatible providers and native Backblaze B2, instead of Storj only;
|
||||||
@@ -436,9 +445,20 @@ Two different things must survive two different events:
|
|||||||
so nothing registered there can run before it.
|
so nothing registered there can run before it.
|
||||||
2. **Pools import** (`ix-zfs.service`), making `/mnt/<pool>` — and this
|
2. **Pools import** (`ix-zfs.service`), making `/mnt/<pool>` — and this
|
||||||
repository — available.
|
repository — available.
|
||||||
3. **`apply.sh` runs** (`ix-preinit.service`): mounts the writable overlay
|
3. **`apply.sh` runs** (`ix-preinit.service`). Before it patches anything it runs
|
||||||
(upper layer in `/run`), patches `b2.py` and `restic.py` on disk inside it,
|
the **compatibility preflight** ([`tools/compat.py`](tools/compat.py)) against
|
||||||
patches the UI bundle, and writes `apply.log` and `hook_status.json`.
|
the middlewared that is *actually installed*, and **any module whose assumptions
|
||||||
|
no longer hold is not applied** — see [TrueNAS
|
||||||
|
compatibility](#truenas-compatibility). What survives that check gets applied:
|
||||||
|
it mounts the writable overlay (upper layer in `/run`), patches `b2.py` and
|
||||||
|
`restic.py` on disk inside it, patches the UI bundle, and writes `apply.log` and
|
||||||
|
`hook_status.json`.
|
||||||
|
|
||||||
|
An incompatible module is skipped **for this boot only**. It is not the kill
|
||||||
|
switch: install a release that supports your TrueNAS and the patch re-applies
|
||||||
|
itself on the next boot, with no manual step. (The kill switch is permanent and
|
||||||
|
is set only when TrueNAS has made the patch *unnecessary* — a different
|
||||||
|
situation, and the opposite conclusion.)
|
||||||
4. **A deferred restart is scheduled.** The middlewared that is running
|
4. **A deferred restart is scheduled.** The middlewared that is running
|
||||||
imported the stock modules in step 1 and never re-imports, so the on-disk
|
imported the stock modules in step 1 and never re-imports, so the on-disk
|
||||||
patch alone is not enough. `apply.sh` detects it was invoked by middlewared
|
patch alone is not enough. `apply.sh` detects it was invoked by middlewared
|
||||||
@@ -476,7 +496,7 @@ then run `install.sh` from there:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Replace /mnt/tank with your pool name
|
# Replace /mnt/tank with your pool name
|
||||||
git clone https://github.com/sudolulo/truenas-truecloud-patch.git \
|
git clone https://git.onetick.ninja/flan/truenas-truecloud-patch.git \
|
||||||
/mnt/tank/truenas-truecloud-patch
|
/mnt/tank/truenas-truecloud-patch
|
||||||
cd /mnt/tank/truenas-truecloud-patch
|
cd /mnt/tank/truenas-truecloud-patch
|
||||||
bash install.sh
|
bash install.sh
|
||||||
@@ -560,7 +580,7 @@ detonate on the next reboot. That is not hypothetical: **v0.0.4 shipped exactly
|
|||||||
such a bug and took all 54 apps on a box down.**
|
such a bug and took all 54 apps on a box down.**
|
||||||
|
|
||||||
The manual step *is* the safety gate. If you want convenience, watch the
|
The manual step *is* the safety gate. If you want convenience, watch the
|
||||||
[releases feed](https://github.com/sudolulo/truenas-truecloud-patch/releases);
|
[releases feed](https://git.onetick.ninja/flan/truenas-truecloud-patch/releases);
|
||||||
don't automate the pull.
|
don't automate the pull.
|
||||||
|
|
||||||
## Update alerts
|
## Update alerts
|
||||||
@@ -580,6 +600,17 @@ WARNING. The CHANGELOG's own section headings are the signal, and a security fix
|
|||||||
anywhere in the range escalates the whole span — a docs-only release on top of a
|
anywhere in the range escalates the whole span — a docs-only release on top of a
|
||||||
security fix still reports as security.
|
security fix still reports as security.
|
||||||
|
|
||||||
|
**Release candidates never alert.** They are invisible to `update.sh` and to the
|
||||||
|
alert, which both take the newest plain `vX.Y.Z` tag. That is what lets debugging
|
||||||
|
happen in `-rc` tags instead of in your notification bell — see
|
||||||
|
[Releasing](#releasing).
|
||||||
|
|
||||||
|
The changelog is read from whichever forge `origin` points at, derived from the
|
||||||
|
remote rather than hard-coded. That is not cosmetic: when the changelog cannot be
|
||||||
|
read, the alert deliberately fires **anyway** rather than risk hiding a security
|
||||||
|
fix — so a wrong URL would not silence the alert, it would make it fire on *every*
|
||||||
|
release, including the documentation-only ones this section promises to suppress.
|
||||||
|
|
||||||
### How it works, and why it's built this way
|
### How it works, and why it's built this way
|
||||||
|
|
||||||
TrueNAS **cannot raise an alert from the CLI** — `midclt` exposes only
|
TrueNAS **cannot raise an alert from the CLI** — `midclt` exposes only
|
||||||
@@ -720,7 +751,8 @@ python3 /mnt/tank/truenas-truecloud-patch/patch/create_task.py verify
|
|||||||
| What you see | What it means |
|
| What you see | What it means |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `[OK] providers`, `[OK]`/`[SKIP] nested_snapshots` | Fine. Nothing to do. |
|
| `[OK] providers`, `[OK]`/`[SKIP] nested_snapshots` | Fine. Nothing to do. |
|
||||||
| `WARNING: … pattern not found` (UI) | The Angular bundle changed. The UI dropdown reverts to Storj-only, but **backups keep working** — create tasks with `create_task.py` meanwhile, and [open an issue](https://github.com/sudolulo/truenas-truecloud-patch/issues) with your TrueNAS version. |
|
| `WARNING: … pattern not found` (UI) | The Angular bundle changed. The UI dropdown reverts to Storj-only, but **backups keep working** — create tasks with `create_task.py` meanwhile, and [open an issue](https://git.onetick.ninja/flan/truenas-truecloud-patch/issues) with your TrueNAS version. |
|
||||||
|
| `WARNING: truecloud-patch is NOT COMPATIBLE with this TrueNAS version` | This TrueNAS changed middleware underneath the patch, and the named module was **deliberately not applied** — see `incompatible.json` for exactly which assumption broke. TrueNAS is left stock, so nothing is half-patched. Check [TrueNAS compatibility](#truenas-compatibility), then `bash update.sh` once a release supports your version; it re-applies itself on the next boot. This is **not** the kill switch and needs no manual reset. |
|
||||||
| `[FAIL] providers` | **Your B2/S3 backups will not run.** middlewared is fine, but the credential/URL handling is gone. Open an issue with your version. |
|
| `[FAIL] providers` | **Your B2/S3 backups will not run.** middlewared is fine, but the credential/URL handling is gone. Open an issue with your version. |
|
||||||
| `[FAIL] nested_snapshots` | The stock guard is back, so tasks with `snapshot = true` on a nested dataset will fail validation. Turn the option off on those tasks until it's fixed. |
|
| `[FAIL] nested_snapshots` | The stock guard is back, so tasks with `snapshot = true` on a nested dataset will fail validation. Turn the option off on those tasks until it's fixed. |
|
||||||
|
|
||||||
@@ -842,7 +874,7 @@ If a module shows `[FAIL]`:
|
|||||||
risk.
|
risk.
|
||||||
4. **If the detail says the module doesn't exist**, a TrueNAS update renamed
|
4. **If the detail says the module doesn't exist**, a TrueNAS update renamed
|
||||||
or restructured the internal API.
|
or restructured the internal API.
|
||||||
[Open an issue](https://github.com/sudolulo/truenas-truecloud-patch/issues)
|
[Open an issue](https://git.onetick.ninja/flan/truenas-truecloud-patch/issues)
|
||||||
with your TrueNAS version number and the full verify output.
|
with your TrueNAS version number and the full verify output.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+38
@@ -88,6 +88,44 @@ if [ "$(id -u)" -ne 0 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ── Minimum TrueNAS version ───────────────────────────────────────────────────
|
||||||
|
#
|
||||||
|
# TrueCloud Backup -- the feature this whole project extends -- was introduced in
|
||||||
|
# 24.10. On anything older, `plugins/cloud_backup/` does not exist at all: there is
|
||||||
|
# no restic, no cloud_backup task type, and nothing for the patch to attach to. It
|
||||||
|
# would not break the box, it would simply do nothing, silently, while the user
|
||||||
|
# believed their backups were configured. Say no clearly instead.
|
||||||
|
#
|
||||||
|
# A version we cannot PARSE is not a version we may refuse on: warn and continue.
|
||||||
|
# Refusing to install over a string we failed to read would be a worse failure than
|
||||||
|
# the one being prevented.
|
||||||
|
MIN_TRUENAS="24.10"
|
||||||
|
|
||||||
|
_tc_version_raw=""
|
||||||
|
if command -v midclt &>/dev/null; then
|
||||||
|
_tc_version_raw=$(midclt call system.version 2>/dev/null || true) # TrueNAS-25.10.4
|
||||||
|
fi
|
||||||
|
# Both spellings are real: modern releases report `TrueNAS-25.10.4`, older ones
|
||||||
|
# `TrueNAS-SCALE-24.04.2` -- and the SCALE- form is used by exactly the versions
|
||||||
|
# this gate exists to turn away, so failing to parse it would let them through.
|
||||||
|
_tc_version=$(printf '%s' "$_tc_version_raw" \
|
||||||
|
| sed -n 's/^TrueNAS-\(SCALE-\)\{0,1\}\([0-9]\{1,\}\.[0-9]\{1,\}\).*/\2/p')
|
||||||
|
|
||||||
|
if [ -z "$_tc_version" ]; then
|
||||||
|
echo "WARNING: could not determine the TrueNAS version" \
|
||||||
|
"${_tc_version_raw:+(got '${_tc_version_raw}')}."
|
||||||
|
echo "WARNING: this patch requires TrueNAS SCALE ${MIN_TRUENAS} or newer. Continuing anyway."
|
||||||
|
echo ""
|
||||||
|
elif [ "$(printf '%s\n%s\n' "$MIN_TRUENAS" "$_tc_version" | sort -V | head -1)" != "$MIN_TRUENAS" ]; then
|
||||||
|
echo "ERROR: TrueNAS ${_tc_version} is too old — this patch requires ${MIN_TRUENAS} or newer." >&2
|
||||||
|
echo "" >&2
|
||||||
|
echo " TrueCloud Backup does not exist before ${MIN_TRUENAS}, so there is nothing" >&2
|
||||||
|
echo " here for the patch to extend. Upgrade TrueNAS first." >&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "TrueNAS ${_tc_version} (minimum ${MIN_TRUENAS}) — ok"
|
||||||
|
fi
|
||||||
|
|
||||||
if ! command -v midclt &>/dev/null; then
|
if ! command -v midclt &>/dev/null; then
|
||||||
echo "ERROR: midclt not found. Run this script on TrueNAS SCALE." >&2
|
echo "ERROR: midclt not found. Run this script on TrueNAS SCALE." >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user