Commit 9432f732 authored by Dietmar Maurer's avatar Dietmar Maurer

start ceph management GUI

parent b613c189
......@@ -80,6 +80,19 @@ my $check_ceph_inited = sub {
return 1;
};
my $check_ceph_enabled = sub {
my ($noerr) = @_;
return undef if !&$check_ceph_inited($noerr);
if (! -f $ceph_cfgpath) {
die "pveceph configuration not enabled\n" if !$noerr;
return undef;
}
return 1;
};
my $force_symlink = sub {
my ($old, $new) = @_;
......@@ -143,13 +156,15 @@ my $run_ceph_cmd = sub {
alarm($oldalarm) if $oldalarm;
die $err if $err;
};
sub ceph_mon_status {
my ($quiet) = @_;
my $run_ceph_cmd_json = sub {
my ($cmd, %opts) = @_;
my $json = '';
my $quiet = delete $opts{quiet};
my $parser = sub {
my $line = shift;
$json .= $line;
......@@ -160,33 +175,25 @@ sub ceph_mon_status {
print "$line\n" if !$quiet;
};
&$run_ceph_cmd(['mon_status'], outfunc => $parser, errfunc => $errfunc);
&$run_ceph_cmd([@$cmd, '--format', 'json'],
outfunc => $parser, errfunc => $errfunc);
my $res = decode_json($json);
return $res;
}
};
my $ceph_osd_status = sub {
sub ceph_mon_status {
my ($quiet) = @_;
return &$run_ceph_cmd_json(['mon_status'], quiet => $quiet);
my $json = '';
my $parser = sub {
my $line = shift;
$json .= $line;
};
my $errfunc = sub {
my $line = shift;
print "$line\n" if !$quiet;
};
&$run_ceph_cmd(['osd', 'dump', '--format', 'json'],
outfunc => $parser, errfunc => $errfunc);
}
my $res = decode_json($json);
my $ceph_osd_status = sub {
my ($quiet) = @_;
return $res;
return &$run_ceph_cmd_json(['osd', 'dump'], quiet => $quiet);
};
my $write_ceph_config = sub {
......@@ -556,38 +563,9 @@ __PACKAGE__->register_method ({
code => sub {
my ($param) = @_;
my $res = { status => 'unknown' };
eval {
if (!&$check_ceph_installed(1)) {
$res->{status} = 'notinstalled';
}
if (! -f $ceph_cfgpath) {
$res->{status} = 'notconfigured';
return;
} else {
$res->{status} = 'configured';
}
my $cfg = &$parse_ceph_config($pve_ceph_cfgpath);
$res->{config} = $cfg;
eval {
my $monstat = ceph_mon_status(1);
$res->{monstat} = $monstat;
};
warn $@ if $@;
eval {
my $osdstat = &$ceph_osd_status(1);
$res->{osdstat} = $osdstat;
};
warn $@ if $@;
};
warn $@ if $@;
&$check_ceph_enabled();
return $res;
return &$run_ceph_cmd_json(['status'], quiet => 1);
}});
__PACKAGE__->register_method ({
......
......@@ -85,6 +85,7 @@ JSSRC= \
node/Tasks.js \
node/Subscription.js \
node/APT.js \
node/Ceph.js \
node/Config.js \
qemu/StatusView.js \
window/Migrate.js \
......
Ext.define('PVE.node.CephStatus', {
extend: 'PVE.grid.ObjectGrid',
alias: 'widget.pveNodeCephStatus',
initComponent: function() {
var me = this;
var nodename = me.pveSelNode.data.node;
if (!nodename) {
throw "no node name specified";
}
var renderquorum = function(value) {
if (!value) {
return '';
}
var txt = '';
Ext.Array.each(value, function(name) {
txt += name + ' ';
});
return txt;
};
var rendermonmap = function(d) {
if (!d) {
return '';
}
var txt = 'e' + d.epoch + ': ' + d.mons.length + " mons at ";
Ext.Array.each(d.mons, function(d) {
txt += d.name + '=' + d.addr + ',';
});
return txt;
};
var renderosdmap = function(value) {
if (!value || !value.osdmap) {
return '';
}
var d = value.osdmap;
var txt = 'e' + d.epoch + ': ';
txt += d.num_osds + ' osds: ' + d.num_up_osds + ' up, ' +
d.num_in_osds + " in";
return txt;
};
var renderhealth = function(value) {
if (!value || !value.overall_status) {
return '';
}
var txt = value.overall_status;
Ext.Array.each(value.summary, function(d) {
txt += " " + d.summary + ';';
});
return txt;
};
var renderpgmap = function(d) {
if (!d) {
return '';
}
var txt = 'v' + d.version + ': ';
txt += d.num_pgs + " pgs:";
Ext.Array.each(d.pgs_by_state, function(s) {
txt += " " + s.count + " " + s.state_name;
});
txt += '; ';
txt += d.data_bytes + " bytes data, ";
txt += d.bytes_used + " bytes used, ";
txt += d.bytes_avail + " bytes avail";
return txt;
};
Ext.applyIf(me, {
url: "/api2/json/nodes/" + nodename + "/ceph/status",
cwidth1: 150,
interval: 3000,
rows: {
health: {
header: 'health',
renderer: renderhealth,
required: true
},
fsid: {
header: 'cluster',
required: true
},
monmap: {
header: 'monmap',
renderer: rendermonmap,
required: true
},
quorum_names: {
header: 'quorum',
renderer: renderquorum,
required: true
},
osdmap: {
header: 'osdmap',
renderer: renderosdmap,
required: true
},
pgmap: {
header: 'pgmap',
renderer: renderpgmap,
required: true
}
}
});
me.callParent();
me.on('show', me.rstore.startUpdate);
me.on('hide', me.rstore.stopUpdate);
me.on('destroy', me.rstore.stopUpdate);
}
});
Ext.define('PVE.node.Ceph', {
extend: 'Ext.tab.Panel',
alias: 'widget.pveNodeCeph',
initComponent: function() {
var me = this;
var nodename = me.pveSelNode.data.node;
if (!nodename) {
throw "no node name specified";
}
Ext.apply(me, {
plain: true,
tabPosition: 'bottom',
defaults: {
border: false,
pveSelNode: me.pveSelNode
},
items: [
{
xtype: 'pveNodeCephStatus',
title: 'Status',
itemId: 'status'
},
{
title: 'Config',
itemId: 'config',
html: "ABCD"
},
{
title: 'Monitor',
itemId: 'test2',
html: "ABCD"
},
{
title: 'OSD',
itemId: 'test3',
html: "ABCD"
},
{
title: 'Pool',
itemId: 'test4',
html: "ABCD"
},
{
title: 'Crush',
itemId: 'test5',
html: "ABCD"
}
],
listeners: {
afterrender: function(tp) {
var first = tp.items.get(0);
if (first) {
first.fireEvent('show', first);
}
}
}
});
me.callParent();
}
});
\ No newline at end of file
......@@ -154,6 +154,12 @@ Ext.define('PVE.node.Config', {
xtype: 'pveNodeAPT',
nodename: nodename
}]);
me.items.push([{
title: 'Ceph',
itemId: 'ceph',
xtype: 'pveNodeCeph',
nodename: nodename
}]);
}
me.callParent();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment