[pve-devel] [PATCH manager v2 1/5] dc: add simple cluster panel
Thomas Lamprecht
t.lamprecht at proxmox.com
Wed Apr 4 14:36:43 CEST 2018
Show configured cluster nodes with their addresses, votes, IDs.
Also show cluster name, config_version, and node count.
Prepares for creating and joining a cluster over the WebUI.
Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
changes v1 -> v2:
* re-used an already defined gettext for "no cluster configured" (Dominik)
* removed commented out code (Dominik)
* use a diff store for the node grid to avoid flickering
* ensure that the updates stores stop refreshing once the view is destroyed,
else we got a "leaky" store which continues to load even if we do not show
this panel anymore.
www/manager6/Makefile | 1 +
www/manager6/dc/Cluster.js | 200 +++++++++++++++++++++++++++++++++++++++++++++
www/manager6/dc/Config.js | 13 ++-
3 files changed, 210 insertions(+), 4 deletions(-)
create mode 100644 www/manager6/dc/Cluster.js
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index a01880f7..0796aa2c 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -193,6 +193,7 @@ JSSRC= \
dc/SecurityGroups.js \
dc/Config.js \
dc/NodeView.js \
+ dc/Cluster.js \
Workspace.js
lint: ${JSSRC}
diff --git a/www/manager6/dc/Cluster.js b/www/manager6/dc/Cluster.js
new file mode 100644
index 00000000..10e25bf0
--- /dev/null
+++ b/www/manager6/dc/Cluster.js
@@ -0,0 +1,200 @@
+/*jslint confusion: true*/
+Ext.define('pve-cluster-nodes', {
+ extend: 'Ext.data.Model',
+ fields: [
+ 'node', { type: 'integer', name: 'nodeid' }, 'ring0_addr', 'ring1_addr',
+ { type: 'integer', name: 'quorum_votes' }
+ ],
+ proxy: {
+ type: 'proxmox',
+ url: "/api2/json/cluster/config/nodes"
+ },
+ idProperty: 'nodeid'
+});
+
+Ext.define('pve-cluster-info', {
+ extend: 'Ext.data.Model',
+ proxy: {
+ type: 'proxmox',
+ url: "/api2/json/cluster/config/join"
+ }
+});
+
+Ext.define('PVE.ClusterAdministration', {
+ extend: 'Ext.panel.Panel',
+ xtype: 'pveClusterAdministration',
+
+ title: gettext('Cluster Administration'),
+
+ border: false,
+ defaults: { border: false },
+
+ viewModel: {
+ parent: null,
+ data: {
+ totem: {},
+ nodelist: [],
+ preferred_node: {
+ name: '',
+ fp: '',
+ addr: ''
+ },
+ isInCluster: false,
+ nodecount: 0
+ }
+ },
+
+ items: [
+ {
+ xtype: 'panel',
+ title: gettext('Cluster Information'),
+ controller: {
+ xclass: 'Ext.app.ViewController',
+
+ init: function(view) {
+ view.store = Ext.create('Proxmox.data.UpdateStore', {
+ autoStart: true,
+ interval: 15 * 1000,
+ storeid: 'pve-cluster-info',
+ model: 'pve-cluster-info'
+ });
+ view.store.on('load', this.onLoad, this);
+ view.on('destroy', view.store.stopUpdate);
+ },
+
+ onLoad: function(store, records, success) {
+ var vm = this.getViewModel();
+ if (!success || !records || !records[0].data) {
+ vm.set('totem', {});
+ vm.set('isInCluster', false);
+ vm.set('nodelist', []);
+ vm.set('preferred_node', {
+ name: '',
+ addr: '',
+ fp: ''
+ });
+ return;
+ }
+ var data = records[0].data;
+ vm.set('totem', data.totem);
+ vm.set('isInCluster', !!data.totem.cluster_name);
+ vm.set('nodelist', data.nodelist);
+
+ var nodeinfo = Ext.Array.findBy(data.nodelist, function (el) {
+ return el.name === data.preferred_node;
+ });
+
+ vm.set('preferred_node', {
+ name: data.preferred_node,
+ addr: nodeinfo.pve_addr,
+ fp: nodeinfo.pve_fp
+ });
+ },
+ },
+ layout: 'hbox',
+ bodyPadding: 5,
+ items: [
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Cluster Name'),
+ bind: {
+ value: '{totem.cluster_name}',
+ hidden: '{!isInCluster}'
+ },
+ flex: 1
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Config Version'),
+ bind: {
+ value: '{totem.config_version}',
+ hidden: '{!isInCluster}'
+ },
+ flex: 1
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Number of Nodes'),
+ labelWidth: 120,
+ bind: {
+ value: '{nodecount}',
+ hidden: '{!isInCluster}'
+ },
+ flex: 1
+ },
+ {
+ xtype: 'displayfield',
+ value: gettext('Standalone node - no cluster defined'),
+ bind: {
+ hidden: '{isInCluster}'
+ },
+ flex: 1
+ }
+ ]
+ },
+ {
+ xtype: 'grid',
+ title: gettext('Cluster Nodes'),
+ controller: {
+ xclass: 'Ext.app.ViewController',
+
+ init: function(view) {
+ view.rstore = Ext.create('Proxmox.data.UpdateStore', {
+ autoLoad: true,
+ xtype: 'update',
+ interval: 5 * 1000,
+ autoStart: true,
+ storeid: 'pve-cluster-nodes',
+ model: 'pve-cluster-nodes'
+ });
+ view.setStore(Ext.create('Proxmox.data.DiffStore', {
+ rstore: view.rstore,
+ sorters: {
+ property: 'nodeid',
+ order: 'DESC'
+ }
+ }));
+ Proxmox.Utils.monStoreErrors(view, view.rstore);
+ view.store.on('load', this.onLoad, this);
+ view.on('destroy', view.rstore.stopUpdate);
+ },
+
+ onLoad: function(store, records, success) {
+ var vm = this.getViewModel();
+ if (!success || !records) {
+ vm.set('nodecount', 0);
+ return;
+ }
+ vm.set('nodecount', records.length);
+ }
+ },
+ columns: [
+ {
+ header: gettext('Nodename'),
+ flex: 2,
+ dataIndex: 'name'
+ },
+ {
+ header: gettext('ID'),
+ flex: 1,
+ dataIndex: 'nodeid'
+ },
+ {
+ header: gettext('Votes'),
+ flex: 1,
+ dataIndex: 'quorum_votes'
+ },
+ {
+ header: gettext('Ring 0'),
+ flex: 2,
+ dataIndex: 'ring0_addr'
+ },
+ {
+ header: gettext('Ring 1'),
+ flex: 2,
+ dataIndex: 'ring1_addr'
+ }
+ ]
+ }
+ ]
+});
diff --git a/www/manager6/dc/Config.js b/www/manager6/dc/Config.js
index 17d7a96a..e574f5db 100644
--- a/www/manager6/dc/Config.js
+++ b/www/manager6/dc/Config.js
@@ -22,13 +22,18 @@ Ext.define('PVE.dc.Config', {
if (caps.dc['Sys.Audit']) {
me.items.push({
- title: gettext('Summary'),
+ title: gettext('Summary'),
xtype: 'pveDcSummary',
iconCls: 'fa fa-book',
itemId: 'summary'
- });
-
- me.items.push({
+ },
+ {
+ title: gettext('Cluster'),
+ xtype: 'pveClusterAdministration',
+ iconCls: 'fa fa-server',
+ itemId: 'cluster'
+ },
+ {
xtype: 'pveDcOptionView',
title: gettext('Options'),
iconCls: 'fa fa-gear',
--
2.14.2
More information about the pve-devel
mailing list