[pve-devel] [PATCH manager v4] ui: storage: combine RBD external and hyperconverged add dialog

Thomas Lamprecht t.lamprecht at proxmox.com
Tue Jul 31 10:28:06 CEST 2018


Combine both dialogues. This reduces storage choices from the
Storage -> Add menu, and thus improves usability.

We make the whole dialog also more intelligent by querying the
monitors, so that we can show them for the hyper converged case
keeping a similar interface for both cases. Further we can use this
to decide if a hyperconverged setup is possible at all.
While this information would also be available through the fact if
the pool selector has entries I wanted to show them anyway and could
make logic a bit easier using it.
---

changes v3 -> v4:
* add pveceph-possible intelligence
* unified interface for both
* not disabling stuff on edit as it's just hard to read

I initially tried to have two patches, one unifying and one for making it more
intelligent, but those two things are quite intertwined... And just having a
second patch for the sake of it, where then the first one is not much tested,
or undesired anyway, seemed not worth the work.


 www/manager6/Utils.js           |  11 +-
 www/manager6/dc/StorageView.js  |   4 -
 www/manager6/storage/RBDEdit.js | 200 ++++++++++++++++++++++++--------
 3 files changed, 157 insertions(+), 58 deletions(-)

diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index c062b591..3ff5ef67 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -430,17 +430,12 @@ Ext.define('PVE.Utils', { utilities: {
 	rbd: {
 	    name: 'RBD',
 	    ipanel: 'RBDInputPanel',
-	    hideAdd: true,
-	    faIcon: 'building'
-	},
-	rbd_ext: {
-	    name: 'RBD (external)',
-	    ipanel: 'RBDInputPanel',
 	    faIcon: 'building'
 	},
 	pveceph: {
 	    name: 'RBD (PVE)',
-	    ipanel: 'PVERBDInputPanel',
+	    ipanel: 'RBDInputPanel',
+	    hideAdd: true,
 	    faIcon: 'building'
 	},
 	zfs: {
@@ -461,7 +456,7 @@ Ext.define('PVE.Utils', { utilities: {
 
     format_storage_type: function(value, md, record) {
 	if (value === 'rbd' && record) {
-	    value = (record.get('monhost')?'rbd_ext':'pveceph');
+	    value = (record.get('monhost') ? 'rbd' : 'pveceph');
 	}
 
 	var schema = PVE.Utils.storageSchema[value];
diff --git a/www/manager6/dc/StorageView.js b/www/manager6/dc/StorageView.js
index 57214b7f..cc1e3ed6 100644
--- a/www/manager6/dc/StorageView.js
+++ b/www/manager6/dc/StorageView.js
@@ -54,10 +54,6 @@ Ext.define('PVE.dc.StorageView', {
 	    var type = rec.data.type,
 	        sid = rec.data.storage;
 
-	    if (type === 'rbd' && !rec.data.monhost) {
-		type = 'pveceph';
-	    }
-
 	    me.createStorageEditWindow(type, sid);
 	};
 
diff --git a/www/manager6/storage/RBDEdit.js b/www/manager6/storage/RBDEdit.js
index d26a6ac3..8ae41d1f 100644
--- a/www/manager6/storage/RBDEdit.js
+++ b/www/manager6/storage/RBDEdit.js
@@ -1,6 +1,86 @@
+/*jslint confusion: true*/
 Ext.define('PVE.storage.RBDInputPanel', {
     extend: 'PVE.panel.StorageBase',
 
+    viewModel: {
+	parent: null,
+	data: {
+	    pveceph: true,
+	    pvecephPossible: true
+	}
+    },
+
+    controller: {
+	xclass: 'Ext.app.ViewController',
+	control: {
+	    '#': {
+		afterrender: 'queryMonitors'
+	    },
+	    'textfield[name=username]': {
+		disable: 'resetField'
+	    },
+	    'displayfield[name=monhost]': {
+		enable: 'queryMonitors'
+	    },
+	    'textfield[name=monhost]': {
+		disable: 'resetField',
+		enable: 'resetField'
+	    }
+	},
+	resetField: function(field) {
+	    field.reset();
+	},
+	queryMonitors: function(field, newVal, oldVal) {
+	    // we get called with two signatures, the above one for a field
+	    // change event and the afterrender from the view, this check only
+	    // can be true for the field change one and omit the API request if
+	    // pveceph got unchecked - as it's not needed there.
+	    if (field && !newVal && oldVal) {
+		return;
+	    }
+	    var view = this.getView();
+	    var vm = this.getViewModel();
+	    if (!(view.isCreate || vm.get('pveceph'))) {
+		return; // only query on create or if editing a pveceph store
+	    }
+
+	    var monhostField = this.lookupReference('monhost');
+
+	    Proxmox.Utils.API2Request({
+		url: '/api2/json/nodes/localhost/ceph/mon',
+		method: 'GET',
+		scope: this,
+		callback: function(options, success, response) {
+		    var data = response.result.data;
+		    if (response.status === 200) {
+			if (data.length > 0) {
+			    var monhost = Ext.Array.pluck(data, 'name').sort().join(',');
+			    monhostField.setValue(monhost);
+			    monhostField.resetOriginalValue();
+			    if (view.isCreate) {
+				vm.set('pvecephPossible', true);
+			    }
+			} else {
+			    vm.set('pveceph', false);
+			}
+		    } else {
+			vm.set('pveceph', false);
+			vm.set('pvecephPossible', false);
+		    }
+		}
+	    });
+	}
+    },
+
+    setValues: function(values) {
+	if (values.monhost) {
+	    this.viewModel.set('pveceph', false);
+	    this.lookupReference('pvecephRef').setValue(false);
+	    this.lookupReference('pvecephRef').resetOriginalValue();
+	}
+	this.callParent([values]);
+    },
+
     initComponent : function() {
 	var me = this;
 
@@ -9,48 +89,68 @@ Ext.define('PVE.storage.RBDInputPanel', {
 	}
 	me.type = 'rbd';
 
-	me.column1 = [];
+	var getBinds = function (activeIfPVECeph, hide) {
+	    var bind = {
+		disabled: activeIfPVECeph ? '{!pveceph}' : '{pveceph}'
+	    };
 
-	if (me.pveceph) {
-	    me.column1.push(
-		{
-		    xtype: me.isCreate ? 'pveCephPoolSelector' : 'displayfield',
-		    nodename: me.nodename,
-		    name: 'pool',
-		    fieldLabel: gettext('Pool'),
-		    allowBlank: false
-		}
-	    );
-	} else {
-	    me.column1.push(
-		{
-		    xtype: me.isCreate ? 'textfield' : 'displayfield',
-		    name: 'pool',
-		    value: 'rbd',
-		    fieldLabel: gettext('Pool'),
-		    allowBlank: false
-		},
-		{
-		    xtype: me.isCreate ? 'textfield' : 'displayfield',
-		    name: 'monhost',
-		    vtype: 'HostList',
-		    value: '',
-		    fieldLabel: 'Monitor(s)',
-		    allowBlank: false
+	    // displayfield has no submitValue and bind mixin cannot handle that
+	    if (me.isCreate) {
+		bind.submitValue = activeIfPVECeph ? '{pveceph}' : '{!pveceph}';
+	    }
+	    if (hide) {
+		bind.hidden = activeIfPVECeph ? '{!pveceph}' : '{pveceph}';
+	    }
+
+	    return bind;
+	};
+
+	me.column1 = [
+	    {
+		xtype: me.isCreate ? 'pveCephPoolSelector' : 'displayfield',
+		nodename: me.nodename,
+		name: 'pool',
+		bind: getBinds(true, true),
+		fieldLabel: gettext('Pool'),
+		allowBlank: false
+	    },
+	    {
+		xtype: me.isCreate ? 'textfield' : 'displayfield',
+		name: 'pool',
+		value: 'rbd',
+		bind: getBinds(false, true),
+		fieldLabel: gettext('Pool'),
+		allowBlank: false
+	    },
+	    {
+		xtype: 'textfield',
+		name: 'monhost',
+		vtype: 'HostList',
+		bind: getBinds(false, true),
+		value: '',
+		fieldLabel: 'Monitor(s)',
+		allowBlank: false
+	    },
+	    {
+		xtype: 'displayfield',
+		reference: 'monhost',
+		bind: {
+		    disabled: '{!pveceph}',
+		    hidden: '{!pveceph}'
 		},
-		{
-		    xtype: me.isCreate ? 'textfield' : 'displayfield',
-		    name: 'username',
-		    value: me.isCreate ? 'admin': '',
-		    fieldLabel: gettext('User name'),
-		    allowBlank: true
-		}
-	    );
-	}
+		value: '',
+		fieldLabel: 'Monitor(s)'
+	    },
+	    {
+		xtype: me.isCreate ? 'textfield' : 'displayfield',
+		name: 'username',
+		bind: me.isCreate ? getBinds(false) : {},
+		value: 'admin',
+		fieldLabel: gettext('User name'),
+		allowBlank: true
+	    }
+	];
 
-	// here value is an array,
-	// while before it was a string
-	/*jslint confusion: true*/
 	me.column2 = [
 	    {
 		xtype: 'pveContentTypeSelector',
@@ -68,14 +168,22 @@ Ext.define('PVE.storage.RBDInputPanel', {
 		fieldLabel: 'KRBD'
 	    }
 	];
-	/*jslint confusion: false*/
+
+	me.columnB = [{
+	    xtype: 'proxmoxcheckbox',
+	    name: 'pveceph',
+	    reference: 'pvecephRef',
+	    bind : {
+		disabled: '{!pvecephPossible}',
+		value: '{pveceph}'
+	    },
+	    checked: true,
+	    uncheckedValue: 0,
+	    submitValue: false,
+	    hidden: !me.isCreate,
+	    boxLabel: gettext('Use Proxmox VE managed hyper-converged ceph pool')
+	}];
 
 	me.callParent();
     }
 });
-
-Ext.define('PVE.storage.PVERBDInputPanel', {
-    extend: 'PVE.storage.RBDInputPanel',
-
-    pveceph: 1
-});
-- 
2.18.0





More information about the pve-devel mailing list