From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id B7BBC1FF0EF for ; Sun, 02 Aug 2026 05:36:23 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 51CC8213F7; Sun, 02 Aug 2026 05:36:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=neatech-ar.20251104.gappssmtp.com; s=20251104; t=1785641772; x=1786246572; darn=lists.proxmox.com; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3wsqP4HHcehOr5kRN4Z1yZHLazvEn0zLsyHorC7pcV0=; b=q3Sta7t9xI7GT7EbyMCi6a4Vjfan2pEBUHVKE6y5hmZwhLOWImOCyu9kk+mZ7+pCJW EkJnpCsR8t9g4HuJ51PaZ0bapk4mfLYP42dxgwdD00kkWit1DVnSJKeA5H9aVta0i/xV 8SpXwC1kBRMPGkju9QvFqHn0EQTTr3Gnd0I1c3Sa3s9uduNavVp/FErpw0KiZ1R7nfEJ mxrD8NB+fybXZ6ugLH8h4zEWXy/EC7/Xy3X3BRCYCUXyVxeOYvJyuPBONo6dPoqfrbTE 63zh9NwOctE/I4mUJ2fXQiP4fPu3PxFXUaB8/25Axs1kj7QjFAwf2WdlsL3uMWv7dNPK IhCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785641772; x=1786246572; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=3wsqP4HHcehOr5kRN4Z1yZHLazvEn0zLsyHorC7pcV0=; b=D3wbznaHQSaG7hXo9dup/hmlEsnG+TlhTffjK/19bCuVaOGJxK8eh/956OiSnoo5oV 8O71V8gRHpGhTSjm0otdmwm7iAsAyX4KWPsMVESUHFumE8pWntWK1WgCtBKLaaxZ+vME K3pdUrZXsla2JZJ2gVq8d0YrCfbaBdzVeSyY3U5jazI4wcCFtUuSlcVsht6vknCw90pE F6yDD9zhzpctcP5RExA1iuYvwK0irarbyiKjWniNFRPdp2Odmbx2IF1AFjaZHGUb6byH OYzKPSqgr+RY0cNw5cAF4iEfa8+1YgADupuVAQ985F1YWGt/ky65bL7LO8Olmz2yYNtZ YX2A== X-Gm-Message-State: AOJu0YwEebnqm0Ox3AeNf7bU2ijatSQch3mKAn0G6uWLKnS/KdDcRxlh /zHYlICpAwH+GSbaeTNJB5+hP5MJS9/n5/fnR94e9F51DXhyuf5GCffFgWY67TZjJtZTg0f+bu8 kCiCiYQk= X-Gm-Gg: AR+sD12GEzU7S11q+oC9a9BU0GMpzwYwH6qZTedzRVoagRzQDiYL6UnvIkuIKqZ/dzo mY4k2usNlOwg0PaWiNpZenoe55l7Z7lftKo+Jcitj6w9damFgw/iLK5Jwo8uJ9j3mYwrjkxkpU7 7OUHWWJobwXFW0LXnUEvc7P59Fk0unTnFGs8h9bGXO7ZF+iasPYU9GpedSQW9MPZuo5KG2qi1Xt 2ccsflTofpxam4WZ4ChjX3GzLqtLf7QrzNtwrcbq0/VdRrwEYcZ+R3D0aYsrci0TdAN62oMH4+y mj0c2svncrsN8wD/FaIF32X4NumNlG/ZED0Nol+b9mGzwSUOLTKMox9gk7vRaYeVQ/t9pxgnLdD oiM57FH9nfD3ao9jzjV1W0PqVNIcQbi26ewxEtCJxzzA6sHGe6IEH2a2Hxf0WYNAhDlA6Mja6vG W6XES6RzWYzZ0c2uUn/M2tY+CTFEcYVqBNKQeDVntMYQxD9akxCy5a/NHxcwuZKSIUIKlBiQrIc AUBjNrzsbYCeqjDYIHuTVPoNqOB2H7Pr8Nq+FHIkWpqmviDYpJEpuY= X-Received: by 2002:a17:90b:3c50:b0:381:2788:a437 with SMTP id 98e67ed59e1d1-38fbc3ffa28mr6876121a91.1.1785641771978; Sat, 01 Aug 2026 20:36:11 -0700 (PDT) From: Joaquin Varela To: pve-devel@lists.proxmox.com Subject: [PATCH manager v2 1/3] ui: add ZFS over NVMe/TCP storage editor Date: Sun, 2 Aug 2026 00:35:32 -0300 Message-ID: X-Mailer: git-send-email 2.54.0.windows.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DMARC_PASS -0.1 DMARC pass policy RCVD_IN_DNSWL_NONE -0.0001 Sender listed at https://www.dnswl.org/, no trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: SY25VK5IQK7QDCKGIZLHIX2EDIOOGHXS X-Message-ID-Hash: SY25VK5IQK7QDCKGIZLHIX2EDIOOGHXS X-MailFrom: joaquinvarela@neatech.ar X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Joaquin Varela X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Register the zfsnvme storage type and add an ExtJS editor for its ZFS, NVMe/TCP, native multipath and DH-HMAC-CHAP properties. Keep immutable target identity fields read-only after creation. Expose portal-to-interface ordering so all cluster nodes use the intended independent data paths. Signed-off-by: Joaquin Varela --- www/manager6/Makefile | 1 + www/manager6/Utils.js | 6 ++ www/manager6/storage/ZFSNVMeEdit.js | 148 ++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 www/manager6/storage/ZFSNVMeEdit.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index eb0e9d9c..a93eb57b 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -375,6 +375,7 @@ JSSRC= \ storage/Summary.js \ storage/TemplateView.js \ storage/ZFSEdit.js \ + storage/ZFSNVMeEdit.js \ storage/ZFSPoolEdit.js \ storage/ESXIEdit.js \ Workspace.js \ diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index 040b5ae0..82b9ecae 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -880,6 +880,12 @@ Ext.define('PVE.Utils', { faIcon: 'building', backups: false, }, + zfsnvme: { + name: 'ZFS over NVMe/TCP', + ipanel: 'ZFSNVMeInputPanel', + faIcon: 'building', + backups: false, + }, zfspool: { name: 'ZFS', ipanel: 'ZFSPoolInputPanel', diff --git a/www/manager6/storage/ZFSNVMeEdit.js b/www/manager6/storage/ZFSNVMeEdit.js new file mode 100644 index 00000000..db6e559f --- /dev/null +++ b/www/manager6/storage/ZFSNVMeEdit.js @@ -0,0 +1,148 @@ +Ext.define('PVE.storage.ZFSNVMeInputPanel', { + extend: 'PVE.panel.StorageBase', + + onlineHelp: 'storage_zfsnvme', + + onGetValues: function (values) { + if (this.isCreate) { + values.content = 'images'; + } + return this.callParent([values]); + }, + + initComponent: function () { + let me = this; + + me.type = 'zfsnvme'; + + me.column1 = [ + { + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'server', + fieldLabel: gettext('SSH Server'), + allowBlank: false, + }, + { + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'pool', + fieldLabel: gettext('ZFS Pool'), + emptyText: 'tank/pve-nvme', + allowBlank: false, + }, + { + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'subsysnqn', + fieldLabel: gettext('Subsystem NQN'), + emptyText: 'nqn.2026-07.example:pve-storage', + allowBlank: false, + }, + { + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'blocksize', + value: '16k', + fieldLabel: gettext('Block Size'), + validator: PVE.Utils.validateZfsBlocksize, + allowBlank: false, + }, + { + xtype: 'proxmoxcheckbox', + name: 'sparse', + checked: true, + uncheckedValue: 0, + fieldLabel: gettext('Thin provision'), + }, + ]; + + me.column2 = [ + { + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'nvme-portals', + fieldLabel: gettext('NVMe/TCP Portals'), + emptyText: '10.90.1.11:4420,10.90.2.11:4420', + allowBlank: false, + }, + { + xtype: 'textfield', + name: 'nvme-host-ifaces', + fieldLabel: gettext('Host Interfaces'), + emptyText: 'ens20,ens21', + allowBlank: false, + }, + { + xtype: me.isCreate ? 'textfield' : 'displayfield', + inputType: me.isCreate ? 'password' : 'text', + name: 'dhchap-key', + value: me.isCreate ? '' : gettext('Configured'), + submitValue: me.isCreate, + fieldLabel: gettext('DHCHAP Key'), + allowBlank: !me.isCreate, + }, + { + xtype: 'proxmoxKVComboBox', + name: 'nvme-iopolicy', + value: 'round-robin', + fieldLabel: gettext('I/O Policy'), + comboItems: [ + ['round-robin', 'round-robin'], + ['queue-depth', 'queue-depth'], + ['numa', 'numa'], + ], + allowBlank: false, + }, + ]; + + me.advancedColumn1 = [ + { + xtype: 'proxmoxintegerfield', + name: 'nvme-keep-alive-tmo', + value: 5, + minValue: 1, + maxValue: 120, + fieldLabel: gettext('Keep Alive Timeout'), + allowBlank: false, + }, + { + xtype: 'proxmoxintegerfield', + name: 'nvme-reconnect-delay', + value: 2, + minValue: 1, + maxValue: 120, + fieldLabel: gettext('Reconnect Delay'), + allowBlank: false, + }, + ]; + + me.advancedColumn2 = [ + { + xtype: 'proxmoxintegerfield', + name: 'nvme-ctrl-loss-tmo', + value: 600, + minValue: -1, + maxValue: 86400, + fieldLabel: gettext('Controller Loss Timeout'), + allowBlank: false, + }, + { + xtype: 'proxmoxintegerfield', + name: 'nvme-nr-io-queues', + minValue: 1, + maxValue: 1024, + fieldLabel: gettext('I/O Queues'), + deleteEmpty: !me.isCreate, + allowBlank: true, + }, + ]; + + me.columnB = [ + { + xtype: 'displayfield', + userCls: 'pmx-hint', + value: gettext( + 'Host interface names are matched to portals by position and must exist on every selected node.', + ), + }, + ]; + + me.callParent(); + }, +}); -- 2.54.0.windows.1