Commit Graph
314 Commits
Author SHA1 Message Date
Kevin AdamsandClaude Sonnet 5 db13023b83 docs: confirm multipath works over WebSocket transport, live-tested
Full alloc_image/activate_volume/path/deactivate_volume/free_image
cycle against .92 with zero code changes to TrueNASMultipath.pm --
real dm-multipath device came up with 2 active paths. Also notes a
practical finding: .92 has only one TrueNAS portal object (0.0.0.0)
rather than two per-IP ones, and iscsiadm still produced two genuine
independent paths logging into different IPs against it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 09:46:21 -04:00
Kevin AdamsandClaude Sonnet 5 e5f9de040c docs: record REST-path regression check in ADR-012
Ran the full read/write/snapshot suite against .90 (TrueNAS CORE,
real production box) to confirm _transport()'s dispatcher wrapper
doesn't regress the REST path for hosts that never touch WebSocket.
Zero regressions, confirmed back to original state afterward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 09:42:53 -04:00
Kevin AdamsandClaude Sonnet 5 3e550547db docs: mark ADR-012 Accepted
Every read and write API call the WebSocket transport makes is
live-verified against real TrueNAS SCALE hosts. Kevin's sign-off.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 09:35:25 -04:00
Kevin AdamsandClaude Sonnet 5 27b06d8e62 docs: close out ADR-012's write-path verification (zfs.snapshot.* tested)
Every API call the WebSocket transport makes is now live-verified
against a real TrueNAS SCALE host with zero param-shape issues
remaining. Left as Draft pending Kevin's own sign-off, per his
explicit instruction earlier.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 08:57:22 -04:00
Kevin AdamsandClaude Sonnet 5 c9a8376e2e docs: record write-path live-test results in ADR-012
alloc_image/path/volume_size_info/free_image confirmed working
end-to-end against .92 after fixing the delete param-shape bugs.
pool.dataset.create/delete both confirmed along the way. Only
zfs.snapshot.* remains entirely untested against the WS transport.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 08:46:48 -04:00
Kevin AdamsandClaude Sonnet 5 f9eee71e1e docs: record first WebSocket transport implementation in ADR-012
_api_ws/_ws_connect/_ws_call/_transport landed on next, live-verified
against .92 (25.04.2.6) through the real plugin module. Also notes
the /system/product_type bug caught during integration (returns
license tier, not product family -- fixed by parsing /system/version
magnitude instead).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 19:48:14 -04:00
Kevin AdamsandClaude Sonnet 5 15347c06cd docs: close ADR-012's last live-verification gap (NAS-135643 on 25.04.2.6)
Kevin rebuilt .92 from scratch specifically to TrueNAS-25.04.2.6 -- the
exact SCALE minor version NAS-135643 was originally filed against, two
patch levels later. iscsi.target.query returned a real target cleanly,
no error. This was the one item ADR-012 flagged as an acknowledged gap
rather than a completed check; no remaining live-verification gaps for
this ADR now. Also documents a minor auth-flow gotcha found along the
way: retrying auth.login_ex on the same connection after a failed
attempt threw an unhandled RuntimeError on this fresh install,
reinforcing the login_with_api_key recommendation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 15:06:36 -04:00
Kevin AdamsandClaude Sonnet 5 8a4750378c feat: adopt role-based branching strategy (ADR-013)
release/3.x -> main, release/4.x -> next, master -> archive/v2-legacy
(retired, was byte-identical to release/2.x). Branch identity is now
role-based, not version-numbered -- main and next are fixed names
that never get renamed at a major-version cutover; release/N.x is
reserved exclusively for already-superseded majors, created only at
the moment they're archived.

This directly fixes the structural cause of the bug found 2026-08-30:
build.yml hardcoded literal branch-name comparisons for the
testing/beta channel, and ADR-006's original "master -> beta channel"
rule was never superseded when release/3.x took over as the active
branch, leaving master as a silent, stale duplicate of release/2.x
that CI still treated as a legitimate publish source. Rewrote the
version-resolution logic to match roles instead: refs/heads/main,
refs/heads/next, and a refs/heads/release/*.x pattern that auto-
catches any future archived major with zero code changes needed.
Also tightened the push/PR triggers from a bare wildcard to an
explicit allowlist, and switched the release-notes CHANGELOG link to
a tag-relative permalink instead of a floating branch reference.

Research (DEP-14, openedx/frontend-base #273, semantic-release's
branch-pattern config) is cited in ADR-013; the openedx precedent in
particular fixed this identical bug the same way.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 09:43:33 -04:00
Kevin AdamsandClaude Sonnet 5 687bdd8f7f docs: fold .91 verification results into ADR-012
.91 was upgraded straight to TrueNAS-25.10.6 (skipping the planned
Fangtooth stop) and re-tested clean: all 8 method-mapping families
work against real production-scale iSCSI config (2 targets, 9
extents), and NAS-135643 still doesn't reproduce. Also corrects the
auth.login_ex conclusion from the .92-only pass -- it works fine given
the right username (.91's key IS root, .92's isn't), so the
login_with_api_key recommendation stands for a different reason: no
username field exists in storage.cfg to use it correctly, not because
login_ex is broken. Notes the resulting gap (no 25.04.x node left in
the lab) and the revised lab-node role split.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 09:10:14 -04:00
Kevin AdamsandClaude Sonnet 5 02497fb09c docs: track #289 (per-storage version display idea) in ROADMAP
Not committed to any release yet -- filed as a backlog idea alongside
today's #243/ADR-012 work, since a dual REST/WebSocket transport
reality in v4.0.0 makes visible version mismatches more useful to
surface.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 09:05:12 -04:00
Kevin AdamsandClaude Sonnet 5 943beecfac docs: fold multipath-inheritance and release/4.x setup into ADR-012
Two things surfaced since this ADR was last updated: confirmed
TrueNASMultipath.pm needs no separate WebSocket work (it calls the
shared _api() helper directly), and release/4.x now exists as the
implementation branch, including the dormant CI bug it exposed and
the fix for it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 08:52:47 -04:00
Kevin AdamsandClaude Sonnet 5 24ec18e28a docs: document multipath and fix stale v3.0-beta-era content
Multipath (truenas-proxmox-multipath, shipped v3.2.0/#256) had zero
coverage in README.md and was actively described as unsupported/future
work in docs/architecture.md and docs/migration-advanced.md. Added:
- README: Prerequisites, Installation, and Configuration sections for
  the multipath package and its truenas-multipath storage type
- architecture.md: new §9 covering what TrueNASMultipath.pm overrides
  vs. inherits, and the live failover behavior confirmed 2026-08-29
- migration-advanced.md: points to the multipath package instead of
  calling it unsupported
- truenas-storage-help.html: single-path note pointing to the
  multipath alternative

Also fixed README content that was stale from the v3.0 beta era: the
PVE 9 blockdev issue (#266) was fixed in v3.1.0 but still read as
open, "v3.0 (beta)" headings never updated to v3.x, a broken internal
anchor link, and a note claiming WebSocket support was "v3.0.0" scope
when ADR-009 placed it at v4.0.0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 08:47:11 -04:00
Kevin AdamsandClaude Sonnet 5 a55caaf8c6 fix: stop development-channel builds from overwriting the testing apt dist
The "Publish to GitHub Pages testing dist" step ran for both 'testing'
and 'development' channel builds and does rm -rf pool/testing before
copying in the new .deb — so any push to a release/* branch other than
release/3.x silently overwrote the real testing dist with its own alpha
build. Confirmed happening 2026-08-30 when release/4.x was created and
its 3.2.5~alpha+d0ea761 build replaced release/3.x's legitimate beta
build there. Restricted the step to channel == 'testing' only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 08:10:36 -04:00
Kevin AdamsandClaude Sonnet 5 10286da622 docs: fold live WebSocket verification results into ADR-012 (#243)
Ran a diagnostic against the .92 TrueNAS SCALE lab node (25.10.3.1) to
check ADR-012's open assumptions. Confirms auth.login_with_api_key over
auth.login_ex (the latter needs a username field this plugin doesn't
collect), verifies all 8 REST->JSON-RPC method mappings live, and finds
NAS-135643 no longer reproduces on this version. Also documents a real
Perl gotcha: JSON's decode_json returns a blessed JSON::PP::Boolean for
true/false, not a plain 1/0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 18:41:43 -04:00
Kevin AdamsandClaude Sonnet 5 b5fd0a2c88 docs: add ADR-012 draft for v4.0.0 WebSocket JSON-RPC transport (#243)
Scopes the transport-abstraction design called for in #243: confirms the
JSON-RPC 2.0 method mapping for all 8 REST endpoint families the plugin
uses, decides on AnyEvent::WebSocket::Client (apt-packaged, no CPAN-only
deps) after finding an independent prior implementation, and defers the
#249 per-variant file split to a future v4.1/v5.0. Still Draft pending
live verification against the lab's Fangtooth/Goldeneye TrueNAS nodes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 17:29:08 -04:00
Kevin AdamsandClaude Sonnet 5 e14c70bcea docs: fix stale Known Issues list in CLAUDE.md
Four of the six tracked issues (#228, #234, #256, #260) had shipped
since this list was last touched, and #250 was closed too — the
instructions Claude reads at session start were actively wrong.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 22:37:23 -04:00
Kevin AdamsandClaude Sonnet 5 ba9895ada5 chore: bump version to 3.2.5
Fixed:
- #287 HA daemon restart in truenas-proxmox-multipath postinst/postrm

Docs:
- #286 v3 storage panel + SCALE 25.04 UI docs
- #285 deb822 repo instructions for PVE 9 / trixie

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v3.2.5
2026-08-23 22:27:30 -04:00
Kevin AdamsandClaude Sonnet 5 14eeba1beb docs: add deb822-format repo instructions for PVE 9 / Debian trixie
Debian trixie recommends deb822-style .sources files over the one-liner
.list format, and PVE 9 ships on trixie. Show deb822 as the primary form
in README (stable, v2 track, Cloudsmith migration, testing) and
getting-started.md/upgrade-paths.md, keeping the one-liner .list format
as a fallback for PVE 8 / bookworm users.

Fixes #285

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 14:32:36 -04:00
Kevin AdamsandClaude Sonnet 5 92c8beafe3 fix: restart HA daemons in truenas-proxmox-multipath postinst/postrm
Same root cause as #179: postinst/postrm only restarted pvedaemon/pveproxy,
never pvestatd/pve-ha-lrm/pve-ha-crm, so HA-managed VMs on truenas-multipath
storage could fail to start after install/upgrade. Mirrors the #179 fix —
bare statements so set -e aborts on a real failure, HA daemons restarted
via systemctl (they don't support a restart subcommand). Extended
test-restart-services.sh to cover both multipath scripts with the same
stub approach.

Fixes #287

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 14:28:32 -04:00
Kevin AdamsandClaude Sonnet 5 0070bb78e8 docs: backfill CHANGELOG for v3.1.0 through v3.2.4
CHANGELOG.md stopped at 3.0.0 despite five releases since. Backfilled
from git/tag history so the changelog is a reliable release record again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 10:32:14 -04:00
Kevin AdamsandClaude Sonnet 5 58be143489 docs: update install/config docs for v3 storage type and SCALE 25.04 UI
README and getting-started.md still described the legacy v2.x "ZFS over
iSCSI" storage type and pre-25.04 TrueNAS SCALE UI locations. Update both
to match the actual v3 "TrueNAS (ZFS/iSCSI)" panel fields, document the
SCALE 25.04+ API key location and the throwaway-share workaround for the
now-missing standalone portal/initiator-group screen, and sync the help
HTML per the same-commit doc-sync rule.

Fixes #286

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 10:11:28 -04:00
Kevin AdamsandClaude Sonnet 5 eadf6921bd fix: set executable bit on test stub scripts
core.fileMode=false on this checkout (NTFS-mounted /mnt/c) meant the
previous commit recorded tests/stubs/* and tests/fail-stubs/* as 100644
despite being executable locally, so CI failed with "Permission denied"
trying to exec them via PATH lookup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v3.2.4
2026-08-01 18:39:02 -04:00
Kevin AdamsandClaude Sonnet 5 d60adfaaf7 fix: restart HA daemons on install/remove; add regression test (#179)
pvedaemon/pveproxy picked up the patched PVE::Storage state, but
pve-ha-lrm/pve-ha-crm kept running against the pre-install state, so
HA-managed VMs on TrueNAS storage failed to start. They don't support
a `restart` subcommand (only start/stop/status), so they're restarted
via systemctl instead. Also switched every restart from `cmd && log
...` to bare statements — set -e does not fire on the left side of
&&, so a genuine restart failure was previously swallowed silently
instead of aborting the script.

Adds tests/test-restart-services.sh: sources the real postinst/postrm
against stub PVE binaries in CI to catch both classes of regression
(wrong subcommand, silently-swallowed failure) without needing a live
PVE cluster. Real HA-cluster validation is documented as a manual
runbook (RUNBOOK-001) since GitHub Actions can't run pve-ha-lrm/crm.

Bumps $VERSION to 3.2.4.

Fixes #179

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 17:57:46 -04:00
Kevin AdamsandClaude Sonnet 5 55c2663163 fix: restart pvestatd and HA daemons on install/remove
pvedaemon/pveproxy picked up the patched PVE::Storage state, but
pve-ha-lrm/pve-ha-crm kept running against the pre-install state,
so HA-managed VMs on TrueNAS storage failed to start. pve-ha-lrm
and pve-ha-crm don't support a `restart` subcommand (only
start/stop/status), so they're restarted via systemctl instead.

Confirmed root cause by mir07/deamonkai on #179; verified the full
restart_pve_services() sequence end-to-end on pve01-hq before commit.

Fixes #179

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 17:30:09 -04:00
Kevin AdamsandClaude Sonnet 4.6 ec6d531174 chore: bump version to 3.2.3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v3.2.3
2026-06-27 10:51:05 -04:00
Kevin AdamsandClaude Sonnet 4.6 ec3e42e2e5 docs: add SCALE 25.04 portal PUT port field callout (#280)
SCALE 25.04 tightened the iSCSI portal PUT schema — sending port in the
listen array now returns "Extra inputs are not permitted". Added §6.9 in
getting-started.md with the correct curl example, and a matching row in
the help panel troubleshooting table.

Closes #280

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 22:18:45 -04:00
Kevin AdamsandClaude Sonnet 4.6 aef7439157 chore: update bug report template with pveversion -v and journald log command
Replace bare pveversion with pveversion -v (includes full package list
for better triage). Replace grep on /var/log/syslog with journalctl
(syslog doesn't exist on Debian 12+/PVE 9).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 23:49:02 -04:00
Kevin AdamsandClaude Sonnet 4.6 d29dd10fbd docs: document one-time apt codename prompt for v3.2.2+ upgrades
Users who had the v3 repo configured before v3.2.2 see an apt security
prompt when the Codename field changed from unset to 'error'. Document
the --allow-releaseinfo-change one-liner in README, getting-started.md
(new section 6.8), and upgrade-paths.md (codename column + callout).
Closes #284.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 22:28:43 -04:00
Kevin AdamsandClaude Sonnet 4.6 3e725244d0 fix: bump api() to 15 to match PVE 9 APIVER, silencing storage API warning
PVE 9.2.3 sets APIVER=15 in PVE::Storage. Our plugin was returning 14,
triggering "implementing an older storage API" on every pvedaemon/pveproxy
restart. No functional change — plugin loaded and worked correctly at 14.

Closes #282

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v3.2.2
2026-06-23 14:00:46 -04:00
Kevin AdamsandClaude Sonnet 4.6 64b430f182 fix: create dists/error codename alias and fix cp -r overwrite bug
dists/error was never written to gh-pages because the codename alias
code was added after the v3.2.0 tag. The stable publish job only runs
on v*.*.* tags, so all subsequent pushes to release/3.x only touched
dists/testing. Bumping to v3.2.1 triggers stable publish to create it.

Also fix: cp -r src dst when dst already exists puts src inside dst
rather than replacing it. Add rm -rf before cp -r to guarantee a clean
replace on every stable release.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v3.2.1
2026-06-22 08:25:46 -04:00
Kevin AdamsandClaude Sonnet 4.6 c698801338 fix: generate codename alias dirs so error/limelight/rivendell work in sources.list
Codename was added to Release metadata but dists/<codename>/ directories were
never created on GitHub Pages, so apt would 404 on InRelease when using the
codename as the dist name. Copy each dist dir under its codename alias after
the main loop so both Suite and Codename values work interchangeably.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:26:40 -04:00
Kevin AdamsandClaude Sonnet 4.6 a604ec0c09 feat: add apt dist codenames (limelight, error, rivendell)
v2/main → limelight (Rush), v3 → error (The Warning),
v4 → rivendell (Lord of the Rings), testing stays as testing.
Suite field unchanged — codename is an alias, both work in sources.list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 14:55:28 -04:00
Kevin AdamsandClaude Sonnet 4.6 6c313dfa9a feat: bump version to 3.2.0 for multipath stable release
Multipath tested and confirmed working on TrueNAS CORE 13.x (FreeBSD/ALUA)
and SCALE 24.10 + 25.04 (Linux LIO). Failover and path recovery validated
on both platforms. Closes #256.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v3.2.0
2026-06-20 14:00:05 -04:00
Kevin AdamsandClaude Sonnet 4.6 b7acb605ee fix: strip pre-existing unmanaged devices block before injecting managed stanza
If /etc/multipath.conf already had a manual devices{} block before package
install, postinst would append a second identical block, causing multipathd
to emit "duplicate keyword: devices" warnings. Strip any unmanaged devices
block in the append path to keep the file clean.

Fixes #279. Discovered 2026-06-20 on pve01-hq during SCALE 25.04 multipath testing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 12:07:40 -04:00
Kevin AdamsandClaude Sonnet 4.6 1c723a8fb8 fix: clear pool/multipath/testing before publish to prevent stale version accumulation
Old multipath testing debs were never pruned, causing apt to see multiple
3.1.0~beta+<sha> versions and pick whichever sha sorts highest — not newest.
Mirror the existing pool/testing cleanup that already did this correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 22:31:20 -04:00
Kevin AdamsandClaude Sonnet 4.6 da823569a7 feat: add UI panel for truenas-multipath storage type (#278)
Without a registered JS panel the truenas-multipath type was invisible in
the PVE Datacenter → Storage → Add dropdown. Adds truenas-multipath.js
with all base TrueNAS fields plus the required truenas_portals field, and
wires it into the multipath package install/remove scripts and CI build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 22:23:01 -04:00
Kevin AdamsandClaude Sonnet 4.6 d0093f48b3 fix: safe multipath.conf management via BEGIN/END tagged block
On install: if /etc/multipath.conf already exists, append a tagged
block rather than skipping silently (old) or overwriting (dangerous).
On upgrade: replace only the tagged block, leaving the rest untouched.
On remove/purge: strip the tagged block; rest of the file preserved.

This means admins who added their own stanzas during manual testing
(e.g. before the package existed) won't lose config on install or
upgrade. Closes the silent "file already exists" footgun.

Also fixes pre-existing SC2015 shellcheck warnings in postrm.

Refs #256

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 21:54:12 -04:00
Kevin AdamsandClaude Sonnet 4.6 f0150c225e fix: delegate qemu_blockdev_options to Plugin.pm for host_device path
TrueNAS.pm::qemu_blockdev_options returns an iscsi:// blockdev — wrong for
multipath where path() returns /dev/mapper/<wwid>. Simply removing the override
caused the parent's iscsi driver to be inherited instead.

Fix: explicitly call PVE::Storage::Plugin::qemu_blockdev_options (the
grandparent). It calls path(), sees /dev/mapper/<wwid> starts with '/',
stats it as S_ISBLK, and returns { driver => 'host_device', filename => ... }.
QEMU receives: "driver":"host_device","filename":"/dev/mapper/<wwid>"

Tested: VM 103 started with multipath disk (vm-103-disk-0 on TrueNAS-Scale01-MP).
QEMU confirmed using host_device driver on /dev/mapper/36589cfc000000ad...

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 12:48:39 -04:00
Kevin AdamsandClaude Sonnet 4.6 3bd9f551c7 fix: multipath activate_volume and naa field in _find_extent
TrueNAS.pm: expose naa field from _find_extent return hash — needed by
TrueNASMultipath.pm to build the /dev/mapper/<wwid> path.

TrueNASMultipath.pm: use multipathd reconfigure + fallback multipath -v0
instead of bare multipath(8) which conflicts with a running multipathd
daemon. Tested end-to-end on pve01-hq against TrueNAS SCALE:
  - Two sessions (172.31.69.91 + 192.168.69.91) both established
  - /dev/mapper/36589cfc000000eb2adcd24154021d376 appears as block device
  - deactivate_volume cleanly flushes and logs out

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 12:31:39 -04:00
Kevin AdamsandClaude Sonnet 4.6 db730e39f5 fix: only declare new properties in TrueNASMultipath::properties()
PVE::SectionConfig registers properties globally across all plugin types.
Re-declaring the inherited TrueNAS.pm properties (truenas_host, truenas_pool,
etc.) caused a "duplicate property" error at pvedaemon startup when both
plugins are loaded. TrueNASMultipath::properties() now returns only the
new truenas_portals property; all inherited properties remain registered
by TrueNAS.pm.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 12:09:48 -04:00
Kevin Adams 15d84637c9 fix: bare return in qemu_blockdev_options (perlcritic) 2026-06-08 11:54:40 -04:00
Kevin AdamsandClaude Sonnet 4.6 a534341d13 fix: add -Iperl5 so TrueNASMultipath.pm can find its parent in CI lint
TrueNASMultipath.pm inherits from TrueNAS.pm which lives in perl5/. The
-I/tmp/pve-stub flag alone doesn't make that path searchable, so the
'use base' failed at compile time. Adding -Iperl5 fixes it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 11:48:12 -04:00
Kevin AdamsandClaude Sonnet 4.6 0d195a9074 feat: truenas-proxmox-multipath plugin and packaging (#256)
Adds TrueNASMultipath.pm — a separate PVE storage type 'truenas-multipath'
that inherits all REST API and iSCSI resource management from TrueNAS.pm but
uses iscsiadm + dm-multipath for block device access:

  path()             → /dev/mapper/<wwid>  (NAA from TrueNAS extent)
  activate_volume()  → iscsiadm login on each portal in truenas_portals;
                       waits for /dev/mapper device to appear
  deactivate_volume()→ multipath flush + iscsiadm logout
  qemu_blockdev_options → returns undef (path() used instead)

Packaging:
  packaging/DEBIAN-multipath/ — control.j2, postinst, postrm,
  changelog.Debian, multipath.conf.example
  Distributed via the 'multipath' apt component (ADR-011)
  Depends: truenas-proxmox >= 3.1.0, open-iscsi, multipath-tools

CI (build.yml):
  - Third staging dir (dist-multipath) and .deb output
  - multipath component pool under pool/multipath/v<major>
  - Both stable and testing publish steps updated to generate
    main + multipath components; Release lists both
  - Lint checks TrueNASMultipath.pm and multipath packaging scripts

PoC confirmed 2026-06-07 on pve01-hq against TrueNAS SCALE 24.10:
  - Two sessions (172.31.69.91 + 192.168.69.91), both active
  - dm-multipath aggregated 3 disks × 2 paths each
  - /dev/mapper/mpath* devices appeared correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 08:52:47 -04:00
Kevin AdamsandClaude Sonnet 4.6 0ce11dc6ba docs: update ROADMAP.md with v3.1.0 completed items and snapshot results
Snapshot interface (#234) confirmed working 2026-06-07:
- Disk-only: freeze/snap/thaw, rollback verified (ngrep/nmap gone)
- RAM: 292 MiB saved to TrueNAS SCALE zvol, rollback verified (/dev/shm proof)
Filed #277 (GET_LBA_STATUS iSCSI error — non-fatal log noise).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v3.1.0
2026-06-07 15:04:09 -04:00
Kevin AdamsandClaude Sonnet 4.6 80a78896bf fix: add state volume pattern to parse_volname (#234)
PVE allocates a vm-<vmid>-state-<snapname> volume when a snapshot is taken
with "Include RAM" selected. parse_volname didn't recognise this pattern,
causing a crash during both setup and cleanup of the state volume.

Added state volume pattern — treated as raw images, same vmid extraction
as disk volumes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 14:19:14 -04:00
Kevin AdamsandClaude Sonnet 4.6 a47346161b fix: use bare return instead of return undef (perlcritic)
Subroutines::ProhibitExplicitReturnUndef — volume_snapshot,
volume_snapshot_delete, volume_snapshot_rollback all used return undef
where bare return is the correct Perl idiom.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 14:14:53 -04:00
Kevin AdamsandClaude Sonnet 4.6 59d8a8100f feat: implement ZFS snapshot interface via TrueNAS REST API (#234)
Implements the full PVE storage plugin snapshot interface backed by native
ZFS snapshots on TrueNAS, via the v2.0 REST API:

  volume_has_feature       — advertises snapshot support for raw volumes
  volume_snapshot_needs_fsfreeze — returns 1 (request guest IO freeze)
  volume_snapshot          — POST /zfs/snapshot {dataset, name}
  volume_snapshot_delete   — DELETE /zfs/snapshot/id/{uri_escaped_id}
  volume_snapshot_rollback — POST /zfs/snapshot/rollback {id, options}
  volume_rollback_is_possible — enforces ZFS "most recent snap only" rule
  volume_snapshot_info     — GET /zfs/snapshot?dataset=... → {name: {id, ctime}}

Snapshot ID format: pool/volname@snapname
DELETE path requires full URI encoding (uri_escape) — unlike the dataset
endpoint, the snapshot API does not accept bare slashes in the path segment.

Tested on pve01-hq (PVE 9.2.3) against TrueNAS CORE 13.0-U6:
  - create / list / delete: OK
  - rollback_is_possible ordering: correctly rejects non-latest snapshots

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 14:09:45 -04:00
Kevin AdamsandClaude Sonnet 4.6 58a648e1a3 fix: use GITHUB_TOKEN for gh-pages push (ACCESS_TOKEN expired)
The ACCESS_TOKEN secret was created in 2022 and has expired. Switch both
gh-pages publish steps (stable and testing dist) to github.token, which is
generated fresh per run and never expires. Add permissions: contents: write
to the publish job so GITHUB_TOKEN can push to gh-pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 11:08:04 -04:00
Kevin AdamsandClaude Sonnet 4.6 da0aaff0d2 fix: testing dist channel name and broken README badges (#275)
build.yml: testing dist publish condition used 'beta'/'alpha' but the
workflow channel values are 'testing'/'development' — step was always
skipped. Corrected to match actual channel names.

README: badge URLs referenced TheGrandWazoo/truenas-proxmox (repo not yet
renamed); corrected to freenas-proxmox. Workflow badge now includes
branch=release/3.x so it tracks the default branch explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 10:09:14 -04:00
Kevin AdamsandClaude Sonnet 4.6 1c98591ed4 fix: add Debian changelog to both packages (#273)
Adds packaging/changelog.Debian and packaging/DEBIAN-transitional/changelog.Debian
and wires them into the build staging steps. The gzipped changelog lands at
/usr/share/doc/truenas-proxmox/changelog.Debian.gz and
/usr/share/doc/freenas-proxmox/changelog.Debian.gz respectively, satisfying
Debian policy §12.7 and silencing the 'apt changelog' failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 09:02:24 -04:00