TrueNAS compatibility: the patch's assumptions no longer hold #5

Closed
opened 2026-07-13 16:28:54 -04:00 by gitea-actions · 1 comment

tools/compat.py checks what this patch assumes about middlewared against iXsystems' actual source, every day. Those assumptions no longer hold on the versions below.

This does not break anyone today. apply.sh re-checks on every boot and declines to apply a module whose assumptions fail, so TrueNAS is left stock rather than half-patched. The cost is the module's feature, not a broken backup.

release/26.0.0-BETA.3

nested

  • plugins/zfs_/dataset.py no longer exists, so zfs.dataset.query is gone

    SNAPSHOT_BLOCK enumerates FILESYSTEM datasets to build the staging plan
  • plugins/zfs_/snapshot.py no longer exists, so zfs.snapshot.delete is gone

    delete_snapshot_tree() sweeps the recursive snapshot. Without it every run orphans one snapshot per descendant dataset (250 on a real pool)
  • plugins/zfs_/snapshot.py no longer exists, so zfs.snapshot.query is gone

    delete_snapshot_tree()'s fallback sweep enumerates the tree by name

master

nested

  • restic_backup('context', 'job', 'entry', 'credentials', 'dry_run', 'rate_limit') — positional parameters changed; the patch calls it as (middleware, job, cloud_backup)

    SYNC_BLOCK wraps it to tear down bind mounts in a finally
  • plugins/zfs_/dataset.py no longer exists, so zfs.dataset.query is gone

    SNAPSHOT_BLOCK enumerates FILESYSTEM datasets to build the staging plan
  • plugins/zfs_/snapshot.py no longer exists, so zfs.snapshot.delete is gone

    delete_snapshot_tree() sweeps the recursive snapshot. Without it every run orphans one snapshot per descendant dataset (250 on a real pool)
  • plugins/zfs_/snapshot.py no longer exists, so zfs.snapshot.query is gone

    delete_snapshot_tree()'s fallback sweep enumerates the tree by name

providers

  • get_restic_config('entry', 'credentials') — positional parameters changed; the patch calls it as (cloud_backup)

    RESTIC_BLOCK wraps it to rewrite the repo URL; it calls the original WITHOUT await, so it must stay synchronous
Full support matrix
TrueNAS B2/S3 providers Nested snapshots Hardware-verified
24.10.2.4 ok ok —
25.04.2.6 ok ok —
25.10.4 ok ok nested + providers; 252-snapshot recursive backup of /mnt/Tap, 18m
26.0.0-BETA.3 (unreleased) ok BROKEN —
master (unreleased) BROKEN BROKEN —
verdict meaning
ok Every assumption the patch makes about middleware still holds.
BROKEN middleware changed underneath the patch. apply.sh refuses to apply that module on this version and leaves TrueNAS stock, so backups keep working — without the module's feature.
native TrueNAS does this itself now. The module retires; it is not a failure.

"ok" means the patch's assumptions hold, checked automatically against iX's
source. It does not mean a human ran a backup on it — that is the
Hardware-verified column, which is filled in by hand and only by doing it.

Filed and kept up to date by compat.yml. It edits this body when the findings change, and stays quiet when they do not.

`tools/compat.py` checks what this patch assumes about middlewared against iXsystems' actual source, every day. Those assumptions no longer hold on the versions below. **This does not break anyone today.** `apply.sh` re-checks on every boot and **declines to apply** a module whose assumptions fail, so TrueNAS is left stock rather than half-patched. The cost is the module's feature, not a broken backup. ### `release/26.0.0-BETA.3` **nested** - plugins/zfs_/dataset.py no longer exists, so `zfs.dataset.query` is gone <br><sub>SNAPSHOT_BLOCK enumerates FILESYSTEM datasets to build the staging plan</sub> - plugins/zfs_/snapshot.py no longer exists, so `zfs.snapshot.delete` is gone <br><sub>delete_snapshot_tree() sweeps the recursive snapshot. Without it every run orphans one snapshot per descendant dataset (250 on a real pool)</sub> - plugins/zfs_/snapshot.py no longer exists, so `zfs.snapshot.query` is gone <br><sub>delete_snapshot_tree()'s fallback sweep enumerates the tree by name</sub> ### `master` **nested** - restic_backup('context', 'job', 'entry', 'credentials', 'dry_run', 'rate_limit') — positional parameters changed; the patch calls it as (middleware, job, cloud_backup) <br><sub>SYNC_BLOCK wraps it to tear down bind mounts in a finally</sub> - plugins/zfs_/dataset.py no longer exists, so `zfs.dataset.query` is gone <br><sub>SNAPSHOT_BLOCK enumerates FILESYSTEM datasets to build the staging plan</sub> - plugins/zfs_/snapshot.py no longer exists, so `zfs.snapshot.delete` is gone <br><sub>delete_snapshot_tree() sweeps the recursive snapshot. Without it every run orphans one snapshot per descendant dataset (250 on a real pool)</sub> - plugins/zfs_/snapshot.py no longer exists, so `zfs.snapshot.query` is gone <br><sub>delete_snapshot_tree()'s fallback sweep enumerates the tree by name</sub> **providers** - get_restic_config('entry', 'credentials') — positional parameters changed; the patch calls it as (cloud_backup) <br><sub>RESTIC_BLOCK wraps it to rewrite the repo URL; it calls the original WITHOUT await, so it must stay synchronous</sub> <details><summary>Full support matrix</summary> | TrueNAS | B2/S3 providers | Nested snapshots | Hardware-verified | | --- | --- | --- | --- | | 24.10.2.4 | ok | ok | — | | 25.04.2.6 | ok | ok | — | | 25.10.4 | ok | ok | nested + providers; 252-snapshot recursive backup of /mnt/Tap, 18m | | 26.0.0-BETA.3 _(unreleased)_ | ok | **BROKEN** | — | | master _(unreleased)_ | **BROKEN** | **BROKEN** | — | | verdict | meaning | | --- | --- | | **ok** | Every assumption the patch makes about middleware still holds. | | **BROKEN** | middleware changed underneath the patch. `apply.sh` **refuses to apply that module** on this version and leaves TrueNAS stock, so backups keep working — without the module's feature. | | **native** | TrueNAS does this itself now. The module retires; it is not a failure. | "ok" means *the patch's assumptions hold*, checked automatically against iX's source. It does not mean a human ran a backup on it — that is the **Hardware-verified** column, which is filled in by hand and only by doing it. </details> _Filed and kept up to date by [`compat.yml`](.github/workflows/compat.yml). It edits this body when the findings change, and stays quiet when they do not._ <!-- compat-fingerprint: c5443d25599f34f7 -->
Owner

Duplicate of #1 — closing.

This was not a second finding. find_issue() in tools/compat_publish.py skipped pull requests by testing for the presence of the pull_request key: GitHub omits it on a plain issue, Gitea sends it as null. So on Gitea the lookup discarded every issue as if it were a PR, came back empty, and the bot filed a brand-new report on every run instead of editing the one already open.

Fixed in 52b11ea. #1 is now the single living report and is edited in place.

Duplicate of #1 — closing. This was not a second finding. `find_issue()` in `tools/compat_publish.py` skipped pull requests by testing for the *presence* of the `pull_request` key: GitHub omits it on a plain issue, Gitea sends it as `null`. So on Gitea the lookup discarded every issue as if it were a PR, came back empty, and the bot filed a brand-new report on every run instead of editing the one already open. Fixed in 52b11ea. #1 is now the single living report and is edited in place.
flan closed this issue 2026-07-13 22:40:24 -04:00
Sign in to join this conversation.
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: flan/truenas-truecloud-patch#5