From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 636BD77ECE for ; Mon, 25 Oct 2021 15:48:42 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 6632023893 for ; Mon, 25 Oct 2021 15:48:11 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id F3B232364F for ; Mon, 25 Oct 2021 15:48:00 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id C8A9045F73 for ; Mon, 25 Oct 2021 15:48:00 +0200 (CEST) From: Fabian Ebner To: pve-devel@lists.proxmox.com Date: Mon, 25 Oct 2021 15:47:53 +0200 Message-Id: <20211025134755.169491-11-f.ebner@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211025134755.169491-1-f.ebner@proxmox.com> References: <20211025134755.169491-1-f.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.260 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager 4/6] ui: node: add destroy menu for directory, lvm, lvmthin, zfs X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Oct 2021 13:48:42 -0000 Signed-off-by: Fabian Ebner --- Dependency bump for pve-storage needed. www/manager6/node/Directory.js | 82 ++++++++++++++++++++++++++++++ www/manager6/node/LVM.js | 83 ++++++++++++++++++++++++++++++ www/manager6/node/LVMThin.js | 93 ++++++++++++++++++++++++++++++++++ www/manager6/node/ZFS.js | 81 ++++++++++++++++++++++++++++- 4 files changed, 337 insertions(+), 2 deletions(-) diff --git a/www/manager6/node/Directory.js b/www/manager6/node/Directory.js index 67f56870..c3dba2ef 100644 --- a/www/manager6/node/Directory.js +++ b/www/manager6/node/Directory.js @@ -63,6 +63,43 @@ Ext.define('PVE.node.Directorylist', { extend: 'Ext.grid.Panel', xtype: 'pveDirectoryList', + viewModel: { + data: { + path: '', + }, + formulas: { + dirName: (get) => get('path')?.replace('/mnt/pve/', '') || undefined, + }, + }, + + controller: { + xclass: 'Ext.app.ViewController', + + destroyDirectory: function() { + let me = this; + let vm = me.getViewModel(); + let view = me.getView(); + + const dirName = vm.get('dirName'); + + if (!view.nodename) { + throw "no node name specified"; + } + + if (!dirName) { + throw "no directory name specified"; + } + + Ext.create('Proxmox.window.SafeDestroy', { + url: `/nodes/${view.nodename}/disks/directory/${dirName}`, + item: { id: dirName }, + showProgress: true, + taskName: 'dirremove', + taskDone: () => { view.reload(); }, + }).show(); + }, + }, + stateful: true, stateId: 'grid-node-directory', columns: [ @@ -117,6 +154,45 @@ Ext.define('PVE.node.Directorylist', { }); }, }, + '->', + { + xtype: 'tbtext', + data: { + dirName: undefined, + }, + bind: { + data: { + dirName: "{dirName}", + }, + }, + tpl: [ + '', + gettext('Directory') + ' {dirName}:', + '', + Ext.String.format(gettext('No {0} selected'), gettext('directory')), + '', + ], + }, + { + text: gettext('More'), + iconCls: 'fa fa-bars', + disabled: true, + bind: { + disabled: '{!dirName}', + }, + menu: [ + { + text: gettext('Destroy'), + itemId: 'remove', + iconCls: 'fa fa-fw fa-trash-o', + handler: 'destroyDirectory', + disabled: true, + bind: { + disabled: '{!dirName}', + }, + }, + ], + }, ], reload: function() { @@ -129,6 +205,12 @@ Ext.define('PVE.node.Directorylist', { activate: function() { this.reload(); }, + selectionchange: function(model, selected) { + let me = this; + let vm = me.getViewModel(); + + vm.set('path', selected[0]?.data.path || ''); + }, }, initComponent: function() { diff --git a/www/manager6/node/LVM.js b/www/manager6/node/LVM.js index 4b5225d8..70ddf451 100644 --- a/www/manager6/node/LVM.js +++ b/www/manager6/node/LVM.js @@ -52,6 +52,40 @@ Ext.define('PVE.node.LVMList', { extend: 'Ext.tree.Panel', xtype: 'pveLVMList', + viewModel: { + data: { + volumeGroup: '', + }, + }, + + controller: { + xclass: 'Ext.app.ViewController', + + destroyVolumeGroup: function() { + let me = this; + let vm = me.getViewModel(); + let view = me.getView(); + + const volumeGroup = vm.get('volumeGroup'); + + if (!view.nodename) { + throw "no node name specified"; + } + + if (!volumeGroup) { + throw "no volume group specified"; + } + + Ext.create('Proxmox.window.SafeDestroy', { + url: `/nodes/${view.nodename}/disks/lvm/${volumeGroup}`, + item: { id: volumeGroup }, + showProgress: true, + taskName: 'lvmremove', + taskDone: () => { view.reload(); }, + }).show(); + }, + }, + emptyText: gettext('No Volume Groups found'), stateful: true, @@ -120,6 +154,45 @@ Ext.define('PVE.node.LVMList', { }); }, }, + '->', + { + xtype: 'tbtext', + data: { + volumeGroup: undefined, + }, + bind: { + data: { + volumeGroup: "{volumeGroup}", + }, + }, + tpl: [ + '', + 'Volume group {volumeGroup}:', + '', + Ext.String.format(gettext('No {0} selected'), 'volume group'), + '', + ], + }, + { + text: gettext('More'), + iconCls: 'fa fa-bars', + disabled: true, + bind: { + disabled: '{!volumeGroup}', + }, + menu: [ + { + text: gettext('Destroy'), + itemId: 'remove', + iconCls: 'fa fa-fw fa-trash-o', + handler: 'destroyVolumeGroup', + disabled: true, + bind: { + disabled: '{!volumeGroup}', + }, + }, + ], + }, ], reload: function() { @@ -142,6 +215,16 @@ Ext.define('PVE.node.LVMList', { activate: function() { this.reload(); }, + selectionchange: function(model, selected) { + let me = this; + let vm = me.getViewModel(); + + if (selected.length < 1 || selected[0].data.parentId !== 'root') { + vm.set('volumeGroup', ''); + } else { + vm.set('volumeGroup', selected[0].data.name); + } + }, }, selModel: 'treemodel', diff --git a/www/manager6/node/LVMThin.js b/www/manager6/node/LVMThin.js index 4a0b21ba..ca32bb3b 100644 --- a/www/manager6/node/LVMThin.js +++ b/www/manager6/node/LVMThin.js @@ -50,6 +50,47 @@ Ext.define('PVE.node.LVMThinList', { extend: 'Ext.grid.Panel', xtype: 'pveLVMThinList', + viewModel: { + data: { + thinPool: '', + volumeGroup: '', + }, + }, + + controller: { + xclass: 'Ext.app.ViewController', + + destroyThinPool: function() { + let me = this; + let vm = me.getViewModel(); + let view = me.getView(); + + const thinPool = vm.get('thinPool'); + const volumeGroup = vm.get('volumeGroup'); + + if (!view.nodename) { + throw "no node name specified"; + } + + if (!thinPool) { + throw "no thin pool specified"; + } + + if (!volumeGroup) { + throw "no volume group specified"; + } + + Ext.create('Proxmox.window.SafeDestroy', { + url: `/nodes/${view.nodename}/disks/lvmthin/${thinPool}`, + params: { 'volume-group': volumeGroup }, + item: { id: `${volumeGroup}/${thinPool}` }, + showProgress: true, + taskName: 'lvmthinremove', + taskDone: () => { view.reload(); }, + }).show(); + }, + }, + emptyText: gettext('No thinpools found'), stateful: true, @@ -142,6 +183,51 @@ Ext.define('PVE.node.LVMThinList', { }); }, }, + '->', + { + xtype: 'tbtext', + data: { + thinPool: undefined, + volumeGroup: undefined, + }, + bind: { + data: { + thinPool: "{thinPool}", + volumeGroup: "{volumeGroup}", + }, + }, + tpl: [ + '', + '', + 'Thinpool {volumeGroup}/{thinPool}:', + '', // volumeGroup + 'Missing volume group (node running old version?)', + '', + '', // thinPool + Ext.String.format(gettext('No {0} selected'), 'thinpool'), + '', + ], + }, + { + text: gettext('More'), + iconCls: 'fa fa-bars', + disabled: true, + bind: { + disabled: '{!volumeGroup || !thinPool}', + }, + menu: [ + { + text: gettext('Destroy'), + itemId: 'remove', + iconCls: 'fa fa-fw fa-trash-o', + handler: 'destroyThinPool', + disabled: true, + bind: { + disabled: '{!volumeGroup || !thinPool}', + }, + }, + ], + }, ], reload: function() { @@ -154,6 +240,13 @@ Ext.define('PVE.node.LVMThinList', { activate: function() { this.reload(); }, + selectionchange: function(model, selected) { + let me = this; + let vm = me.getViewModel(); + + vm.set('volumeGroup', selected[0]?.data.vg || ''); + vm.set('thinPool', selected[0]?.data.lv || ''); + }, }, initComponent: function() { diff --git a/www/manager6/node/ZFS.js b/www/manager6/node/ZFS.js index 8ea364bf..c5c5aac8 100644 --- a/www/manager6/node/ZFS.js +++ b/www/manager6/node/ZFS.js @@ -297,6 +297,40 @@ Ext.define('PVE.node.ZFSList', { extend: 'Ext.grid.Panel', xtype: 'pveZFSList', + viewModel: { + data: { + pool: '', + }, + }, + + controller: { + xclass: 'Ext.app.ViewController', + + destroyPool: function() { + let me = this; + let vm = me.getViewModel(); + let view = me.getView(); + + const pool = vm.get('pool'); + + if (!view.nodename) { + throw "no node name specified"; + } + + if (!pool) { + throw "no pool specified"; + } + + Ext.create('Proxmox.window.SafeDestroy', { + url: `/nodes/${view.nodename}/disks/zfs/${pool}`, + item: { id: pool }, + showProgress: true, + taskName: 'zfsremove', + taskDone: () => { view.reload(); }, + }).show(); + }, + }, + stateful: true, stateId: 'grid-node-zfs', columns: [ @@ -378,6 +412,45 @@ Ext.define('PVE.node.ZFSList', { } }, }, + '->', + { + xtype: 'tbtext', + data: { + pool: undefined, + }, + bind: { + data: { + pool: "{pool}", + }, + }, + tpl: [ + '', + 'Pool {pool}:', + '', + Ext.String.format(gettext('No {0} selected'), 'pool'), + '', + ], + }, + { + text: gettext('More'), + iconCls: 'fa fa-bars', + disabled: true, + bind: { + disabled: '{!pool}', + }, + menu: [ + { + text: gettext('Destroy'), + itemId: 'remove', + iconCls: 'fa fa-fw fa-trash-o', + handler: 'destroyPool', + disabled: true, + bind: { + disabled: '{!pool}', + }, + }, + ], + }, ], show_detail: function(zpool) { @@ -445,8 +518,12 @@ Ext.define('PVE.node.ZFSList', { activate: function() { this.reload(); }, - selectionchange: function() { - this.down('#detailbtn').setDisabled(this.getSelection().length === 0); + selectionchange: function(model, selected) { + let me = this; + let vm = me.getViewModel(); + + me.down('#detailbtn').setDisabled(selected.length === 0); + vm.set('pool', selected[0]?.data.name || ''); }, itemdblclick: function(grid, record) { this.show_detail(record.get('name')); -- 2.30.2