diff --git a/pve-manager/js/pvemanagerlib-8.0.5_1.js.patch b/pve-manager/js/pvemanagerlib-8.0.5_1.js.patch new file mode 100644 index 0000000..e01515f --- /dev/null +++ b/pve-manager/js/pvemanagerlib-8.0.5_1.js.patch @@ -0,0 +1,286 @@ +--- pvemanagerlib.js.orig 2024-01-06 14:50:39.890252726 -0500 ++++ pvemanagerlib.js 2024-01-06 15:51:53.708260622 -0500 +@@ -9228,6 +9228,7 @@ + alias: ['widget.pveiScsiProviderSelector'], + comboItems: [ + ['comstar', 'Comstar'], ++ ['freenas', 'FreeNAS/TrueNAS API'], + ['istgt', 'istgt'], + ['iet', 'IET'], + ['LIO', 'LIO'], +@@ -58017,16 +58018,23 @@ + me.callParent(); + }, + }); ++ + Ext.define('PVE.storage.ZFSInputPanel', { + extend: 'PVE.panel.StorageBase', +- + viewModel: { +- parent: null, +- data: { +- isLIO: false, +- isComstar: true, +- hasWriteCacheOption: true, +- }, ++ parent: null, ++ data: { ++ isComstar: true, ++ isFreeNAS: false, ++ isLIO: false, ++ isToken: false, ++ hasWriteCacheOption: true, ++ }, ++ formulas: { ++ hideUsername: function(get) { ++ return (!get('isFreeNAS') || !(get('isFreeNAS') && !get('isToken'))); ++ }, ++ }, + }, + + controller: { +@@ -58035,12 +58043,41 @@ + 'field[name=iscsiprovider]': { + change: 'changeISCSIProvider', + }, ++ 'field[name=truenas_token_auth]': { ++ change: 'changeUsername', ++ }, + }, + changeISCSIProvider: function(f, newVal, oldVal) { ++ var me = this; + var vm = this.getViewModel(); + vm.set('isLIO', newVal === 'LIO'); + vm.set('isComstar', newVal === 'comstar'); +- vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'istgt'); ++ vm.set('isFreeNAS', newVal === 'freenas'); ++ vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'freenas' || newVal === 'istgt'); ++ if (newVal !== 'freenas') { ++ me.lookupReference('freenas_use_ssl_field').setValue(false); ++ me.lookupReference('truenas_token_auth_field').setValue(false); ++ me.lookupReference('freenas_apiv4_host_field').setValue(''); ++ me.lookupReference('freenas_user_field').setValue(''); ++ me.lookupReference('freenas_user_field').allowBlank = true; ++ me.lookupReference('truenas_secret_field').setValue(''); ++ me.lookupReference('truenas_secret_field').allowBlank = true; ++ me.lookupReference('truenas_confirm_secret_field').setValue(''); ++ me.lookupReference('truenas_confirm_secret_field').allowBlank = true; ++ } else { ++ me.lookupReference('freenas_user_field').allowBlank = false; ++ me.lookupReference('truenas_secret_field').allowBlank = false; ++ me.lookupReference('truenas_confirm_secret_field').allowBlank = false; ++ } ++ }, ++ changeUsername: function(f, newVal, oldVal) { ++ var me = this; ++ var vm = me.getViewModel(); ++ vm.set('isToken', newVal); ++ me.lookupReference('freenas_user_field').allowBlank = newVal; ++ if (newVal) { ++ me.lookupReference('freenas_user_field').setValue(''); ++ } + }, + }, + +@@ -58053,18 +58090,68 @@ + + values.nowritecache = values.writecache ? 0 : 1; + delete values.writecache; ++ console.warn(values.freenas_password); ++ if (values.freenas_password) { ++ values.truenas_secret = values.freenas_password; ++ } ++ console.warn(values.truenas_secret); + + return me.callParent([values]); + }, + + setValues: function(values) { +- values.writecache = values.nowritecache ? 0 : 1; +- this.callParent([values]); ++ if (values.freenas_password) { ++ values.truenas_secret = values.freenas_password; ++ } ++ values.truenas_confirm_secret = values.truenas_secret; ++ values.writecache = values.nowritecache ? 0 : 1; ++ this.callParent([values]); + }, + + initComponent: function() { + var me = this; + ++ var tnsecret = Ext.create('Ext.form.TextField', { ++ xtype: 'proxmoxtextfield', ++ name: 'truenas_secret', ++ reference: 'truenas_secret_field', ++ inputType: me.isCreate ? '' : 'password', ++ value: '', ++ editable: true, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('API Password'), ++ change: function(f, value) { ++ if (f.rendered) { ++ f.up().down('field[name=truenas_confirm_secret]').validate(); ++ } ++ }, ++ }); ++ ++ var tnconfirmsecret = Ext.create('Ext.form.TextField', { ++ xtype: 'proxmoxtextfield', ++ name: 'truenas_confirm_secret', ++ reference: 'truenas_confirm_secret_field', ++ inputType: me.isCreate ? '' : 'password', ++ value: '', ++ editable: true, ++ submitValue: false, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('Confirm API Password'), ++ validator: function(value) { ++ var pw = me.up().down('field[name=truenas_secret]').getValue(); ++ if (pw !== value) { ++ return "Secrets do not match!"; ++ } ++ return true; ++ }, ++ }); ++ + me.column1 = [ + { + xtype: me.isCreate ? 'textfield' : 'displayfield', +@@ -58074,7 +58161,7 @@ + allowBlank: false, + }, + { +- xtype: me.isCreate ? 'textfield' : 'displayfield', ++ xtype: 'textfield', + name: 'pool', + value: '', + fieldLabel: gettext('Pool'), +@@ -58084,11 +58171,11 @@ + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'blocksize', + value: '4k', +- fieldLabel: gettext('Block Size'), ++ fieldLabel: gettext('ZFS Block Size'), + allowBlank: false, + }, + { +- xtype: me.isCreate ? 'textfield' : 'displayfield', ++ xtype: 'textfield', + name: 'target', + value: '', + fieldLabel: gettext('Target'), +@@ -58099,9 +58186,60 @@ + name: 'comstar_tg', + value: '', + fieldLabel: gettext('Target group'), +- bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' }, ++ bind: { ++ hidden: '{!isComstar}' ++ }, + allowBlank: true, + }, ++ { ++ xtype: 'proxmoxcheckbox', ++ name: 'freenas_use_ssl', ++ reference: 'freenas_use_ssl_field', ++ inputId: 'freenas_use_ssl_field', ++ checked: false, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ uncheckedValue: 0, ++ fieldLabel: gettext('API use SSL'), ++ }, ++ { ++ xtype: 'proxmoxcheckbox', ++ name: 'truenas_token_auth', ++ reference: 'truenas_token_auth_field', ++ inputId: 'truenas_use_token_auth_field', ++ checked: false, ++ listeners: { ++ change: function(field, newValue) { ++ if (newValue === true) { ++ tnsecret.labelEl.update('API Token'); ++ tnconfirmsecret.labelEl.update('Confirm API Token'); ++ me.lookupReference('freenas_user_field').setValue(''); ++ me.lookupReference('freenas_user_field').allowBlank = true; ++ } else { ++ tnsecret.labelEl.update('API Password'); ++ tnconfirmsecret.labelEl.update('Confirm API Password'); ++ me.lookupReference('freenas_user_field').allowBlank = false; ++ } ++ }, ++ }, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ uncheckedValue: 0, ++ fieldLabel: gettext('API Token Auth'), ++ }, ++ { ++ xtype: 'textfield', ++ name: 'freenas_user', ++ reference: 'freenas_user_field', ++ inputId: 'freenas_user_field', ++ value: '', ++ fieldLabel: gettext('API Username'), ++ bind: { ++ hidden: '{hideUsername}' ++ }, ++ }, + ]; + + me.column2 = [ +@@ -58131,7 +58269,9 @@ + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'comstar_hg', + value: '', +- bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' }, ++ bind: { ++ hidden: '{!isComstar}' ++ }, + fieldLabel: gettext('Host group'), + allowBlank: true, + }, +@@ -58139,15 +58279,32 @@ + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'lio_tpg', + value: '', +- bind: me.isCreate ? { disabled: '{!isLIO}' } : { hidden: '{!isLIO}' }, +- allowBlank: false, ++ bind: { ++ hidden: '{!isLIO}' ++ }, + fieldLabel: gettext('Target portal group'), ++ allowBlank: true ++ }, ++ { ++ xtype: 'proxmoxtextfield', ++ name: 'freenas_apiv4_host', ++ reference: 'freenas_apiv4_host_field', ++ value: '', ++ editable: true, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('API IPv4 Host'), + }, ++ tnsecret, ++ tnconfirmsecret, + ]; + + me.callParent(); + }, + }); ++ + Ext.define('PVE.storage.ZFSPoolSelector', { + extend: 'PVE.form.ComboBoxSetStoreNode', + alias: 'widget.pveZFSPoolSelector', diff --git a/pve-manager/js/pvemanagerlib.js.patch b/pve-manager/js/pvemanagerlib.js.patch index 9fa45ec..e01515f 100644 --- a/pve-manager/js/pvemanagerlib.js.patch +++ b/pve-manager/js/pvemanagerlib.js.patch @@ -1,88 +1,92 @@ ---- pvemanagerlib.js.orig 2023-12-30 15:36:27.913505863 -0500 -+++ pvemanagerlib.js 2024-01-02 09:30:56.000000000 -0500 +--- pvemanagerlib.js.orig 2024-01-06 14:50:39.890252726 -0500 ++++ pvemanagerlib.js 2024-01-06 15:51:53.708260622 -0500 @@ -9228,6 +9228,7 @@ alias: ['widget.pveiScsiProviderSelector'], comboItems: [ ['comstar', 'Comstar'], -+ ['freenas', 'FreeNAS/TrueNAS API'], ++ ['freenas', 'FreeNAS/TrueNAS API'], ['istgt', 'istgt'], ['iet', 'IET'], ['LIO', 'LIO'], -@@ -58017,16 +58018,24 @@ +@@ -58017,16 +58018,23 @@ me.callParent(); }, }); + Ext.define('PVE.storage.ZFSInputPanel', { extend: 'PVE.panel.StorageBase', - +- viewModel: { - parent: null, - data: { -+isComstar: true, -+ isFreeNAS: false, - isLIO: false, +- parent: null, +- data: { +- isLIO: false, - isComstar: true, -+ isToken: false, - hasWriteCacheOption: true, - }, -+formulas: { -+ hideUsername: function(get) { -+ return (!get('isFreeNAS') || !(get('isFreeNAS') && !get('isToken'))); -+ }, -+ }, +- hasWriteCacheOption: true, +- }, ++ parent: null, ++ data: { ++ isComstar: true, ++ isFreeNAS: false, ++ isLIO: false, ++ isToken: false, ++ hasWriteCacheOption: true, ++ }, ++ formulas: { ++ hideUsername: function(get) { ++ return (!get('isFreeNAS') || !(get('isFreeNAS') && !get('isToken'))); ++ }, ++ }, }, controller: { -@@ -58034,13 +58043,42 @@ - control: { +@@ -58035,12 +58043,41 @@ 'field[name=iscsiprovider]': { change: 'changeISCSIProvider', -+}, + }, + 'field[name=truenas_token_auth]': { + change: 'changeUsername', - }, ++ }, }, changeISCSIProvider: function(f, newVal, oldVal) { -+var me = this; ++ var me = this; var vm = this.getViewModel(); vm.set('isLIO', newVal === 'LIO'); vm.set('isComstar', newVal === 'comstar'); - vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'istgt'); + vm.set('isFreeNAS', newVal === 'freenas'); -+ vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'freenas' || newVal === 'istgt'); -+ if (newVal !== 'freenas') { -+ me.lookupReference('freenas_use_ssl_field').setValue(false); -+ me.lookupReference('truenas_token_auth_field').setValue(false); -+ me.lookupReference('freenas_apiv4_host_field').setValue(''); -+ me.lookupReference('freenas_user_field').setValue(''); -+ me.lookupReference('freenas_user_field').allowBlank = true; -+ me.lookupReference('truenas_secret_field').setValue(''); -+ me.lookupReference('truenas_secret_field').allowBlank = true; -+ me.lookupReference('truenas_confirm_secret_field').setValue(''); -+ me.lookupReference('truenas_confirm_secret_field').allowBlank = true; -+ } else { -+ me.lookupReference('freenas_user_field').allowBlank = false; -+ me.lookupReference('truenas_secret_field').allowBlank = false; -+ me.lookupReference('truenas_confirm_secret_field').allowBlank = false; -+ } -+ }, -+ changeUsername: function(f, newVal, oldVal) { -+ var me = this; -+ var vm = me.getViewModel(); -+ vm.set('isToken', newVal); -+ me.lookupReference('freenas_user_field').allowBlank = newVal; -+ if (newVal) { -+ me.lookupReference('freenas_user_field').setValue(''); -+ } ++ vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'freenas' || newVal === 'istgt'); ++ if (newVal !== 'freenas') { ++ me.lookupReference('freenas_use_ssl_field').setValue(false); ++ me.lookupReference('truenas_token_auth_field').setValue(false); ++ me.lookupReference('freenas_apiv4_host_field').setValue(''); ++ me.lookupReference('freenas_user_field').setValue(''); ++ me.lookupReference('freenas_user_field').allowBlank = true; ++ me.lookupReference('truenas_secret_field').setValue(''); ++ me.lookupReference('truenas_secret_field').allowBlank = true; ++ me.lookupReference('truenas_confirm_secret_field').setValue(''); ++ me.lookupReference('truenas_confirm_secret_field').allowBlank = true; ++ } else { ++ me.lookupReference('freenas_user_field').allowBlank = false; ++ me.lookupReference('truenas_secret_field').allowBlank = false; ++ me.lookupReference('truenas_confirm_secret_field').allowBlank = false; ++ } ++ }, ++ changeUsername: function(f, newVal, oldVal) { ++ var me = this; ++ var vm = me.getViewModel(); ++ vm.set('isToken', newVal); ++ me.lookupReference('freenas_user_field').allowBlank = newVal; ++ if (newVal) { ++ me.lookupReference('freenas_user_field').setValue(''); ++ } }, }, -@@ -58053,28 +58091,78 @@ +@@ -58053,18 +58090,68 @@ values.nowritecache = values.writecache ? 0 : 1; delete values.writecache; -+ console.warn(values.freenas_password); ++ console.warn(values.freenas_password); + if (values.freenas_password) { + values.truenas_secret = values.freenas_password; + } @@ -103,60 +107,53 @@ }, initComponent: function() { -- var me = this; -+ var me = this; -+ -+ var tnsecret = Ext.create('Ext.form.TextField', { -+ xtype: 'proxmoxtextfield', -+ name: 'truenas_secret', -+ reference: 'truenas_secret_field', -+ inputType: me.isCreate ? '' : 'password', -+ value: '', -+ editable: true, -+ emptyText: Proxmox.Utils.noneText, -+ bind: { -+ hidden: '{!isFreeNAS}' -+ }, -+ fieldLabel: gettext('API Password'), -+ change: function(f, value) { -+ if (f.rendered) { -+ f.up().down('field[name=truenas_confirm_secret]').validate(); -+ } -+ }, -+ }); + var me = this; -- me.column1 = [ -- { -- xtype: me.isCreate ? 'textfield' : 'displayfield', -- name: 'portal', -+ var tnconfirmsecret = Ext.create('Ext.form.TextField', { -+ xtype: 'proxmoxtextfield', -+ name: 'truenas_confirm_secret', -+ reference: 'truenas_confirm_secret_field', -+ inputType: me.isCreate ? '' : 'password', -+ value: '', -+ editable: true, -+ submitValue: false, -+ emptyText: Proxmox.Utils.noneText, -+ bind: { -+ hidden: '{!isFreeNAS}' -+ }, -+ fieldLabel: gettext('Confirm API Password'), -+ validator: function(value) { -+ var pw = me.up().down('field[name=truenas_secret]').getValue(); -+ if (pw !== value) { -+ return "Secrets do not match!"; -+ } -+ return true; -+ }, -+ }); ++ var tnsecret = Ext.create('Ext.form.TextField', { ++ xtype: 'proxmoxtextfield', ++ name: 'truenas_secret', ++ reference: 'truenas_secret_field', ++ inputType: me.isCreate ? '' : 'password', ++ value: '', ++ editable: true, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('API Password'), ++ change: function(f, value) { ++ if (f.rendered) { ++ f.up().down('field[name=truenas_confirm_secret]').validate(); ++ } ++ }, ++ }); + -+ me.column1 = [ -+ { -+ xtype: me.isCreate ? 'textfield' : 'displayfield', -+ name: 'portal', - value: '', - fieldLabel: gettext('Portal'), ++ var tnconfirmsecret = Ext.create('Ext.form.TextField', { ++ xtype: 'proxmoxtextfield', ++ name: 'truenas_confirm_secret', ++ reference: 'truenas_confirm_secret_field', ++ inputType: me.isCreate ? '' : 'password', ++ value: '', ++ editable: true, ++ submitValue: false, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('Confirm API Password'), ++ validator: function(value) { ++ var pw = me.up().down('field[name=truenas_secret]').getValue(); ++ if (pw !== value) { ++ return "Secrets do not match!"; ++ } ++ return true; ++ }, ++ }); ++ + me.column1 = [ + { + xtype: me.isCreate ? 'textfield' : 'displayfield', +@@ -58074,7 +58161,7 @@ allowBlank: false, }, { @@ -165,7 +162,7 @@ name: 'pool', value: '', fieldLabel: gettext('Pool'), -@@ -58084,11 +58172,11 @@ +@@ -58084,11 +58171,11 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'blocksize', value: '4k', @@ -179,7 +176,7 @@ name: 'target', value: '', fieldLabel: gettext('Target'), -@@ -58099,8 +58187,59 @@ +@@ -58099,9 +58186,60 @@ name: 'comstar_tg', value: '', fieldLabel: gettext('Target group'), @@ -188,7 +185,7 @@ + hidden: '{!isComstar}' + }, allowBlank: true, -+}, + }, + { + xtype: 'proxmoxcheckbox', + name: 'freenas_use_ssl', @@ -237,10 +234,11 @@ + bind: { + hidden: '{hideUsername}' + }, - }, ++ }, ]; -@@ -58131,7 +58270,9 @@ + me.column2 = [ +@@ -58131,7 +58269,9 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'comstar_hg', value: '', @@ -251,19 +249,18 @@ fieldLabel: gettext('Host group'), allowBlank: true, }, -@@ -58139,15 +58280,32 @@ +@@ -58139,15 +58279,32 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'lio_tpg', value: '', - bind: me.isCreate ? { disabled: '{!isLIO}' } : { hidden: '{!isLIO}' }, - allowBlank: false, -- fieldLabel: gettext('Target portal group'), + bind: { + hidden: '{!isLIO}' + }, -+ fieldLabel: gettext('Target portal group'), -+ allowBlank: true - }, + fieldLabel: gettext('Target portal group'), ++ allowBlank: true ++ }, + { + xtype: 'proxmoxtextfield', + name: 'freenas_apiv4_host', @@ -275,7 +272,7 @@ + hidden: '{!isFreeNAS}' + }, + fieldLabel: gettext('API IPv4 Host'), -+ }, + }, + tnsecret, + tnconfirmsecret, ];