Hi,
We completed a full lifecycle test of 3.0.0-beta3. Summary: the critical LXC create bug is FIXED — thank you. Four issues remain, all reproducible; literal (masked) HTTP evidence is in the appendix at the end. This is our second full evidence report.
=== ENVIRONMENT ===
- Module: TZ Proxmox VE 3.0.0 (beta3 zip, files dated up to 2026-08-12)
- WHMCS 9.0.4 — PHP 8.3 (web) / 8.1 (cron), ionCube OK, lazy DB migration ran cleanly
- Proxmox VE: pve-manager 9.2.10, kernel 7.0.14-12-pve, single node
- Product: LXC, unprivileged, provisioned from a CT template + vztmpl, rootfs on a custom ZFS pool (not "local")
- Module ↔ PVE: DIRECT https on :8006, API token auth — no proxy/middleware in the path
=== CONFIRMED FIXED — LXC Create ===
POST /nodes/{node}/lxc → 200; task vzcreate OK with zero warnings; correct veth/gateway config; rootfs on the custom pool; template extracted; container started via start=1. In 2.1.2 this same call failed 400 (QEMU-only params). Clean work.
=== ISSUE 1 — Inventory sync is destructive and LXC-blind ===
(a) Templates "Refresh Library" only calls GET /nodes/{node}/qemu — it never calls GET /nodes/{node}/lxc — so LXC CT templates are invisible AND pre-existing LXC template rows are DELETED from mod_tzproxmox_templates by the sync.
(b) ISO sync reads GET /nodes/{node}/storage/{storage}/content but filters out type=vztmpl; our vztmpl row in mod_tzproxmox_isos was deleted ("No images found") even though pvesm lists it.
(c) Node sync ("Sync All Clusters") resets storage_pool back to "local", discarding the configured custom pool (backup_storage is preserved — the reset is selective).
Suggested fix: include GET /lxc (template==1) in template sync; include vztmpl in image sync; never overwrite a non-empty storage_pool.
=== ISSUE 2 — Change Password uses a non-existent LXC API ===
Admin "Change Password" fires PUT /nodes/{node}/lxc/{vmid}/config with a "password" property → 400 "property is not defined in schema..." (2× reproducible; root password hash inside the CT verified unchanged). Note: in PVE, "password" exists ONLY at container creation; there is NO API to change the root password of an existing CT (unlike QEMU's agent/set-user-password). A real fix needs host-side execution (e.g. pct exec ... chpasswd — perhaps via your console helper service), or the button should be disabled for LXC with a clear message.
=== ISSUE 3 — Client console: the shipped helper is never used ===
The client-area console flow works up to the last hop: POST /access/ticket (novnc user) → POST /lxc/{vmid}/vncproxy 200; then the BROWSER is sent to wss://{host}:{API port}/api2/json/.../vncwebsocket?port=...&vncticket=... → 401, because the websocket upgrade also requires a PVEAuthCookie the browser does not have. We installed your proxmox-console-helper 1.1.0 on the node (listening on 8787, /health OK): ZERO connections ever reach it, and a grep of the entire module tree finds no reference to "8787" or "/tzproxmox-console" anywhere — the module never targets the helper it ships with. How is the helper supposed to be wired to the module? Missing setting, or integration not implemented yet in beta3?
=== ISSUE 4 — Suspend/Unsuspend silently lose a config write ===
Both actions fire POST /nodes/{node}/lxc/{vmid}/config → 501 Not Implemented (LXC config changes require PUT; POST is the QEMU pattern) right before the successful status/stop / status/start. Whatever that write intends is silently lost. Practical impact: onboot stays 1 on a suspended container — after a node reboot, a suspended (e.g. unpaid) container COMES BACK ONLINE while WHMCS still shows Suspended. Suggested fix: PUT onboot=0 (and optionally a lock/tag) on suspend; restore on unsuspend.
=== MINOR ===
- Terminate works cleanly (stop → DELETE, CT destroyed, IP released) but the row in mod_tzproxmox_service_data is not removed.
- Admin-area "Open Console" opens a bare deep-link to the PVE GUI login page — probably not intended.
- Auto-generated hostname on create ("IP-x.x.x.x-...-PID-nnnn") is not a valid/clean hostname pattern.
On the positive side: the lazy migration created the new IP tables and backfilled block_id correctly, and the tokenized noVNC gateway with expiration is the right design — it just needs the helper wiring.
LICENSE — We are mid-validation and the trial clock keeps expiring on us. Given the scope of QA we are providing (second full evidence report), could you set us up with a proper beta/NFR license so we can validate your fixes as you ship them?
Best regards,
Ricardo Auada — WFree / Webcenter
=== EVIDENCE APPENDIX (pveproxy access log, tickets masked; times BRT 18/Aug/2026) ===
A) CREATE (fixed):
15:30:19 GET /api2/json/cluster/nextid?vmid=2000 → 200
15:30:19 GET /api2/json/nodes/pve-br01/qemu/2000/config → 500 (vmid-free probe)
15:30:19 GET /api2/json/nodes/pve-br01/lxc/2000/config → 500 (vmid-free probe)
15:30:19 POST /api2/json/nodes/pve-br01/lxc → 200
Task: UPID:...:vzcreate:2000:whmcs@pve!...: OK (no warnings). Resulting config: net0 veth ip/gw correct, rootfs on custom zfspool, unprivileged=1, running (start=1).
B) SYNC (issue 1):
11:21:28 GET /api2/json/nodes/pve-br01/qemu → 200 (Templates refresh; no GET /lxc at any point → LXC template row deleted)
11:21:55 GET /api2/json/nodes/pve-br01/storage → 200
11:21:55 GET /api2/json/nodes/pve-br01/storage/local/content → 200 (vztmpl filtered out → row deleted; UI "No images found")
11:22:34 Nodes "Sync All Clusters" → storage_pool reset custom→"local" (backup_storage preserved)
C) CHANGE PASSWORD (issue 2):
15:37:30 PUT /api2/json/nodes/pve-br01/lxc/2000/config → 400
15:37:46 PUT /api2/json/nodes/pve-br01/lxc/2000/config → 400
UI: Proxmox API Error (400): {"password":"property is not defined in schema and the schema does not allow additional properties"}
D) CLIENT CONSOLE (issue 3):
16:16:18 POST /api2/json/access/ticket → 200 (server-side, novnc user)
16:16:19 POST /api2/json/nodes/pve-br01/lxc/2000/vncproxy → 200 (server-side)
16:16:19 browser GET /api2/json/nodes/pve-br01/lxc/2000/vncwebsocket?port=5901&vncticket=[MASKED] → 401
16:16:48 idem → 401 ; 16:16:53 idem → 401
Helper 1.1.0 on :8787: zero connections (socket + journal). grep of module tree: no "8787" / "tzproxmox-console" outside the installer script.
E) SUSPEND / UNSUSPEND (issue 4):
16:24:09 POST /api2/json/nodes/pve-br01/lxc/2000/config → 501 (suspend)
16:24:09 POST /api2/json/nodes/pve-br01/lxc/2000/status/stop → 200
16:24:52 POST /api2/json/nodes/pve-br01/lxc/2000/config → 501 (unsuspend)
16:24:52 POST /api2/json/nodes/pve-br01/lxc/2000/status/start → 200
onboot verified =1 while suspended.
F) TERMINATE (works; minor residue):
16:26:54 POST /api2/json/nodes/pve-br01/lxc/2000/status/stop → 200
16:26:57 DELETE /api2/json/nodes/pve-br01/lxc/2000 → 200
IP released in mod_tzproxmox_ips; mod_tzproxmox_service_data row for the service NOT removed.
Raw logs and task files available on request.