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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Same sed bug as fixed on gh-pages: was stripping 'Filename: ' label
entirely, leaving a bare path that apt cannot use to download packages.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
build.yml:
- New "Publish to GitHub Pages testing dist" step — runs on beta/alpha
channel builds (pushes to release/3.x and master); replaces pool/testing/
with the latest build so the dist always has exactly one version
- Cloudsmith now receives v2.x stable only; beta/alpha no longer published
to Cloudsmith testing channel
README:
- Replace Cloudsmith testing install instructions with GitHub Pages testing
dist track; same GPG key as stable, just different dist name
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stable v3.x and above go to GitHub Pages only. Cloudsmith still receives:
- v2.x stable releases (existing Cloudsmith user base on freenas-proxmox)
- beta/alpha/dev builds (testing channel, until GitHub Pages testing track
ships as a v3.1.0 item)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
scripts/migrate-repo-to-github-pages.sh:
- Detects installed version and picks the correct dist track automatically
- Finds Cloudsmith sources by URL content (not filename) to handle the
varied naming conventions users have in sources.list.d/
- Removes old keyrings, imports GitHub Pages key, writes new source
- Confirms the package is visible from the new repo before exiting
build.yml publish job:
- Add empty binary-amd64 and binary-arm64 Packages files alongside
binary-all, and set Architectures: all amd64 arm64 in Release
- Silences the "doesn't support architecture 'amd64'" warning on PVE
hosts without duplicating package entries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements ADR-010: stable releases are now published to
https://thegrandwazoo.github.io/freenas-proxmox/ in addition to Cloudsmith.
Dist tracks:
v3 main — v3.x releases (new installs)
main main — v2.x only (backward-compat, never auto-promoted to v3)
v2 main — v2.x alias (explicit pin)
CI: new "Publish to GitHub Pages APT repo" step in the publish job runs on
tagged stable releases. Downloads the built .deb, places it in pool/v{major},
regenerates Packages.gz and a GPG-signed InRelease for the relevant dist(s),
and pushes to the gh-pages branch.
Setup: scripts/setup-apt-signing-key.sh generates the GPG key pair and prints
the exact `gh secret set` commands to run. Requires APT_SIGNING_KEY and
APT_SIGNING_KEY_PASSPHRASE secrets to be added to the repo before the first
tagged release.
README updated to point new installs at GitHub Pages; Cloudsmith testing
channel retained for beta builds.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces truenas-proxmox as the real package and freenas-proxmox as a
transitional meta-package that Depends on truenas-proxmox. Existing
users running apt upgrade automatically pull in the new package; the
migration one-liner (apt install truenas-proxmox && apt purge
freenas-proxmox) completes the transition. The freenas-proxmox package
name will not exist in v4.0.
Changes:
- packaging/DEBIAN/: Package renamed to truenas-proxmox, INSTALL_DIR
and LOG_FILE updated to /usr/share/truenas-proxmox and
/var/log/truenas-proxmox-install.log; Replaces/Breaks fields added
- packaging/DEBIAN-transitional/: new empty meta-package that pulls in
truenas-proxmox and prints a deprecation notice on configure
- build.yml: PACKAGE_NAME=truenas-proxmox; both debs built and
published to Cloudsmith; transitional postinst added to shellcheck
- All GitHub repo URLs updated to TheGrandWazoo/truenas-proxmox
- apt install/remove/purge commands in docs updated to truenas-proxmox
- GitHub repo rename to truenas-proxmox pending (gh repo rename step)
Closes#262
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consolidating to a single payment path to reduce decision friction.
GitHub Sponsors has no platform fee; PayPal does.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 env var to suppress deprecation
warnings ahead of GitHub's June 2nd forced cutover. Pin actions/checkout
to v4.3.1 (latest v4 patch). Upload/download-artifact left at @v4 pending
a separate audit of the v7/v8 breaking changes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Inject pveOnlineHelpInfo entry in truenas-storage.js so PVE wires
the Help button automatically via the StorageBase framework
- Add onlineHelp: 'storage_truenas' to the input panel definition
- Add ui/truenas-storage-help.html — local help page installed to
/usr/share/pve-docs/truenas-storage.html (no internet required)
- Add docs/getting-started.md and docs/architecture.md
- Update postinst/postrm to install and remove the help HTML file
- Update build.yml to include the help HTML in the package staging dir
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the validate-patches job (no more patch files in v3.0).
Update lint to target TrueNAS.pm instead of FreeNAS.pm.
Rebuild staging assembly: TrueNAS.pm + truenas-storage.js are the
only payload — no patch dirs, no REST-Client.pm, no triggers file.
Add $VERSION = '3.0.0' to TrueNAS.pm as the single source of truth.
Add release/3.x as a testing-channel branch alongside master.
Pin actions to @v4 (upload/download-artifact, checkout).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: auto-detect and correct ZFS blocksize for TrueNAS SCALE/CORE (#241)
SCALE requires >= 16k volblocksize; CORE works with 8k. Without correction,
creating a disk on SCALE with blocksize=8k triggers a ZFS warning and wastes
space on SCALE's minimum-4k-block pool layout.
Three changes:
- freenas_get_recommended_blocksize: fixes freenas_api_connect → freenas_api_check
so product_name is actually populated before the SCALE check (was always returning
8192 before this fix)
- freenas_parse_blocksize: new helper to compare "8k"/"16k"/integer blocksize strings
- alloc_image (both 8.x and 8.4.x patches): always detect recommended blocksize for
freenas provider; if configured < recommended, override for this call AND persist
the correction back to storage.cfg via lock_storage_config
- on_add_hook (8.4.x patch only): detect at storage creation time and correct $scfg
before write_config saves it — no extra write needed
Tested on pve01-hq (PVE 8.4.19) against Tank02 (SCALE 24.10.2.1):
- Disk created with blocksize=8k → task log shows correction message, storage.cfg
updated to 16384, no volblocksize warning from TrueNAS
- Disk created with blocksize=16384 → no-op, clean TASK OK
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: add validate-patches step for ZFSPlugin PVE 8.4.x patch
ZFSPlugin-8.4.14_1.pm.patch has been in the build since v2.3.0 but was
never dry-run validated in CI. Now that we have the 8.4 orig committed
(ZFSPlugin-8.4.14_1.pm.orig from libpve-storage-perl 8.3.8), wire it up.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: replace explicit return undef with bare return (perlcritic)
Subroutines::ProhibitExplicitReturnUndef violation in
freenas_get_recommended_blocksize. Bare return in list context returns
an empty list rather than a list containing undef, which is the
correct Perl idiom.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Stable releases now produce X.Y.Z-1 (e.g. 2.3.0-1) so they sort higher
than any pre-release build in dpkg. Pre-release builds now use tilde
(~beta+sha, ~alpha+sha) which sorts below the base version, ensuring
apt upgrade always selects stable over a previously installed beta.
Previously -beta+sha sorted higher than X.Y.Z causing apt to refuse
upgrades from beta to stable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
softprops/action-gh-release@v3 adds Node 24 support (v2 was Node 20).
Pin cloudsmith-io/action to v0.6.14 (latest stable) instead of @master.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two install-time failures on PVE 8.4.x nodes:
1. 'patch' utility not in Depends — causes silent patch failure on fresh
nodes; all three PVE file patches silently skip, plugin appears to
install but storage operations fail. Added 'patch' to control.j2.
2. ZFSPlugin.pm routing not applied on PVE 8.4.x — tabs→spaces reformat
and get_base($scfg) signature change in 8.4 broke hunks #3 and #4
(the freenas elsif routing branches). Nodes with a prior partial
install are doubly affected: grep idempotency check passes on partial
freenas strings, so the routing is never applied, causing:
"freenas: unknown iscsi provider" on clone/migrate operations.
New ZFSPlugin-8.4.14_1.pm.patch generated against stock PVE 8.4.19,
bundled as patches/ZFSPlugin/8.4.patch alongside existing 8.patch.
Verified clean on pve01-hq (8.4.19) and pve02-hq (8.4.14).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Users on unsupported PVE versions now get clear guidance at every
layer — README, install time, and GitHub release notes — rather than
silently failing or getting confusing patch errors.
- README: replace bare compatibility table with a full matrix and
prominent callout blocks for PVE 7 (last v2.x), PVE 8 (EOL
2026-08-31), PVE 9+ (use v3.0), and PVE ≤6 (unsupported)
- postinst: add check_pve_version() that exits on PVE < 7, warns
loudly on PVE 7 (stay on v2.x, do not upgrade to v3.0), notes
the PVE 8 EOL date, and warns on PVE 9+ (v2.x not supported)
- build.yml release template: add a version compatibility table so
every GitHub release prominently states who should and should not
install it
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PVE 8.4 reformatted pvemanagerlib.js (tabs→spaces, structural changes),
making the existing 8.0.5-era patch fail on all 8.4.x nodes.
- Add pvemanagerlib-8.4.14_1.js.patch covering PVE 8.4.x (all hunks
verified on 8.4.14 and 8.4.19)
- Update postinst to detect pve-manager major.minor (e.g. "8.4") and
try a minor-version-specific patch before falling back to the major
patch — 8.3.x nodes keep using 8.patch, 8.4.x nodes use 8.4.patch
- Update build.yml to bundle 8.4.patch alongside the existing 8.patch
Tested live on pve01-hq (8.4.19) and pve03-hq (8.3.2) — correct patch
selected in each case, pvemanagerlib patched successfully on 8.4.19.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GitHub is removing Node.js 20 from Actions runners on Sep 16, 2026
and forcing Node 24 as default from Jun 2, 2026. Upgrade all
first-party actions to latest major versions that ship with node24:
actions/checkout@v4 → v6
actions/upload-artifact@v4 → v7
actions/download-artifact@v4 → v8
Note: setup-python@v5 warning is inside cloudsmith-io/action@master
and is not directly addressable here.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
our \$VERSION = '2.3.0' is now the single source of truth for the release
series. The build.yml extracts it with a perl one-liner (no module load,
no stubs needed) and uses it as BASE_VERSION for alpha/beta channel builds.
Git tags remain the release trigger: pushing an exact vX.Y.Z tag publishes
to the stable Cloudsmith channel. A mismatch warning fires if the tag
version and \$VERSION disagree, catching forgotten version bumps.
The v2.3.0-pre anchor tag approach is superseded by this; the anchor tag
can stay in history as a breadcrumb but \$VERSION is now what drives builds.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two changes:
1. BASE_VERSION now strips pre-release suffixes from the nearest ancestor tag
(e.g. v2.3.0-pre → 2.3.0), so anchor tags like v2.3.0-pre make feature
branch builds say 2.3.0-alpha+<sha> without "pre" leaking into the version.
2. Stable release detection changed from glob (refs/tags/v*) to an exact
semver regex (^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$). Tags with a suffix
(v2.3.0-pre, v2.3.0-rc1) build and validate but do not publish to Cloudsmith
stable — they fall through to the 'none' channel.
This lets us place a v2.3.0-pre anchor tag to version the development series
correctly, then later push v2.3.0 as the actual stable release.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
perl -c requires all modules to be loadable at compile time. PVE::SafeSyslog
only exists on Proxmox VE hosts, so the syntax check always failed on
GitHub Actions runners. Fix:
- Install real Perl deps via apt (libwww-perl, libio-socket-ssl-perl,
librest-client-perl, libjson-perl)
- Create a minimal stub for PVE::SafeSyslog so perl -c can load FreeNAS.pm
- Pass -I/tmp/pve-stub to perl -c so the stub is found
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unquoted YAML plain scalars cannot contain ': ' (colon-space) because
the parser interprets it as a nested key-value mapping. The two step
names 'Dry-run patch: ZFSPlugin (PVE 8)' and 'Dry-run patch: apidoc.js
(PVE 8)' triggered this, causing GitHub Actions to reject the workflow
file before any jobs ran.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs that prevented any jobs from running:
1. action.yml contained only YAML comments (no 'on:' or 'jobs:' keys),
making it an invalid workflow file. GitHub rejected it at parse time.
Fixed by giving it a minimal valid structure with workflow_dispatch
trigger only, so it never fires automatically.
2. build.yml perlcritic step referenced perl5/PVE/Storage/Custom/FreeNAS.pm
which is not committed to the repository, causing a step failure.
Removed — only FreeNAS.pm (LunCmd) is linted for now.
3. build.yml publish job used 'if: |' block scalar for a multi-line
expression, which GitHub Actions rejects in expression position.
Changed to a single inline expression string.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>