If an OSD is removed during the wrong conditions, it could lead to blocked IO or worst case data loss.
Check against global flags that limit the capabilities of Ceph to heal itself (norebalance, norecover, noout) and if there are degraded objects. Unfortunately, the 'safe-to-destroy' Ceph API endpoint will not help here as it only works as long as the OSD is still running. By the time the destroy button is enabled, the OSD will already be stopped. Signed-off-by: Aaron Lauterer <a.laute...@proxmox.com> --- changes: * incorporated most nits * did not "improve" deconstruction of API call results as it would still be quite noisy but a little less readable IMHO. www/manager6/ceph/OSD.js | 69 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/www/manager6/ceph/OSD.js b/www/manager6/ceph/OSD.js index 78f226ff..b36787f5 100644 --- a/www/manager6/ceph/OSD.js +++ b/www/manager6/ceph/OSD.js @@ -178,6 +178,20 @@ Ext.define('PVE.CephRemoveOsd', { labelWidth: 130, fieldLabel: gettext('Cleanup Disks'), }, + { + xtype: 'displayfield', + name: 'osd-flag-hint', + userCls: 'pmx-hint', + value: gettext('Global flags limiting the self healing of Ceph are enabled.'), + hidden: true, + }, + { + xtype: 'displayfield', + name: 'degraded-objects-hint', + userCls: 'pmx-hint', + value: gettext('Objects are degraded. Consider waiting until the cluster is healthy.'), + hidden: true, + }, ], initComponent: function() { let me = this; @@ -198,6 +212,13 @@ Ext.define('PVE.CephRemoveOsd', { }); me.callParent(); + + if (me.warnings.flags) { + me.down('field[name=osd-flag-hint]').setHidden(false); + } + if (me.warnings.degraded) { + me.down('field[name=degraded-objects-hint]').setHidden(false); + } }, }); @@ -439,14 +460,58 @@ Ext.define('PVE.node.CephOsdTree', { }).show(); }, - destroy_osd: function() { + destroy_osd: async function() { let me = this; let vm = this.getViewModel(); + + let warnings = { + flags: false, + degraded: false, + }; + + let flagsPromise = Proxmox.Async.api2({ + url: `/cluster/ceph/flags`, + method: 'GET', + }); + + let statusPromise = Proxmox.Async.api2({ + url: `/cluster/ceph/status`, + method: 'GET', + }); + + me.getView().mask(gettext('Loading...')); + + try { + let result = await Promise.all([flagsPromise, statusPromise]); + + let flagsData = result[0].result.data; + let statusData = result[1].result.data; + + let flags = Array.from( + flagsData.filter(v => v.value), + v => v.name, + ).filter(v => ['norebalance', 'norecover', 'noout'].includes(v)); + + if (flags.length) { + warnings.flags = true; + } + if (Object.keys(statusData.pgmap).includes('degraded_objects')) { + warnings.degraded = true; + } + } catch (error) { + Ext.Msg.alert(gettext('Error'), error.htmlStatus); + me.getView().unmask(); + return; + } + + me.getView().unmask(); Ext.create('PVE.CephRemoveOsd', { nodename: vm.get('osdhost'), osdid: vm.get('osdid'), + warnings: warnings, taskDone: () => { me.reload(); }, - }).show(); + autoShow: true, + }); }, set_flags: function() { -- 2.30.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel