FreeNAS/freenas 72e2cbe — src/middlewared/middlewared/plugins/iscsi_ lio.py

Update how we tell LIO that an extent has resized.
DeltaFile
+2-2src/middlewared/middlewared/plugins/iscsi_/lio.py
+2-21 files

FreeNAS/freenas 2e9aa50 — src/middlewared/middlewared/api/v27_0_0 iscsi_global.py

Allow iSCSI mode=2
DeltaFile
+1-1src/middlewared/middlewared/api/v27_0_0/iscsi_global.py
+1-11 files

FreeNAS/freenas 5af664c — src/middlewared/middlewared/plugins/iscsi_ alua.py extents.py, src/middlewared/middlewared/utils/lio config.py

Add middleware support for LIO ALUA HA

Wire up the middleware side of LIO ALUA high-availability: load
lio_ha.ko with per-node addresses on service start, manage ALUA
state across failover events, clean up STANDBY configfs on pool
export, and add pre-flight validation that targets have static
initiator ACLs before ALUA can be enabled.

For each target, create a portal-less phantom TPG carrying the peer
node's controller group so that a single RTPG response from any
connected port lists both ALUA groups.  Write tpgt_N/rtpi explicitly
before enable so that relative target port IDs in RTPG match the
tag formula (portal.tag on Node A, portal.tag + 32000 on Node B)
rather than being auto-assigned sequentially by the kernel.

ALUA group states are driven by role and ha_state:

  MASTER  + synced        local=OPTIMIZED     remote=NONOPTIMIZED
  MASTER  + connected     local=OPTIMIZED     remote=TRANSITIONING

    [4 lines not shown]
DeltaFile
+537-135src/middlewared/middlewared/utils/lio/config.py
+214-2src/middlewared/middlewared/plugins/iscsi_/lio.py
+87-71src/middlewared/middlewared/plugins/iscsi_/fs_attachment_delegate.py
+89-58src/middlewared/middlewared/plugins/iscsi_/target_to_extent.py
+59-47src/middlewared/middlewared/plugins/iscsi_/extents.py
+62-9src/middlewared/middlewared/plugins/iscsi_/alua.py
+1,048-3228 files not shown
+1,232-37114 files

FreeNAS/freenas 064a267 — src/middlewared/middlewared/plugins smb.py, src/middlewared/middlewared/plugins/truenas entitlement_usage.py entitlements.py

Gate SMB block cloning and Veeam shares on SMB_BLOCK_CLONING

This commit adds changes to replace the SMB_FASTPATH and SMB_VEEAM license features with a single SMB_BLOCK_CLONING feature, which gates the ZFS block cloning and integrity streams smb.conf parameters as well as the VEEAM_REPOSITORY_SHARE purpose.
DeltaFile
+4-6src/middlewared/middlewared/pytest/unit/utils/test_entitlements.py
+3-6src/middlewared/middlewared/pytest/unit/utils/test_license_legacy_utils.py
+1-7src/middlewared/middlewared/utils/entitlements/engine.py
+4-4src/middlewared/middlewared/plugins/truenas/entitlements.py
+5-3src/middlewared/middlewared/plugins/smb.py
+2-4src/middlewared/middlewared/plugins/truenas/entitlement_usage.py
+19-308 files not shown
+30-4514 files

FreeNAS/freenas 34e73d9 — src/middlewared/middlewared/pytest/unit/utils test_disk_vpd_serial.py conftest.py, src/middlewared/middlewared/utils disks.py

NAS-136915 / 27.0.0-BETA.1 / Consolidate the disk identifier logic and fall back to udev when sysfs has no serial (#19856)

Middleware built a disk's identifier in two places, once over udev's
view of the disk for the disk table and the disk list, and once over
sysfs for everything that goes through the disk object (reporting,
SMART, temperatures, SED, the pool validator), so the two could disagree
about the same disk. Both now go through one implementation. Two private
methods nothing called any more are removed; there is no public API
change.

On the hardware we ship this changes no value. udev and sysfs report the
same serial and lunid for SAS, SATA and NVMe disks, and the disk object
still reads sysfs, so the disk-stats tick costs what it did.

One behavior is new. A disk that reports no serial in sysfs, which is a
usb-storage disk (those expose no VPD pages at all) or a SCSI device
that implements VPD page 0x83 but not page 0x80, now takes the serial
udev resolved for it instead of falling through to its partition table
or its device name. For such a disk:

    [11 lines not shown]
DeltaFile
+278-0src/middlewared/middlewared/pytest/unit/utils/test_disk_identifier.py
+81-0src/middlewared/middlewared/utils/disks_/udev.py
+52-23src/middlewared/middlewared/utils/disks_/disk_class.py
+61-0src/middlewared/middlewared/pytest/unit/utils/conftest.py
+0-47src/middlewared/middlewared/pytest/unit/utils/test_disk_vpd_serial.py
+25-20src/middlewared/middlewared/utils/disks.py
+497-904 files not shown
+564-15210 files

FreeNAS/freenas ece908f — src/middlewared/middlewared/plugins/failover_ event.py

Fix `You can only use create_task from main thread` in `vrrp_master`

(cherry picked from commit 9b7a2ab4a18c28d6955ec37901b2406ade48bc0c)
DeltaFile
+1-1src/middlewared/middlewared/plugins/failover_/event.py
+1-11 files

FreeNAS/freenas 8c90baa — src/middlewared/middlewared/plugins/failover_ event.py

NAS-144088 / 27.0.0-BETA.1 / Fix `You can only use create_task from main thread` in `vrrp_master` (#19890)

https://github.com/truenas/middleware/pull/19862 lacked
https://github.com/truenas/middleware/pull/19865
DeltaFile
+1-1src/middlewared/middlewared/plugins/failover_/event.py
+1-11 files

FreeNAS/freenas 9b7a2ab — src/middlewared/middlewared/plugins/failover_ event.py

Fix `You can only use create_task from main thread` in `vrrp_master`
DeltaFile
+1-1src/middlewared/middlewared/plugins/failover_/event.py
+1-11 files

FreeNAS/freenas 6036ce0 — src/middlewared/middlewared/api/v26_0_0 truenas.py, src/middlewared/middlewared/pytest/unit/plugins test_truenas_connect.py

NAS-144098 / 26.0.0-RC.1 / Send license issued_at in TNC heartbeat (by sonicaj) (#19888)

This PR adds changes to expose the license's issue date as `issued_at`
on `truenas.license.info` and send it to TNC in the heartbeat payload.

- v2 licenses: the `issued_at` string exactly as recorded in the
license, with no parsing or reformatting.
- Legacy licenses: the support contract start date as `YYYY-MM-DD`.
Legacy blobs carry no issue timestamp, so no time or timezone is
invented.
- System-generated (hardware-only) records, no license, or an invalid
license: `null`.

In the heartbeat, `issued_at` is gated exactly like `license_id` (only
for issued licenses), so TNC can tell a legacy value apart by the
`legacy_` prefix on `license_id`.


Original PR: https://github.com/truenas/middleware/pull/19886

Co-authored-by: Waqar Ahmed <waqarahmedjoyia at live.com>
DeltaFile
+6-0src/middlewared/middlewared/pytest/unit/utils/test_license_legacy_utils.py
+6-0src/middlewared/middlewared/api/v26_0_0/truenas.py
+3-0src/middlewared/middlewared/utils/license/types.py
+3-0src/middlewared/middlewared/pytest/unit/utils/test_license_info_wire.py
+3-0src/middlewared/middlewared/pytest/unit/plugins/test_truenas_connect.py
+1-0src/middlewared/middlewared/utils/license/legacy.py
+22-03 files not shown
+25-09 files

FreeNAS/freenas 5b11845 — src/middlewared/middlewared/api/v26_0_0 truenas.py, src/middlewared/middlewared/pytest/unit/plugins test_truenas_connect.py

NAS-144098 / 26.0.0 / Send license issued_at in TNC heartbeat (by sonicaj) (#19887)

This PR adds changes to expose the license's issue date as `issued_at`
on `truenas.license.info` and send it to TNC in the heartbeat payload.

- v2 licenses: the `issued_at` string exactly as recorded in the
license, with no parsing or reformatting.
- Legacy licenses: the support contract start date as `YYYY-MM-DD`.
Legacy blobs carry no issue timestamp, so no time or timezone is
invented.
- System-generated (hardware-only) records, no license, or an invalid
license: `null`.

In the heartbeat, `issued_at` is gated exactly like `license_id` (only
for issued licenses), so TNC can tell a legacy value apart by the
`legacy_` prefix on `license_id`.


Original PR: https://github.com/truenas/middleware/pull/19886

Co-authored-by: Waqar Ahmed <waqarahmedjoyia at live.com>
DeltaFile
+6-0src/middlewared/middlewared/pytest/unit/utils/test_license_legacy_utils.py
+6-0src/middlewared/middlewared/api/v26_0_0/truenas.py
+3-0src/middlewared/middlewared/utils/license/types.py
+3-0src/middlewared/middlewared/pytest/unit/utils/test_license_info_wire.py
+3-0src/middlewared/middlewared/pytest/unit/plugins/test_truenas_connect.py
+1-0src/middlewared/middlewared/utils/license/legacy.py
+22-03 files not shown
+25-09 files

FreeNAS/freenas 7e41ee5 — src/middlewared/middlewared/api/v26_0_0 truenas.py, src/middlewared/middlewared/pytest/unit/plugins test_truenas_connect.py

Send license issued_at in TNC heartbeat

This commit adds changes to expose the license's issue date as `issued_at` on `truenas.license.info` and send it to TNC in the heartbeat. v2 licenses pass the minted timestamp through verbatim, legacy licenses report their contract start date, and system-generated records report null.
DeltaFile
+6-0src/middlewared/middlewared/pytest/unit/utils/test_license_legacy_utils.py
+6-0src/middlewared/middlewared/api/v26_0_0/truenas.py
+3-0src/middlewared/middlewared/utils/license/types.py
+3-0src/middlewared/middlewared/pytest/unit/utils/test_license_info_wire.py
+3-0src/middlewared/middlewared/pytest/unit/plugins/test_truenas_connect.py
+1-0src/middlewared/middlewared/utils/license/legacy.py
+22-03 files not shown
+25-09 files

FreeNAS/freenas 0ff6c7a —

Empty commit to create PR on github.

You should reset it
DeltaFile
+0-00 files

FreeNAS/freenas 22b781a — src/middlewared/middlewared/api/v26_0_0 truenas.py, src/middlewared/middlewared/api/v27_0_0 truenas.py

NAS-144098 / 27.0.0-BETA.1 / Send license issued_at in TNC heartbeat (#19886)

This PR adds changes to expose the license's issue date as `issued_at`
on `truenas.license.info` and send it to TNC in the heartbeat payload.

- v2 licenses: the `issued_at` string exactly as recorded in the
license, with no parsing or reformatting.
- Legacy licenses: the support contract start date as `YYYY-MM-DD`.
Legacy blobs carry no issue timestamp, so no time or timezone is
invented.
- System-generated (hardware-only) records, no license, or an invalid
license: `null`.

In the heartbeat, `issued_at` is gated exactly like `license_id` (only
for issued licenses), so TNC can tell a legacy value apart by the
`legacy_` prefix on `license_id`.
DeltaFile
+6-0src/middlewared/middlewared/pytest/unit/utils/test_license_legacy_utils.py
+6-0src/middlewared/middlewared/api/v27_0_0/truenas.py
+6-0src/middlewared/middlewared/api/v26_0_0/truenas.py
+4-1src/middlewared/middlewared/plugins/truenas_connect/heartbeat.py
+3-0src/middlewared/middlewared/utils/license/types.py
+3-0src/middlewared/middlewared/pytest/unit/utils/test_license_info_wire.py
+28-14 files not shown
+34-110 files

FreeNAS/freenas cc37c3e — src/middlewared/middlewared/api/v26_0_0 truenas.py, src/middlewared/middlewared/api/v27_0_0 truenas.py

Send license issued_at in TNC heartbeat

This commit adds changes to expose the license's issue date as `issued_at` on `truenas.license.info` and send it to TNC in the heartbeat. v2 licenses pass the minted timestamp through verbatim, legacy licenses report their contract start date, and system-generated records report null.
DeltaFile
+6-0src/middlewared/middlewared/pytest/unit/utils/test_license_legacy_utils.py
+6-0src/middlewared/middlewared/api/v27_0_0/truenas.py
+6-0src/middlewared/middlewared/api/v26_0_0/truenas.py
+4-1src/middlewared/middlewared/plugins/truenas_connect/heartbeat.py
+3-0src/middlewared/middlewared/utils/license/types.py
+3-0src/middlewared/middlewared/pytest/unit/utils/test_license_info_wire.py
+28-14 files not shown
+34-110 files

FreeNAS/freenas 093a842 — src/middlewared/middlewared/plugins smb.py, src/middlewared/middlewared/plugins/truenas entitlement_usage.py entitlements.py

Gate SMB fast path on the Veeam entitlement

This commit adds changes to drop the separate SMB_FASTPATH license feature and gate the ZFS block cloning / integrity streams smb.conf parameters on SMB_VEEAM instead, since Veeam Fast Clone depends on them and the two were never meant to be licensed independently.
DeltaFile
+4-4src/middlewared/middlewared/plugins/truenas/entitlements.py
+0-3src/middlewared/middlewared/pytest/unit/utils/test_license_legacy_utils.py
+0-2src/middlewared/middlewared/pytest/unit/utils/test_entitlements.py
+0-2src/middlewared/middlewared/plugins/truenas/entitlement_usage.py
+1-1src/middlewared/middlewared/pytest/unit/test_entitlement_gate_vocabulary.py
+1-1src/middlewared/middlewared/plugins/smb.py
+6-135 files not shown
+6-1811 files

FreeNAS/freenas 01b7eb7 — src/middlewared/middlewared/plugins/container migrate.py, src/middlewared/middlewared/plugins/docker state_setup.py

Pass a ZFSResourceSetArgsData to zfs.resource.set_impl

## Problem
`zfs.resource.set_impl` took a path plus loose `properties`/`user_properties`/`inherit`/`bypass` arguments, unlike `create_impl` which takes a model. Internal callers handed raw dicts straight to libzfs, so a bad property name or value only surfaced as a libzfs error part way through the write.

## Solution
- **Typed input**: `set_impl` takes a `ZFSResourceSetArgsData`, the same model the public `zfs.resource.set` uses, so every caller's values are validated when the model is built, before anything is written. `touched_names` and `changed_fields` read the model too; the event, audit and quota/refquota `none` handling are unchanged.
- **Private fields**: `ZFSResourceSetArgsData` gains a `Private` `bypass` (honoured by both `set` and `set_impl`), and `ZFSResourceSetProperties` gains a `Private` `volthreading` for the iSCSI and NVMe-oF zvol handling. API callers still cannot supply either.
- **Callers**: every internal caller builds the model inline. `pool.dataset.update_impl` keeps its dict arguments since the HA peer calls it by name, and coerces them into the model. The tier special_small_blocks constants are ints now that they go through the typed model.
- **System dataset encryption**: when the pool root is passphrase-encrypted, `setup_datasets` added `encryption=off` to the comparison for existing system datasets too, so an encrypted child would have been sent an encryption change that ZFS refuses and setup would fail. Encryption is left out of the update comparison; creation still sets it.
DeltaFile
+17-37src/middlewared/middlewared/plugins/zfs/resource_set.py
+35-14src/middlewared/middlewared/plugins/container/migrate.py
+22-8src/middlewared/middlewared/plugins/iscsi_/extents.py
+21-3src/middlewared/middlewared/plugins/docker/state_setup.py
+18-4src/middlewared/middlewared/plugins/nvmet/namespace.py
+17-4src/middlewared/middlewared/plugins/pool_/import_pool.py
+130-7010 files not shown
+211-10916 files

FreeNAS/freenas 27450ec — src/middlewared/middlewared/api/v27_0_0 pool_dataset.py, src/middlewared/middlewared/plugins/zfs resource_create.py resource.py

Fix the checksum choices result, the extent readonly event test and the create mount-path check

## Problem
- **checksum choices**: `pool.dataset.checksum_choices` now returns the checksums `zfs.resource` accepts, which include OFF, but its result model still had the fixed fields master's list had without OFF and forbids extras. Every call failed result validation: integration tests raise, production logs a serialization warning, and older API clients fail outright because the adapter validates against the current model first.
- **extent readonly test**: `test_readonly_on_an_extent_zvol_syncs_the_extent` expected two CHANGED events for one readonly change. The second came from the iSCSI resync writing readonly back onto the zvol, which the resync no longer does, so the test failed.
- **create mount-path check**: create refused a filesystem when `/mnt/<path>` already existed, while the share ACL is applied at the path the filesystem really mounts at. Under an ancestor with a non-default mountpoint the two differ, so an occupied real mount path went unnoticed until the mount failed after the resource was created, and a stray `/mnt/<path>` refused a create that would never mount there.

## Solution
- **checksum choices**: added OFF to the v27 result model. Create and update have always accepted `checksum=OFF`, so the list now matches what they take. Older API versions keep their models, and the adapter drops OFF for those clients as before.
- **extent readonly test**: it now expects the single CHANGED event from the caller's own set.
- **create mount-path check**: it tests the nearest existing ancestor's mountpoint joined with the rest of the path, the same path the ACL step uses. With default mountpoints that is still `/mnt/<path>`.
DeltaFile
+1-1tests/api2/test_zfs_resource_delegates.py
+1-1src/middlewared/middlewared/plugins/zfs/resource_create.py
+1-1src/middlewared/middlewared/plugins/zfs/resource.py
+1-0src/middlewared/middlewared/api/v27_0_0/pool_dataset.py
+4-34 files

FreeNAS/freenas b86a7c1 — src/middlewared/middlewared/api/v27_0_0 zfs_resource_crud.py, src/middlewared/middlewared/plugins/zfs resource_create.py rules_common.py

Measure volume reservation headroom the way master did

## Problem
The reservation headroom checks drifted from master in ways that refused requests ZFS and master accept:

- **set**: headroom was measured as `requested - current refreservation` on every refreservation change. The kernel only charges the part of a reservation above the data the volume already holds, so converting a sparse volume that has data to thick was refused even with `force_size`. For example, an 80G sparse volume with 60G written and 50G free needs 20G for `refreservation=80G`, but was refused as needing 80G.
- **create**: a new volume was measured against the nearest ancestor's `available - usedbyrefreservation`. When that ancestor has a refquota, `available` is already clamped to it, so the refreservation was counted twice. Under a nearly empty parent with refquota=10G and refreservation=10G on a 5T pool, every thick volume create was refused, where master allowed up to 8G.

## Solution
- **set**: the volume headroom check runs only when `volsize` changes, as `pool.dataset.update` did on master. A refreservation-only change is left to ZFS, which refuses what it cannot back.
- **create**: the check measures against the nearest existing ancestor's `available`, as both `pool.dataset.create` and `zfs.resource.create` did on master.
DeltaFile
+19-29tests/api2/test_zfs_resource_create.py
+4-4src/middlewared/middlewared/api/v27_0_0/zfs_resource_crud.py
+3-4src/middlewared/middlewared/plugins/zfs/create_rules.py
+1-3src/middlewared/middlewared/plugins/zfs/rules_common.py
+2-2src/middlewared/middlewared/plugins/zfs/resource.py
+1-1src/middlewared/middlewared/plugins/zfs/resource_create.py
+30-432 files not shown
+33-448 files

FreeNAS/freenas fa1da41 — src/middlewared/middlewared/utils disks.py, src/middlewared/middlewared/utils/disks_ disk_class.py

Read the sysfs serial inside DiskEntry.serial again and keep the sync path's lunid fallback to sysfs
DeltaFile
+15-18src/middlewared/middlewared/utils/disks_/disk_class.py
+3-2src/middlewared/middlewared/utils/disks.py
+18-202 files

FreeNAS/freenas 6648a75 — src/middlewared/middlewared/api/v26_0_0 s3.py, src/middlewared/middlewared/plugins/truenas_s3 config.py on_disk.py

NAS-144061 / 26.0.0 / Add bucket recovery APIs (by anodos325) (#19884)

There are various situations in which we can have orphaned buckets.
Examples include:

* bucket is deleted and admin wants to reinstate.
* the NAS is disaster recovery instance and needs to activate buckets
after switching datasets to read-write.

This is facilited by inserting a .truenas_s3/config_backup.json file
inside each bucket (daemon-owned path) and restoring the DB row / S3
config with some user-provided overrides if required.

Two new API endpoints are added:

* sharing.s3.recoverable_buckets lists mounted datasets containing
orphaned buckets.

* sharing.s3.recover basically takes a list of datasets and rebuilds

    [4 lines not shown]
DeltaFile
+423-16src/middlewared/middlewared/plugins/truenas_s3/bucket_crud.py
+295-0tests/api2/test_s3_bucket.py
+120-0src/middlewared/middlewared/pytest/unit/plugins/test_truenas_s3_on_disk.py
+103-0src/middlewared/middlewared/plugins/truenas_s3/on_disk.py
+63-1src/middlewared/middlewared/api/v26_0_0/s3.py
+9-1src/middlewared/middlewared/plugins/truenas_s3/config.py
+1,013-186 files

FreeNAS/freenas 79b509e — src/middlewared/middlewared/api/v26_0_0 s3.py, src/middlewared/middlewared/plugins/truenas_s3 config.py on_disk.py

NAS-144061 / 27.0.0-BETA.1 / Add bucket recovery APIs (#19873)

There are various situations in which we can have orphaned buckets.
Examples include:

* bucket is deleted and admin wants to reinstate.
* the NAS is disaster recovery instance and needs to activate buckets
after switching datasets to read-write.

This is facilited by inserting a .truenas_s3/config_backup.json file
inside each bucket (daemon-owned path) and restoring the DB row / S3
config with some user-provided overrides if required.

Two new API endpoints are added:

* sharing.s3.recoverable_buckets lists mounted datasets containing
orphaned buckets.

* sharing.s3.recover basically takes a list of datasets and rebuilds

    [3 lines not shown]
DeltaFile
+423-16src/middlewared/middlewared/plugins/truenas_s3/bucket_crud.py
+295-0tests/api2/test_s3_bucket.py
+120-0src/middlewared/middlewared/pytest/unit/plugins/test_truenas_s3_on_disk.py
+103-0src/middlewared/middlewared/plugins/truenas_s3/on_disk.py
+63-1src/middlewared/middlewared/api/v26_0_0/s3.py
+9-1src/middlewared/middlewared/plugins/truenas_s3/config.py
+1,013-186 files

FreeNAS/freenas 7eca670 —

Empty commit to create PR on github.

You should reset it
DeltaFile
+0-00 files

FreeNAS/freenas 33cb50f — src/middlewared/middlewared/api/v26_0_0 s3.py, src/middlewared/middlewared/api/v27_0_0 s3.py

NAS-144061 / 27.0.0-BETA.1 / Add bucket recovery APIs (#19873)

There are various situations in which we can have orphaned buckets.
Examples include:

* bucket is deleted and admin wants to reinstate.
* the NAS is disaster recovery instance and needs to activate buckets
after switching datasets to read-write.

This is facilited by inserting a .truenas_s3/config_backup.json file
inside each bucket (daemon-owned path) and restoring the DB row / S3
config with some user-provided overrides if required.

Two new API endpoints are added:

* sharing.s3.recoverable_buckets lists mounted datasets containing
orphaned buckets.

* sharing.s3.recover basically takes a list of datasets and rebuilds
bucket configuration from backups for them.
DeltaFile
+433-17src/middlewared/middlewared/plugins/truenas_s3/bucket_crud.py
+295-0tests/api2/test_s3_bucket.py
+120-0src/middlewared/middlewared/pytest/unit/plugins/test_truenas_s3_on_disk.py
+103-0src/middlewared/middlewared/plugins/truenas_s3/on_disk.py
+63-1src/middlewared/middlewared/api/v27_0_0/s3.py
+63-1src/middlewared/middlewared/api/v26_0_0/s3.py
+1,077-191 files not shown
+1,086-207 files

FreeNAS/freenas cf11e5a — tests/api2 test_kmip.py test_zfs_resource_create.py

Remove tests
DeltaFile
+0-2,687tests/api2/test_300_nfs.py
+0-1,427tests/api2/test_200_ftp.py
+0-1,128tests/api2/test_account.py
+0-1,025tests/api2/test_rsync_ssh_authentication.py
+0-807tests/api2/test_zfs_resource_create.py
+0-752tests/api2/test_kmip.py
+0-7,826299 files not shown
+0-47,181305 files

FreeNAS/freenas b013ba3 — src/middlewared/middlewared/plugins/truenas_s3 config.py bucket_crud.py, tests/api2 test_s3_bucket.py

Read ZFS properties raw in the S3 bucket backup and recovery

`mounted` parses to a bool and a literal `none` to None, so no backup was
ever written and every recovery was refused. The backup test also leaked
its row into the rest of the module.
DeltaFile
+14-10src/middlewared/middlewared/plugins/truenas_s3/bucket_crud.py
+2-2src/middlewared/middlewared/plugins/truenas_s3/config.py
+4-0tests/api2/test_s3_bucket.py
+20-123 files

FreeNAS/freenas 8629c35 — src/middlewared/middlewared/plugins/system_general update.py

NAS-144083 / 26.0.0 / remove unconditional call-remote in system update (by anodos325) (#19883)

system.general.update called failover.call_remote unconditionally when
ds_auth or ui_certificate changed, stalling for the connect timeout and
logging a spurious standby warning on non-HA systems.

Original PR: https://github.com/truenas/middleware/pull/19882

Co-authored-by: Andrew Walker <andrew.walker at truenas.com>
DeltaFile
+5-4src/middlewared/middlewared/plugins/system_general/update.py
+5-41 files

FreeNAS/freenas d1bb5f4 — src/middlewared/middlewared/plugins/system_general update.py

Gate standby pam regeneration on failover.licensed

system.general.update called failover.call_remote unconditionally when ds_auth or ui_certificate changed, stalling for the connect timeout and logging a spurious standby warning on non-HA systems.

(cherry picked from commit d31e09427cd917b0b0df4fa8b494d661cb1e2764)
DeltaFile
+5-4src/middlewared/middlewared/plugins/system_general/update.py
+5-41 files

FreeNAS/freenas e8018b8 — src/middlewared/middlewared/plugins/system_general update.py

NAS-144083 / 27.0.0-BETA.1 / remove unconditional call-remote in system update (#19882)

system.general.update called failover.call_remote unconditionally when
ds_auth or ui_certificate changed, stalling for the connect timeout and
logging a spurious standby warning on non-HA systems.
DeltaFile
+5-4src/middlewared/middlewared/plugins/system_general/update.py
+5-41 files

FreeNAS/freenas d31e094 — src/middlewared/middlewared/plugins/system_general update.py

Gate standby pam regeneration on failover.licensed

system.general.update called failover.call_remote unconditionally when ds_auth or ui_certificate changed, stalling for the connect timeout and logging a spurious standby warning on non-HA systems.
DeltaFile
+5-4src/middlewared/middlewared/plugins/system_general/update.py
+5-41 files

FreeNAS/freenas de4c4b7 — src/middlewared/middlewared/plugins/zfs resource.py resource_create.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_create_post_write.py

Keep a created resource whose key cannot be recorded

## Problem
`zfs.resource.create` destroyed the resource it had just created when its encryption key could not be written to the database. That only happens when the middleware database itself is failing, where the next operations fail too, and master never rolled back here. The rollback's destroy also queued a late ZFS event whose handler deletes key rows by name, so a quick retry under the same name could have its freshly written key row removed and lose the dataset's key at the next reboot or failover.

## Solution
Let the key-record failure propagate and keep the resource, as master did. The key is still recorded when the mount fails, so a mount failure no longer loses a generated key, and the docstring and tests are updated to match.
DeltaFile
+6-26src/middlewared/middlewared/pytest/unit/plugins/zfs/test_create_post_write.py
+1-16src/middlewared/middlewared/plugins/zfs/resource_create.py
+1-10tests/api2/test_zfs_resource_create.py
+3-3src/middlewared/middlewared/plugins/zfs/resource.py
+11-554 files