mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-08-08 10:32:50 +00:00
API change: /cluster/status - do not use clustat
This commit is contained in:
parent
94c47be79d
commit
91d7c7aa00
@ -349,91 +349,6 @@ __PACKAGE__->register_method({
|
|||||||
return undef;
|
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({
|
__PACKAGE__->register_method({
|
||||||
name => 'get_status',
|
name => 'get_status',
|
||||||
path => 'status',
|
path => 'status',
|
||||||
@ -468,10 +383,38 @@ __PACKAGE__->register_method({
|
|||||||
my $rrd = PVE::Cluster::rrd_dump();
|
my $rrd = PVE::Cluster::rrd_dump();
|
||||||
|
|
||||||
if ($members) {
|
if ($members) {
|
||||||
my $cmd = ['clustat', '-x'];
|
my $res = [];
|
||||||
my $out = '';
|
|
||||||
PVE::Tools::run_command($cmd, outfunc => sub { $out .= shift; });
|
if (my $d = $clinfo->{cluster}) {
|
||||||
return &$parse_clustat($clinfo, $members, $rrd, $nodename, $out);
|
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 {
|
} else {
|
||||||
# fake entry for local node if no cluster defined
|
# fake entry for local node if no cluster defined
|
||||||
my $pmxcfs = ($clinfo && $clinfo->{version}) ? 1 : 0; # pmxcfs online ?
|
my $pmxcfs = ($clinfo && $clinfo->{version}) ? 1 : 0; # pmxcfs online ?
|
||||||
@ -483,10 +426,10 @@ __PACKAGE__->register_method({
|
|||||||
type => 'node',
|
type => 'node',
|
||||||
id => "node/$nodename",
|
id => "node/$nodename",
|
||||||
name => $nodename,
|
name => $nodename,
|
||||||
|
ip => PVE::Cluster::remote_node_ip($nodename),
|
||||||
'local' => 1,
|
'local' => 1,
|
||||||
nodeid => 0,
|
nodeid => 0,
|
||||||
pmxcfs => $pmxcfs,
|
online => 1,
|
||||||
state => 1,
|
|
||||||
level => $sublevel,
|
level => $sublevel,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,17 @@ Ext.define('PVE.dc.NodeView', {
|
|||||||
|
|
||||||
var store = Ext.create('PVE.data.DiffStore', { rstore: rstore });
|
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, {
|
Ext.apply(me, {
|
||||||
store: store,
|
store: store,
|
||||||
stateful: false,
|
stateful: false,
|
||||||
|
bbar: [ status ],
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
header: gettext('Name'),
|
header: gettext('Name'),
|
||||||
@ -42,7 +50,7 @@ Ext.define('PVE.dc.NodeView', {
|
|||||||
header: gettext('Online'),
|
header: gettext('Online'),
|
||||||
width: 100,
|
width: 100,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
dataIndex: 'state',
|
dataIndex: 'online',
|
||||||
renderer: PVE.Utils.format_boolean
|
renderer: PVE.Utils.format_boolean
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -52,133 +60,11 @@ Ext.define('PVE.dc.NodeView', {
|
|||||||
dataIndex: 'level',
|
dataIndex: 'level',
|
||||||
renderer: PVE.Utils.render_support_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'),
|
header: gettext('Server Address'),
|
||||||
width: 100,
|
flex: 1,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
dataIndex: 'ip'
|
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: {
|
listeners: {
|
||||||
@ -195,38 +81,37 @@ Ext.define('PVE.dc.HAServiceView', {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cluster_rec = rstore.getById('cluster');
|
console.log("test1");
|
||||||
var quorum_rec = rstore.getById('quorum');
|
console.dir(records);
|
||||||
|
|
||||||
if (!(cluster_rec && quorum_rec)) {
|
var cluster_rec = rstore.getById('cluster');
|
||||||
|
|
||||||
|
if (!cluster_rec) {
|
||||||
status.update(noClusterText);
|
status.update(noClusterText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cluster_raw = cluster_rec.raw;
|
var cluster_raw = cluster_rec.raw;
|
||||||
var quorum_raw = quorum_rec.raw;
|
if (!cluster_raw) {
|
||||||
if (!(cluster_raw && quorum_raw)) {
|
|
||||||
status.update(noClusterText);
|
status.update(noClusterText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var text = gettext("Cluster") + ": " + cluster_raw.name + ", " +
|
||||||
status.update("Quorate: " + PVE.Utils.format_boolean(quorum_raw.quorate));
|
gettext("Quorate") + ": " + PVE.Utils.format_boolean(cluster_raw.quorate);
|
||||||
|
status.update(text);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}, function() {
|
}, function() {
|
||||||
|
|
||||||
Ext.define('pve-ha-services', {
|
Ext.define('pve-dc-nodes', {
|
||||||
extend: 'Ext.data.Model',
|
extend: 'Ext.data.Model',
|
||||||
fields: [ 'id', 'type', 'name', 'owner', 'last_owner', 'state_str', 'restarts',
|
fields: [ 'id', 'type', 'name', 'nodeid', 'ip', 'level', 'local', 'online'],
|
||||||
{ name: 'last_transition', type: 'date', dateFormat: 'timestamp'}
|
|
||||||
],
|
|
||||||
idProperty: 'id'
|
idProperty: 'id'
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Ext.define('PVE.dc.Summary', {
|
Ext.define('PVE.dc.Summary', {
|
||||||
extend: 'Ext.panel.Panel',
|
extend: 'Ext.panel.Panel',
|
||||||
|
|
||||||
@ -235,14 +120,6 @@ Ext.define('PVE.dc.Summary', {
|
|||||||
initComponent: function() {
|
initComponent: function() {
|
||||||
var me = this;
|
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', {
|
var nodegrid = Ext.create('PVE.dc.NodeView', {
|
||||||
title: gettext('Nodes'),
|
title: gettext('Nodes'),
|
||||||
border: false,
|
border: false,
|
||||||
@ -252,15 +129,13 @@ Ext.define('PVE.dc.Summary', {
|
|||||||
|
|
||||||
Ext.apply(me, {
|
Ext.apply(me, {
|
||||||
layout: 'border',
|
layout: 'border',
|
||||||
items: [ nodegrid, hagrid ],
|
items: [ nodegrid ],
|
||||||
listeners: {
|
listeners: {
|
||||||
show: function() {
|
show: function() {
|
||||||
hagrid.fireEvent('show', hagrid);
|
nodegrid.fireEvent('show', nodegrid);
|
||||||
nodegrid.fireEvent('show', hagrid);
|
|
||||||
},
|
},
|
||||||
hide: function() {
|
hide: function() {
|
||||||
hagrid.fireEvent('hide', hagrid);
|
nodegrid.fireEvent('hide', nodegrid);
|
||||||
nodegrid.fireEvent('hide', hagrid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user