diff --git a/PVE/API2/Cluster.pm b/PVE/API2/Cluster.pm index 68dcd08a..21876ff8 100644 --- a/PVE/API2/Cluster.pm +++ b/PVE/API2/Cluster.pm @@ -349,91 +349,6 @@ __PACKAGE__->register_method({ return undef; }}); -my $parse_clustat = sub { - my ($clinfo, $members, $rrd, $nodename, $raw) = @_; - - my $createNode = sub { - my ($expat, $tag, %attrib) = @_; - my $node = { type => $tag, %attrib }; - - if ($tag eq 'node') { - my $name = $node->{name}; - return if !$name; # just to be sure - - foreach my $key (qw(estranged local qdisk rgmanager rgmanager_master state)) { - $node->{$key} = int($node->{$key}) if defined($node->{$key}); - } - $node->{nodeid} = hex($node->{nodeid}) if defined($node->{nodeid}); - - # unique ID for GUI - $node->{id} = "node/$node->{name}"; - - my $pmxcfs = 0; - if (!$members) { # no cluster - if ($name eq $nodename) { - $pmxcfs = ($clinfo && $clinfo->{version}) ? 1 : 0; # pmxcfs online ? - } - } elsif ($members->{$name}) { - $pmxcfs = $members->{$name}->{online} ? 1 : 0 - } - $node->{pmxcfs} = $pmxcfs; - - if ($members && $members->{$name}) { - if (my $ip = $members->{$name}->{ip}) { - $node->{ip} = $ip; - } - } - - if (my $entry = PVE::API2Tools::extract_node_stats($name, $members, $rrd)) { - $node->{level} = $entry->{level} || ''; - } - - } elsif ($tag eq 'group') { - my $name = $node->{name}; - return if !$name; # just to be sure - # unique ID for GUI - $node->{id} = "group/$node->{name}"; - } else { - $node->{id} = $tag; - } - - return $node; - }; - - my $extract_tags = { - cluster => 1, - quorum => 1, - node => 1, - group => 1, - }; - - my $handlers = { - Init => sub { - my $expat = shift; - $expat->{NodeList} = []; - }, - Final => sub { - my $expat = shift; - $expat->{NodeList}; - }, - Start => sub { - my $expat = shift; - my $tag = shift; - if ($extract_tags->{$tag}) { - my $node = &$createNode($expat, $tag, @_); - push @{$expat->{NodeList}}, $node; - } - }, - }; - - my $data = []; - if ($raw) { - my $parser = new XML::Parser(Handlers => $handlers); - $data = $parser->parse($raw); - } - return $data; -}; - __PACKAGE__->register_method({ name => 'get_status', path => 'status', @@ -468,10 +383,38 @@ __PACKAGE__->register_method({ my $rrd = PVE::Cluster::rrd_dump(); if ($members) { - my $cmd = ['clustat', '-x']; - my $out = ''; - PVE::Tools::run_command($cmd, outfunc => sub { $out .= shift; }); - return &$parse_clustat($clinfo, $members, $rrd, $nodename, $out); + my $res = []; + + if (my $d = $clinfo->{cluster}) { + push @$res, { + type => 'cluster', + id => 'cluster', + nodes => $d->{nodes}, + version => $d->{version}, + name => $d->{name}, + quorate => $d->{quorate}, + }; + } + + foreach my $node (keys %$members) { + my $d = $members->{$node}; + my $entry = { + type => 'node', + id => "node/$node", + name => $node, + nodeid => $d->{id}, + ip => $d->{ip}, + 'local' => ($node eq $nodename) ? 1 : 0, + online => $d->{online}, + }; + + if (my $d = PVE::API2Tools::extract_node_stats($node, $members, $rrd)) { + $entry->{level} = $d->{level}; + } + + push @$res, $entry; + } + return $res; } else { # fake entry for local node if no cluster defined my $pmxcfs = ($clinfo && $clinfo->{version}) ? 1 : 0; # pmxcfs online ? @@ -483,10 +426,10 @@ __PACKAGE__->register_method({ type => 'node', id => "node/$nodename", name => $nodename, + ip => PVE::Cluster::remote_node_ip($nodename), 'local' => 1, nodeid => 0, - pmxcfs => $pmxcfs, - state => 1, + online => 1, level => $sublevel, }]; } diff --git a/www/manager/dc/Summary.js b/www/manager/dc/Summary.js index 192a05c2..9a210a38 100644 --- a/www/manager/dc/Summary.js +++ b/www/manager/dc/Summary.js @@ -22,9 +22,17 @@ Ext.define('PVE.dc.NodeView', { var store = Ext.create('PVE.data.DiffStore', { rstore: rstore }); + var noClusterText = gettext("Standalone node - no cluster defined"); + var status = Ext.create('Ext.Component', { + padding: 2, + html: ' ', + dock: 'bottom' + }); + Ext.apply(me, { store: store, stateful: false, + bbar: [ status ], columns: [ { header: gettext('Name'), @@ -42,7 +50,7 @@ Ext.define('PVE.dc.NodeView', { header: gettext('Online'), width: 100, sortable: true, - dataIndex: 'state', + dataIndex: 'online', renderer: PVE.Utils.format_boolean }, { @@ -52,133 +60,11 @@ Ext.define('PVE.dc.NodeView', { dataIndex: 'level', renderer: PVE.Utils.render_support_level }, - { - header: gettext('Estranged'), - width: 100, - sortable: true, - dataIndex: 'estranged', - renderer: PVE.Utils.format_boolean - }, { header: gettext('Server Address'), - width: 100, + flex: 1, sortable: true, dataIndex: 'ip' - }, - { - header: gettext('Services'), - flex: 1, - width: 80, - sortable: true, - dataIndex: 'pmxcfs', - renderer: function(value, metaData, record) { - var list = []; - var data = record.data; - if (data) { - if (data.pmxcfs) { - list.push('PVECluster'); - } - if (data.rgmanager) { - list.push('RGManager'); - } - - } - return list.join(', '); - } - } - ], - listeners: { - show: rstore.startUpdate, - hide: rstore.stopUpdate, - destroy: rstore.stopUpdate - } - }); - - me.callParent(); - } -}, function() { - - Ext.define('pve-dc-nodes', { - extend: 'Ext.data.Model', - fields: [ 'id', 'type', 'name', 'state', 'nodeid', 'ip', - 'pmxcfs', 'rgmanager', 'estranged', 'level' ], - idProperty: 'id' - }); - -}); - -Ext.define('PVE.dc.HAServiceView', { - extend: 'Ext.grid.GridPanel', - - alias: ['widget.pveHaServiceView'], - - initComponent : function() { - var me = this; - - var rstore = Ext.create('PVE.data.UpdateStore', { - interval: 3000, - storeid: 'pve-ha-services', - model: 'pve-ha-services', - proxy: { - type: 'pve', - url: "/api2/json/cluster/status" - }, - filters: { - property: 'type', - value : 'group' - } - }); - - var store = Ext.create('PVE.data.DiffStore', { rstore: rstore }); - - var noClusterText = gettext("Standalone node - no cluster defined"); - var status = Ext.create('Ext.Component', { - padding: 2, - html: ' ', - dock: 'bottom' - }); - - Ext.apply(me, { - store: store, - stateful: false, - //tbar: [ 'start', 'stop' ], - bbar: [ status ], - columns: [ - { - header: gettext('Name'), - flex: 1, - sortable: true, - dataIndex: 'name' - }, - { - header: gettext('Owner'), - flex: 1, - sortable: true, - dataIndex: 'owner' - }, - { - header: gettext('Status'), - width: 80, - sortable: true, - dataIndex: 'state_str' - }, - { - header: gettext('Restarts'), - width: 80, - sortable: true, - dataIndex: 'restarts' - }, - { - header: gettext('Last transition'), - width: 200, - sortable: true, - dataIndex: 'last_transition' - }, - { - header: gettext('Last owner'), - flex: 1, - sortable: true, - dataIndex: 'last_owner' } ], listeners: { @@ -195,38 +81,37 @@ Ext.define('PVE.dc.HAServiceView', { return; } + console.log("test1"); + console.dir(records); + var cluster_rec = rstore.getById('cluster'); - var quorum_rec = rstore.getById('quorum'); - if (!(cluster_rec && quorum_rec)) { + if (!cluster_rec) { status.update(noClusterText); return; } var cluster_raw = cluster_rec.raw; - var quorum_raw = quorum_rec.raw; - if (!(cluster_raw && quorum_raw)) { + if (!cluster_raw) { status.update(noClusterText); return; } - - status.update("Quorate: " + PVE.Utils.format_boolean(quorum_raw.quorate)); + var text = gettext("Cluster") + ": " + cluster_raw.name + ", " + + gettext("Quorate") + ": " + PVE.Utils.format_boolean(cluster_raw.quorate); + status.update(text); }); } }, function() { - Ext.define('pve-ha-services', { + Ext.define('pve-dc-nodes', { extend: 'Ext.data.Model', - fields: [ 'id', 'type', 'name', 'owner', 'last_owner', 'state_str', 'restarts', - { name: 'last_transition', type: 'date', dateFormat: 'timestamp'} - ], + fields: [ 'id', 'type', 'name', 'nodeid', 'ip', 'level', 'local', 'online'], idProperty: 'id' }); }); - Ext.define('PVE.dc.Summary', { extend: 'Ext.panel.Panel', @@ -235,14 +120,6 @@ Ext.define('PVE.dc.Summary', { initComponent: function() { var me = this; - var hagrid = Ext.create('PVE.dc.HAServiceView', { - title: gettext('HA Service Status'), - region: 'south', - border: false, - split: true, - flex: 1 - }); - var nodegrid = Ext.create('PVE.dc.NodeView', { title: gettext('Nodes'), border: false, @@ -252,15 +129,13 @@ Ext.define('PVE.dc.Summary', { Ext.apply(me, { layout: 'border', - items: [ nodegrid, hagrid ], + items: [ nodegrid ], listeners: { show: function() { - hagrid.fireEvent('show', hagrid); - nodegrid.fireEvent('show', hagrid); + nodegrid.fireEvent('show', nodegrid); }, hide: function() { - hagrid.fireEvent('hide', hagrid); - nodegrid.fireEvent('hide', hagrid); + nodegrid.fireEvent('hide', nodegrid); } } });