# freenas-proxmox v3.0 — Architecture & Developer Guide ## Table of Contents 1. [Architecture Overview](#1-architecture-overview) 2. [Per-VM iSCSI Target Model](#2-per-vm-iscsi-target-model) 3. [The `iscsi://` Path Model](#3-the-iscsi-path-model) 4. [API Flow — TrueNAS REST v2.0](#4-api-flow--truenas-rest-v20) 5. [alloc_image Deep Dive](#5-alloc_image-deep-dive) 6. [free_image Deep Dive](#6-free_image-deep-dive) 7. [Build Pipeline and Version/Channel Routing](#7-build-pipeline-and-versionchannel-routing) 8. [Debugging Guide](#8-debugging-guide) 9. [Contributing](#9-contributing) --- ## 1. Architecture Overview ### Where This Plugin Sits Proxmox VE organizes storage backends through a plugin registry. Every storage type — directory, LVM, Ceph, ZFS-over-iSCSI — is a Perl module that subclasses `PVE::Storage::Plugin`. The `pvedaemon` process loads all registered storage plugins at startup and delegates storage operations (create volume, delete volume, list volumes, etc.) to the correct plugin based on the `type` field in `/etc/pve/storage.cfg`. `PVE::Storage::Custom::TrueNAS` is loaded by PVE's auto-discovery mechanism. Any module installed under `/usr/share/perl5/PVE/Storage/Custom/` is automatically registered as a custom storage type. No patching of PVE's core `ZFSPlugin.pm`, `pvemanagerlib.js`, or `apidoc.js` is required — this is the fundamental architectural change from v2.x. ``` Proxmox VE (pvedaemon) └─ PVE::Storage # core storage dispatch └─ PVE::Storage::Custom::TrueNAS # this plugin └─ TrueNAS REST API v2.0 # all state lives here ├─ /pool/dataset # zvol create/delete/resize └─ /iscsi/* # extent, target, targetextent CRUD ``` ### What the Plugin Manages The plugin manages the entire lifecycle of iSCSI-backed block devices on behalf of Proxmox VE: - **ZFS volumes (zvols)** — the actual block storage, created and destroyed via `POST /pool/dataset` and `DELETE /pool/dataset/id/{id}` - **iSCSI extents** — TrueNAS's representation of a device to export over iSCSI, one per zvol - **iSCSI targets** — the access point a client connects to, one per VM (`proxmox-vm-`) - **targetextent mappings** — the join record linking an extent to a target at a specific LUN ID The plugin does NOT manage the iSCSI initiator side. QEMU's built-in libiscsi opens the `iscsi://` URI returned by `path()` directly, without any host-side session management via `iscsiadm`. ### What the Plugin Does Not Do - **Pool name auto-discovery**: The user types the TrueNAS pool name directly in the Add Storage dialog. The plugin does not enumerate available pools. Pool capacity is returned via the TrueNAS API (`GET /pool/dataset`), not SSH. - **Snapshots on PVE 8.x**: The `volume_snapshot` family of methods is defined but will return an unsupported error on PVE 8. PVE 9.0's Snapshot-as-Volume-Chains feature is the target integration point (v3.1.0, ADR-008). - **TPM state disks**: swtpm (the virtual TPM backend) cannot use `iscsi://` URIs; it requires a local filesystem path. TPM disks must be placed on a different storage type. ### Installed File Locations | File | Destination on Proxmox host | |---|---| | `perl5/PVE/Storage/Custom/TrueNAS.pm` | `/usr/share/perl5/PVE/Storage/Custom/TrueNAS.pm` | | `ui/truenas-storage.js` | `/usr/share/pve-manager/js/truenas-storage.js` | | One `