]> git.proxmox.com Git - pve-manager.git/blobdiff - www/manager6/dc/Cluster.js
ui: realm: clarify that the sync jobs really are for the realm
[pve-manager.git] / www / manager6 / dc / Cluster.js
index 6485eab708a3656ff38aef1c265dc5ba06611daa..22b62cc8cfaec2995f37ff16bdd81ed8170d1086 100644 (file)
@@ -1,23 +1,22 @@
-/*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' }
+       { type: 'integer', name: 'quorum_votes' },
     ],
     proxy: {
         type: 'proxmox',
-       url: "/api2/json/cluster/config/nodes"
+       url: "/api2/json/cluster/config/nodes",
     },
-    idProperty: 'nodeid'
+    idProperty: 'nodeid',
 });
 
 Ext.define('pve-cluster-info', {
     extend: 'Ext.data.Model',
     proxy: {
         type: 'proxmox',
-       url: "/api2/json/cluster/config/join"
-    }
+       url: "/api2/json/cluster/config/join",
+    },
 });
 
 Ext.define('PVE.ClusterAdministration', {
@@ -38,11 +37,11 @@ Ext.define('PVE.ClusterAdministration', {
            preferred_node: {
                name: '',
                fp: '',
-               addr: ''
+               addr: '',
            },
            isInCluster: false,
-           nodecount: 0
-       }
+           nodecount: 0,
+       },
     },
 
     items: [
@@ -57,78 +56,96 @@ Ext.define('PVE.ClusterAdministration', {
                        autoStart: true,
                        interval: 15 * 1000,
                        storeid: 'pve-cluster-info',
-                       model: '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) {
+               onLoad: function(store, records, success, operation) {
+                   let vm = this.getViewModel();
+
+                   let data = records?.[0]?.data;
+                   if (!success || !data || !data.nodelist?.length) {
+                       let error = operation.getError();
+                       if (error) {
+                           let msg = Proxmox.Utils.getResponseErrorMessage(error);
+                           if (error.status !== 424 && !msg.match(/node is not in a cluster/i)) {
+                               // an actual error, not just the "not in a cluster one", so show it!
+                               Proxmox.Utils.setErrorMask(this.getView(), msg);
+                           }
+                       }
                        vm.set('totem', {});
                        vm.set('isInCluster', false);
                        vm.set('nodelist', []);
                        vm.set('preferred_node', {
                            name: '',
                            addr: '',
-                           fp: ''
+                           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;
+                   let nodeinfo = data.nodelist.find(el => el.name === data.preferred_node);
+
+                   let links = {};
+                   let ring_addr = [];
+                   PVE.Utils.forEachCorosyncLink(nodeinfo, (num, link) => {
+                       links[num] = link;
+                       ring_addr.push(link);
                    });
 
                    vm.set('preferred_node', {
                        name: data.preferred_node,
                        addr: nodeinfo.pve_addr,
-                       fp: nodeinfo.pve_fp
+                       peerLinks: links,
+                       ring_addr: ring_addr,
+                       fp: nodeinfo.pve_fp,
                    });
                },
 
                onCreate: function() {
-                   var view = this.getView();
+                   let view = this.getView();
                    view.store.stopUpdate();
-                   var win = Ext.create('PVE.ClusterCreateWindow', {
+                   Ext.create('PVE.ClusterCreateWindow', {
                        autoShow: true,
                        listeners: {
                            destroy: function() {
                                view.store.startUpdate();
-                           }
-                       }
+                           },
+                       },
                    });
                },
 
                onClusterInfo: function() {
-                   var vm = this.getViewModel();
-                   var win = Ext.create('PVE.ClusterInfoWindow', {
+                   let vm = this.getViewModel();
+                   Ext.create('PVE.ClusterInfoWindow', {
+                       autoShow: true,
                        joinInfo: {
                            ipAddress: vm.get('preferred_node.addr'),
                            fingerprint: vm.get('preferred_node.fp'),
-                           totem: vm.get('totem')
-                       }
+                           peerLinks: vm.get('preferred_node.peerLinks'),
+                           ring_addr: vm.get('preferred_node.ring_addr'),
+                           totem: vm.get('totem'),
+                       },
                    });
-                   win.show();
                },
 
                onJoin: function() {
-                   var view = this.getView();
+                   let view = this.getView();
                    view.store.stopUpdate();
-                   var win = Ext.create('PVE.ClusterJoinNodeWindow', {
+                   Ext.create('PVE.ClusterJoinNodeWindow', {
                        autoShow: true,
                        listeners: {
                            destroy: function() {
                                view.store.startUpdate();
-                           }
-                       }
+                           },
+                       },
                    });
-               }
+               },
            },
            tbar: [
                {
@@ -136,25 +153,25 @@ Ext.define('PVE.ClusterAdministration', {
                    reference: 'createButton',
                    handler: 'onCreate',
                    bind: {
-                       disabled: '{isInCluster}'
-                   }
+                       disabled: '{isInCluster}',
+                   },
                },
                {
                    text: gettext('Join Information'),
                    reference: 'addButton',
                    handler: 'onClusterInfo',
                    bind: {
-                       disabled: '{!isInCluster}'
-                   }
+                       disabled: '{!isInCluster}',
+                   },
                },
                {
                    text: gettext('Join Cluster'),
                    reference: 'joinButton',
                    handler: 'onJoin',
                    bind: {
-                       disabled: '{isInCluster}'
-                   }
-               }
+                       disabled: '{isInCluster}',
+                   },
+               },
            ],
            layout: 'hbox',
            bodyPadding: 5,
@@ -164,18 +181,18 @@ Ext.define('PVE.ClusterAdministration', {
                    fieldLabel: gettext('Cluster Name'),
                    bind: {
                        value: '{totem.cluster_name}',
-                       hidden: '{!isInCluster}'
+                       hidden: '{!isInCluster}',
                    },
-                   flex: 1
+                   flex: 1,
                },
                {
                    xtype: 'displayfield',
                    fieldLabel: gettext('Config Version'),
                    bind: {
                        value: '{totem.config_version}',
-                       hidden: '{!isInCluster}'
+                       hidden: '{!isInCluster}',
                    },
-                   flex: 1
+                   flex: 1,
                },
                {
                    xtype: 'displayfield',
@@ -183,23 +200,25 @@ Ext.define('PVE.ClusterAdministration', {
                    labelWidth: 120,
                    bind: {
                        value: '{nodecount}',
-                       hidden: '{!isInCluster}'
+                       hidden: '{!isInCluster}',
                    },
-                   flex: 1
+                   flex: 1,
                },
                {
                    xtype: 'displayfield',
                    value: gettext('Standalone node - no cluster defined'),
                    bind: {
-                       hidden: '{isInCluster}'
+                       hidden: '{isInCluster}',
                    },
-                   flex: 1
-               }
-           ]
+                   flex: 1,
+               },
+           ],
        },
        {
            xtype: 'grid',
            title: gettext('Cluster Nodes'),
+           autoScroll: true,
+           enableColumnHide: false,
            controller: {
                xclass: 'Ext.app.ViewController',
 
@@ -210,14 +229,14 @@ Ext.define('PVE.ClusterAdministration', {
                        interval: 5 * 1000,
                        autoStart: true,
                        storeid: 'pve-cluster-nodes',
-                       model: 'pve-cluster-nodes'
+                       model: 'pve-cluster-nodes',
                    });
                    view.setStore(Ext.create('Proxmox.data.DiffStore', {
                        rstore: view.rstore,
                        sorters: {
                            property: 'nodeid',
-                           order: 'DESC'
-                       }
+                           direction: 'ASC',
+                       },
                    }));
                    Proxmox.Utils.monStoreErrors(view, view.rstore);
                    view.rstore.on('load', this.onLoad, this);
@@ -225,41 +244,107 @@ Ext.define('PVE.ClusterAdministration', {
                },
 
                onLoad: function(store, records, success) {
-                   var vm = this.getViewModel();
-                   if (!success || !records) {
+                   let view = this.getView();
+                   let vm = this.getViewModel();
+
+                   if (!success || !records || !records.length) {
                        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'
+
+                   // show/hide columns according to used links
+                   let linkIndex = view.columns.length;
+                   Ext.each(view.columns, (col, i) => {
+                       if (col.linkNumber !== undefined) {
+                           col.setHidden(true);
+                           // save offset at which link columns start, so we can address them directly below
+                           if (i < linkIndex) {
+                               linkIndex = i;
+                           }
+                       }
+                   });
+
+                   PVE.Utils.forEachCorosyncLink(records[0].data,
+                       (linknum, val) => {
+                           if (linknum > 7) {
+                               return;
+                           }
+                           view.columns[linkIndex + linknum].setHidden(false);
+                       },
+                   );
                },
-               {
-                   header: gettext('Votes'),
+           },
+           columns: {
+               items: [
+                   {
+                       header: gettext('Nodename'),
+                       hidden: false,
+                       dataIndex: 'name',
+                   },
+                   {
+                       header: gettext('ID'),
+                       minWidth: 100,
+                       width: 100,
+                       flex: 0,
+                       hidden: false,
+                       dataIndex: 'nodeid',
+                   },
+                   {
+                       header: gettext('Votes'),
+                       minWidth: 100,
+                       width: 100,
+                       flex: 0,
+                       hidden: false,
+                       dataIndex: 'quorum_votes',
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 0),
+                       dataIndex: 'ring0_addr',
+                       linkNumber: 0,
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 1),
+                       dataIndex: 'ring1_addr',
+                       linkNumber: 1,
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 2),
+                       dataIndex: 'ring2_addr',
+                       linkNumber: 2,
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 3),
+                       dataIndex: 'ring3_addr',
+                       linkNumber: 3,
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 4),
+                       dataIndex: 'ring4_addr',
+                       linkNumber: 4,
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 5),
+                       dataIndex: 'ring5_addr',
+                       linkNumber: 5,
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 6),
+                       dataIndex: 'ring6_addr',
+                       linkNumber: 6,
+                   },
+                   {
+                       header: Ext.String.format(gettext('Link {0}'), 7),
+                       dataIndex: 'ring7_addr',
+                       linkNumber: 7,
+                   },
+               ],
+               defaults: {
                    flex: 1,
-                   dataIndex: 'quorum_votes'
-               },
-               {
-                   header: gettext('Ring 0'),
-                   flex: 2,
-                   dataIndex: 'ring0_addr'
+                   hidden: true,
+                   minWidth: 150,
                },
-               {
-                   header: gettext('Ring 1'),
-                   flex: 2,
-                   dataIndex: 'ring1_addr'
-               }
-           ]
-       }
-    ]
+           },
+       },
+    ],
 });