13 Commits

Author SHA1 Message Date
Timur Kumakbayev 6c4411ede9 Merge pull request #95 from brngates98/issue94-add-lxc
feat: advertise rootdir for LXC root volumes (plugindata + docs)
2026-05-04 02:18:16 +05:00
Brian Gates 45bb0e24eb Update README to include LXC support details
Added support for LXC container root volumes in the plugin documentation.
2026-05-03 17:12:36 -04:00
Brian Gates 2c222ef704 Update plugindata to include rootdir in content 2026-05-03 17:11:57 -04:00
Timur Kumakbayev 40eb92df32 Merge pull request #93 from brngates98/issue84
Refactor pod capacity retrieval and space calculations
2026-05-04 01:58:30 +05:00
Brian Gates f7d06166fc Run Perltidy and fix linting issues 2026-05-03 16:48:34 -04:00
Brian Gates ed358b13c5 Fix purestorage pod status totals, usage scope, and space metrics 2026-05-03 16:27:05 -04:00
Brian Gates 397e2f5b64 Refactor pod capacity retrieval and space calculations 2026-05-03 15:28:50 -04:00
Timur Kumakbayev d6b0035d5e Merge pull request #90 from tommymcguiver/api-version-13-updates
API Version 13
2026-02-27 10:59:13 +05:00
Ken Miles e0e4009426 Merge remote-tracking branch 'origin/main' into api-version-13-updates 2026-02-26 09:49:04 +10:00
Timur Kumakbayev c1ff0acf15 Merge pull request #87 from tommymcguiver/syslogging-improvments-2
Improve syslogging implementation and code
2026-02-25 15:13:00 +05:00
Ken Miles 63b2c46104 API Version 13
Modify function signatures, no functionality changes
2026-02-25 13:50:02 +10:00
Ken Miles 0ace4fe87d Improve syslogging implementation and code
Convert direct print statements to use the logger for consistent info message handling.

Also convert warn and die calls to log with the common logger for unified logging.

Removes repetition, enables logging to syslog which allows each message to be timestamped, and can more easily compare
with other systemctl logs like multipathd and iscsid daemons and proxmox services to make it easier to identify race
conditions.
2026-02-24 15:52:59 +10:00
Timur Kumakbayev c666235082 Build script and documentation updates (#83) 2026-01-18 05:05:25 +05:00
5 changed files with 779 additions and 250 deletions
+2
View File
@@ -10,3 +10,5 @@ tests/test_results.txt
/*.deb
*.log
*.substvars
build/
changelog
+273 -196
View File
File diff suppressed because it is too large Load Diff
+401 -53
View File
@@ -5,19 +5,24 @@
This plugin enables the integration of Pure Storage arrays with Proxmox
Virtual Environment (VE) using multipath iSCSI or Fibre Channel (FC).
It allows you to use Pure Storage as a backend for your virtual machine
disks, providing high performance and reliability.
disks, and optionally for LXC container root volumes when configured,
providing high performance and reliability.
## Table of Contents
- [Features](#features)
- [Linux containers (LXC)](#linux-containers-lxc)
- [Prerequisites](#prerequisites)
- [Multipath Configuration](#multipath-configuration)
- [iSCSI Configuration](#iscsi-configuration)
- [Installation](#installation)
- [Manual](#manual)
- [APT](#apt)
- [Manual Installation](#manual-installation)
- [Debian Package Installation (Recommended)](#debian-package-installation-recommended)
- [Configuration](#configuration)
- [Troubleshooting](#troubleshooting)
- [Debug Logging](#debug-logging)
- [Service Status](#service-status)
- [Diagnostic Commands](#diagnostic-commands)
- [Known issues](#known-issues)
- [Contributing](#contributing)
@@ -36,6 +41,21 @@ disks, providing high performance and reliability.
- Instant storage migration
- The plugin will automatically map the iSCSI volumes needed on the
host the VM is being migrated to
- Optional **LXC** support — include `rootdir` in `content` to allow raw
image-backed container root disks on the same block path as QEMU disks
(see [Linux containers (LXC)](#linux-containers-lxc))
## Linux containers (LXC)
The plugin exposes the Proxmox **`rootdir`** content type so a storage
section can host **LXC root filesystems** as raw volumes, alongside
`images` (QEMU disks), when you set e.g. `content images,rootdir`.
LXC on this backend uses the same allocation and device path logic as VM
disks. **Support is best-effort and community-tested** — validate create,
resize, and delete for your workloads on a real array before relying on it
in production. If you only need QEMU VMs, keep `content images` (omit
`rootdir`).
## Prerequisites
@@ -93,7 +113,7 @@ blacklist_exceptions {
}
```
## iSCSI Configuration
### iSCSI Configuration
Initiate iSCSI according to the Proxmox Guidelines.
@@ -108,35 +128,106 @@ sudo iscsiadm -m node --op update -n node.startup -v automatic
## Installation
There are two methods to install the plugin: manual installation and APT
package installation.
There are two methods to install the plugin: manual installation and Debian
package installation via APT.
### Manual
> [!IMPORTANT]
> If you are using a cluster setup, install the plugin on all nodes in the
> cluster. The storage configuration will be automatically synchronized via
> corosync, but the plugin code must be present on each node.
To manually install the plugin, follow these steps:
### Manual Installation
Manual installation is useful for development or when you want to install
from source.
#### Step 1: Install required dependencies
```bash
# Clone repository
git clone https://github.com/kolesa-team/pve-purestorage-plugin.git
# Navigate to the Plugin Directory
cd pve-purestorage-plugin
# Create the custom plugin directory if it does not already exist
mkdir /usr/share/perl5/PVE/Storage/Custom
# Copy plugin to custom plugin directory
cp PureStoragePlugin.pm /usr/share/perl5/PVE/Storage/Custom/PureStoragePlugin.pm
# Restart Proxmox VE
systemctl restart pve-cluster.service pvedaemon.service pvestatd.service pveproxy.service pvescheduler.service
sudo apt-get update
sudo apt-get install -y \
libwww-perl \
libjson-perl \
libjson-xs-perl
```
### APT
**Note**: Replace `<PACKAGE_VERSION>` with your desired version number
(e.g., `0.0.1`).
#### Step 2: Clone the repository
```bash
PACKAGE_VERSION="<PACKAGE_VERSION>" curl -L -o libpve-storage-purestorage-perl.deb "https://github.com/kolesa-team/pve-purestorage-plugin/releases/download/v$PACKAGE_VERSION/libpve-storage-purestorage-perl_$PACKAGE_VERSION-1_all.deb"
git clone https://github.com/kolesa-team/pve-purestorage-plugin.git
cd pve-purestorage-plugin
```
sudo apt install ./libpve-storage-purestorage-perl.deb
#### Step 3: Install the plugin
```bash
# Create the custom plugin directory
sudo mkdir -p /usr/share/perl5/PVE/Storage/Custom
# Copy plugin file
sudo cp PureStoragePlugin.pm /usr/share/perl5/PVE/Storage/Custom/PureStoragePlugin.pm
# Set correct permissions
sudo chmod 644 /usr/share/perl5/PVE/Storage/Custom/PureStoragePlugin.pm
```
#### Step 4: Restart Proxmox VE services
```bash
sudo systemctl restart pvedaemon.service pveproxy.service
```
#### Step 5: Verify installation
```bash
pvesm status
# The purestorage type should now be available
```
### Debian Package Installation (Recommended)
Installing via Debian package is the recommended method as it handles
dependencies automatically and provides easy updates.
#### Step 1: Download the package*
Replace `<PACKAGE_VERSION>` with the desired version (e.g., `0.0.1`). Check
the [releases page](https://github.com/kolesa-team/pve-purestorage-plugin/releases)
for available versions.
```bash
PACKAGE_VERSION="<PACKAGE_VERSION>"
wget "https://github.com/kolesa-team/pve-purestorage-plugin/releases/download/v${PACKAGE_VERSION}/libpve-storage-purestorage-perl_${PACKAGE_VERSION}-1_all.deb"
```
#### Step 2: Install the package
```bash
sudo apt install ./libpve-storage-purestorage-perl_${PACKAGE_VERSION}-1_all.deb
```
#### Step 3: Verify installation
```bash
dpkg -l | grep libpve-storage-purestorage-perl
# Should show the installed package version
```
#### To upgrade to a newer version
```bash
# Download new version
PACKAGE_VERSION="<NEW_VERSION>"
wget "https://github.com/kolesa-team/pve-purestorage-plugin/releases/download/v${PACKAGE_VERSION}/libpve-storage-purestorage-perl_${PACKAGE_VERSION}-1_all.deb"
# Upgrade
sudo apt install ./libpve-storage-purestorage-perl_${PACKAGE_VERSION}-1_all.deb
```
#### To uninstall
```bash
sudo apt remove libpve-storage-purestorage-perl
```
## Configuration
@@ -160,6 +251,10 @@ pvesm add purestorage <storage_id> \
--content images
```
To allow **LXC container root disks** on the same pool as well, use
`--content images,rootdir` instead of `--content images` (see
[Linux containers (LXC)](#linux-containers-lxc)).
Alternatively, you can manually edit the storage configuration file
`/etc/pve/storage.cfg`.
@@ -183,7 +278,7 @@ purestorage: <storage_id>
| podname | (`optional`, conflicts with `vgname`) The pod name where virtual disks will be stored. This should match the configuration on your Pure Storage array. |
| vnprefix | (`optional`) The prefix to prepend to name of virtual disks. |
| hgsuffix | (`optional`) A suffix that is appended to the hostname when the plugin interacts with the Pure Storage array. This can help differentiate hosts if necessary. |
| content | Specifies the types of content that can be stored. For virtual machine disk images, use images. |
| content | Specifies the types of content that can be stored. Use `images` for QEMU VM disks. Add `rootdir` (e.g. `images,rootdir`) to allow LXC root volumes on the same pool; see [Linux containers (LXC)](#linux-containers-lxc). |
| protocol | (`optional`, default is `iscsi`) Specifies the storage protocol (`iscsi`, `fc`). |
| check_ssl | (`optional`, default is `no`) Verify the server's TLS certificate. Set to `yes` to enable SSL certificate verification. |
| token_ttl | (`optional`, default is `3600`) Session token time-to-live in seconds. The plugin caches PureStorage API session tokens in `/etc/pve/priv/purestorage/` (automatically replicated across cluster nodes). Tokens are proactively refreshed at 80% of TTL to prevent expiration during operations. |
@@ -215,6 +310,18 @@ purestorage: pure-cluster
content images
```
**LXC-capable pool** (`images` and `rootdir`; best-effort — see
[Linux containers (LXC)](#linux-containers-lxc)):
```text
purestorage: pure-lxc
address https://purestorage.example.com
token abc123
vgname pure_vg
hgsuffix ""
content images,rootdir
```
> [!NOTE]
> When multiple arrays are specified (Active Cluster configuration -
> experimental feature), the plugin automatically connects volumes to hosts
@@ -229,15 +336,18 @@ steps:
### Debug Logging
Enable debug logging to diagnose issues:
The plugin provides detailed debug logging to help diagnose issues. Debug
output is written to syslog and can be viewed in Proxmox logs.
**Persistent (via configuration):**
**Enable debug logging:**
Persistent (via configuration):
```bash
pvesm set <storage_id> --debug 1
```
**Temporary (for single command, when debug is not set in config):**
Temporary (for single command, when debug is not set in config):
```bash
PURESTORAGE_DEBUG=1 pvesm list <storage_id>
@@ -246,12 +356,12 @@ PURESTORAGE_DEBUG=1 pvesm list <storage_id>
> **Note:** If `debug` is set in storage configuration, it takes priority
> over `PURESTORAGE_DEBUG` environment variable.
Debug levels:
**Debug levels:**
- `0` - Off (production, default)
- `1` - Basic (token operations, main function calls)
- `2` - Verbose (HTTP requests, token validation details)
- `3` - Trace (all internal operations)
- `1` - Basic (token operations, main function calls, volume operations)
- `2` - Verbose (HTTP requests, token validation, API responses)
- `3` - Trace (all internal operations, detailed flow)
**Example debug output:**
@@ -264,6 +374,47 @@ Debug :: Token is valid (age: 125s)
Debug :: Using cached token from file (age: 125s)
```
**Common debug scenarios:**
Debug volume creation:
```bash
PURESTORAGE_DEBUG=2 pvesm alloc <storage_id> <vmid> <volname> 10G
```
Debug volume deletion:
```bash
PURESTORAGE_DEBUG=2 pvesm free <storage_id>:<volname>
```
Debug API authentication issues:
```bash
PURESTORAGE_DEBUG=3 pvesm status <storage_id>
```
**View debug logs:**
Check Proxmox daemon logs:
```bash
journalctl -u pvedaemon -f
```
Filter for PureStorage plugin messages:
```bash
journalctl -u pvedaemon | grep -E "(Debug ::|Info ::|Warning ::|Error ::)"
```
Check token cache status:
```bash
ls -lah /etc/pve/priv/purestorage/
cat /etc/pve/priv/purestorage/<storage_id>_array0.json | jq .
```
### Service Status
Ensure that the Proxmox VE services are running correctly. You can restart
@@ -273,33 +424,195 @@ the services if necessary:
sudo systemctl restart pve-cluster.service pvedaemon.service pvestatd.service pveproxy.service pvescheduler.service
```
### Network and Storage
### Diagnostic Commands
- Verify Network Connectivity: Ensure that the Proxmox VE nodes can reach
the Pure Storage array over the network. Check for firewall rules or
network issues that might be blocking communication.
- Review Logs: Check the Proxmox VE logs for any error messages related to
storage or the plugin. Logs are typically found in /var/log/pve. These
commands are helpful for troubleshooting:
**Multipath diagnostics:**
```bash
multipath -ll -v3 #diagnose issues with the multipath service
iscsiadm -m node #list what iscsi nodes are mounted
ls -l /dev/mapper/3624a9370* #list wwids of Pure mapped devices on the system
```
List all multipath devices with details:
- Multipath Configuration: Verify that your multipath.conf is correctly
configured and that multipath devices are recognized. Use multipath -ll
to list the current multipath devices.
- API Token Permissions: Ensure that the API token used has the necessary
permissions to create and manage volumes on the Pure Storage array.
- Plugin Updates: Ensure you are using the latest version of the plugin.
Check the GitHub repository for updates.
```bash
multipath -ll
```
Verbose multipath debugging:
```bash
multipath -ll -v3
```
Show only Pure Storage devices:
```bash
multipath -ll | grep -A 10 "3624a9370"
```
Reload multipath configuration:
```bash
systemctl reload multipathd
```
**iSCSI diagnostics:**
List all iSCSI sessions:
```bash
iscsiadm -m session
```
Show detailed session information:
```bash
iscsiadm -m session -P 3
```
List all discovered targets:
```bash
iscsiadm -m node
```
Rescan iSCSI sessions:
```bash
iscsiadm -m session --rescan
```
**PureStorage volume diagnostics:**
List all Pure Storage mapped devices:
```bash
ls -l /dev/mapper/3624a9370*
```
Show device information:
```bash
lsblk | grep "3624a9370"
```
Check device WWIDs:
```bash
/lib/udev/scsi_id --whitelisted --device=/dev/mapper/3624a9370<wwid>
```
Show device mapper table:
```bash
dmsetup table
```
Show device mapper dependencies:
```bash
dmsetup deps -o devname
```
List all device mapper devices:
```bash
dmsetup ls --tree
```
Show detailed info for specific device:
```bash
dmsetup info /dev/mapper/3624a9370<wwid>
```
**Partition management (kpartx):**
List partitions on a device:
```bash
kpartx -l /dev/mapper/3624a9370<wwid>
```
Add partition mappings:
```bash
kpartx -a /dev/mapper/3624a9370<wwid>
```
Remove partition mappings:
```bash
kpartx -d /dev/mapper/3624a9370<wwid>
```
Sync partition table:
```bash
kpartx -u /dev/mapper/3624a9370<wwid>
```
**Storage plugin diagnostics:**
List all volumes on storage:
```bash
pvesm list <storage_id>
```
Show storage status:
```bash
pvesm status <storage_id>
```
Scan for new volumes:
```bash
pvesm scan <storage_id>
```
Test volume allocation (dry-run):
```bash
pvesm alloc <storage_id> <vmid> test-volume 1G
pvesm free <storage_id>:test-volume
```
**Network connectivity:**
Test API endpoint connectivity:
```bash
curl -k https://<array_address>/api/2.30/arrays
```
Test with API token:
```bash
curl -k -X POST https://<array_address>/api/2.30/login \
-H "Content-Type: application/json" \
-d '{"api_token":"<your_token>"}'
```
Check iSCSI portal connectivity:
```bash
nc -zv <array_iscsi_ip> 3260
```
**Common issues:**
- **API Token Permissions**: Ensure the API token has sufficient permissions
to create and manage volumes on the Pure Storage array
- **Multipath Configuration**: Verify multipath.conf is correctly configured
and multipath devices are recognized
- **Network Connectivity**: Check firewall rules and network routes to Pure
Storage array
- **Plugin Updates**: Ensure you are using the latest version of the plugin
### Known issues
- `lvm inside a volume`: If you plan to use LVM inside a volume, it is
better to add purestorage volumes to the ignore list to avoid scanning.
**LVM inside a volume:**
If you plan to use LVM inside a volume, it is better to add purestorage
volumes to the ignore list to avoid scanning.
```bash
cat /etc/lvm/lvmlocal.conf
@@ -310,6 +623,41 @@ devices {
}
```
**Debug output contamination ([#56](https://github.com/kolesa-team/pve-purestorage-plugin/issues/56)):**
When debug logging is enabled, debug messages may contaminate command
outputs that should be clean (e.g., `qm showcmd`, `pvesm path`). This can
break tools that parse these outputs.
Workaround: Disable debug logging when using commands that need clean output:
```bash
pvesm set <storage_id> --debug 0
```
Or use temporary debug only when needed:
```bash
PURESTORAGE_DEBUG=1 <command>
```
**Volume auto-mount issues ([#59](https://github.com/kolesa-team/pve-purestorage-plugin/issues/59)):**
The `filesystem_path` function returns device paths that may not work
reliably when volumes are deactivated. This affects operations like
`qm showcmd` and backup tools (e.g., Veeam) that need direct access to
volume paths.
Current behavior: Volumes are activated on-demand and may deactivate when
not in use.
Workaround: Ensure volumes are activated before accessing them directly.
For automated workflows, consider implementing volume activation in your
scripts.
Note: A proper solution using autofs for automatic volume mounting is being
evaluated.
## Contributing
Contributions to this project are welcome.
+8 -1
View File
@@ -10,10 +10,17 @@ Build-Depends: debhelper, devscripts
Package: libpve-storage-purestorage-perl
Architecture: all
Depends: ${perl:Depends}, ${misc:Depends}, libpve-storage-perl (>= 8.2.1), multipath-tools
Depends: ${perl:Depends}, ${misc:Depends},
libpve-storage-perl (>= 8.2.1),
multipath-tools,
libjson-xs-perl,
libwww-perl,
liburi-perl
Description: Pure Storage integration library for Proxmox VE
This package provides a Perl library to integrate Pure FlashArray Storage systems
with the Proxmox VE storage management infrastructure.
.
It allows administrators to configure and manage Pure FlashArray Storage devices
directly within the Proxmox VE environment.
.
Supports Proxmox VE 8.2+ and Proxmox VE 9+.
+95
View File
@@ -0,0 +1,95 @@
#!/bin/bash
set -e
# Build Debian package locally using Docker
# This script mimics the CI/CD build process for local testing
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
BUILD_IMAGE="debian:bookworm"
echo "Building Debian package locally..."
# Check if Docker is available
if ! command -v docker &> /dev/null; then
echo "Error: Docker is not installed or not in PATH"
exit 1
fi
# Run build in Docker container
docker run --rm \
-v "$PROJECT_DIR:/workspace" \
-w /workspace \
"$BUILD_IMAGE" \
bash -c '
set -e
echo "Installing build dependencies..."
apt-get update -qq
apt-get install -y -qq \
debhelper \
devscripts \
build-essential \
git
echo "Installing package build dependencies..."
apt-get build-dep -y . || true
echo "Generating changelog..."
pkgname=libpve-storage-purestorage-perl
tag_list=$(git tag -l | grep -ve "-rc\.[0-9]$" | grep -ve "-beta\.[0-9]$" | sort -V)
if [ -z "$tag_list" ]; then
echo "Warning: No tags found, using default version"
echo "$pkgname (0.0.1-1) stable; urgency=medium" > debian/changelog
echo "" >> debian/changelog
echo " * Initial release" >> debian/changelog
echo "" >> debian/changelog
echo " -- Local Build <build@localhost> $(date -R)" >> debian/changelog
else
prevtag=""
for tag in ${tag_list}; do
tag_header="$tag^..$tag"
tag_info=$prevtag..$tag
tag_version=$(echo $tag | cut -c2-)-1
if [[ "$prevtag" == "" ]]; then
tag_header="$tag"
tag_info="$tag"
elif [[ "$tag" == "$prevtag" ]]; then
continue
fi
echo >> changelog
git log --pretty="format: -- %aN <%aE> %aD%n%n" $tag_header >> changelog
git log --pretty=format:" * %s%n" $tag_info >> changelog
echo "" >> changelog
echo "$pkgname ($tag_version) stable; urgency=medium" >> changelog
prevtag=$tag
done
tac changelog > debian/changelog
fi
echo "Building package..."
dpkg-buildpackage -us -uc -b
echo "Generating checksums..."
cd ..
sha256sum *.deb > sha256sums 2>/dev/null || true
echo "Moving files to build output directory..."
mkdir -p /workspace/build
mv *.deb *.buildinfo *.changes sha256sums /workspace/build/ 2>/dev/null || true
echo "Build complete!"
echo ""
echo "Generated files:"
ls -lh /workspace/build/
'
echo ""
echo "Package built successfully!"
echo "Output files are in the build/ directory:"
ls -lh "$PROJECT_DIR"/build/*.deb 2>/dev/null || echo "No .deb files found"