Commit de5d8ab1 authored by Dietmar Maurer's avatar Dietmar Maurer

add GUI for user_beancounters

parent 3172ae64
...@@ -15,6 +15,7 @@ use PVE::RESTHandler; ...@@ -15,6 +15,7 @@ use PVE::RESTHandler;
use PVE::RPCEnvironment; use PVE::RPCEnvironment;
use PVE::JSONSchema qw(get_standard_option); use PVE::JSONSchema qw(get_standard_option);
use PVE::AccessControl; use PVE::AccessControl;
use PVE::OpenVZ;
use PVE::API2::Services; use PVE::API2::Services;
use PVE::API2::Network; use PVE::API2::Network;
use PVE::API2::Tasks; use PVE::API2::Tasks;
...@@ -99,6 +100,7 @@ __PACKAGE__->register_method ({ ...@@ -99,6 +100,7 @@ __PACKAGE__->register_method ({
{ name => 'upload' }, { name => 'upload' },
{ name => 'qemu' }, { name => 'qemu' },
{ name => 'openvz' }, { name => 'openvz' },
{ name => 'ubcfailcnt' },
{ name => 'network' }, { name => 'network' },
{ name => 'network_changes' }, { name => 'network_changes' },
]; ];
...@@ -106,6 +108,47 @@ __PACKAGE__->register_method ({ ...@@ -106,6 +108,47 @@ __PACKAGE__->register_method ({
return $result; return $result;
}}); }});
__PACKAGE__->register_method({
name => 'beancounters_failcnt',
path => 'ubcfailcnt',
permissions => {
path => '/nodes/{node}',
privs => [ 'Sys.Audit' ],
},
method => 'GET',
proxyto => 'node',
protected => 1, # openvz /proc entries are only readable by root
description => "Get user_beancounters failcnt for all active containers.",
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
},
},
returns => {
type => 'array',
items => {
type => "object",
properties => {
id => { type => 'string' },
failcnt => { type => 'number' },
},
},
},
code => sub {
my ($param) = @_;
my $ubchash = PVE::OpenVZ::read_user_beancounters();
my $res = [];
foreach my $vmid (keys %$ubchash) {
next if !$vmid;
push @$res, { id => $vmid, failcnt => $ubchash->{$vmid}->{failcntsum} };
}
return $res;
}});
__PACKAGE__->register_method({ __PACKAGE__->register_method({
name => 'network_changes', name => 'network_changes',
path => 'network_changes', path => 'network_changes',
......
...@@ -650,7 +650,9 @@ __PACKAGE__->register_method({ ...@@ -650,7 +650,9 @@ __PACKAGE__->register_method({
# test if VM exists # test if VM exists
my $conf = PVE::OpenVZ::load_config($param->{vmid}); my $conf = PVE::OpenVZ::load_config($param->{vmid});
my $ubc = PVE::OpenVZ::read_container_beancounters($param->{vmid}); my $ubchash = PVE::OpenVZ::read_user_beancounters();
my $ubc = $ubchash->{$param->{vmid}} || {};
delete $ubc->{failcntsum};
return PVE::RESTHandler::hash_to_array($ubc, 'id'); return PVE::RESTHandler::hash_to_array($ubc, 'id');
}}); }});
......
...@@ -59,18 +59,18 @@ sub load_config { ...@@ -59,18 +59,18 @@ sub load_config {
return $conf; return $conf;
} }
sub read_container_beancounters { sub read_user_beancounters {
my ($vmid) = @_;
my $ubc = {}; my $ubc = {};
if (my $fh = IO::File->new ("/proc/user_beancounters", "r")) { if (my $fh = IO::File->new ("/proc/user_beancounters", "r")) {
my $cid; my $vmid;
while (defined (my $line = <$fh>)) { while (defined (my $line = <$fh>)) {
if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) { if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) {
$cid = $2 if defined($2); $vmid = $2 if defined($2);
next if !$cid || $cid != $vmid; next if !defined($vmid);
my ($name, $held, $maxheld, $bar, $lim, $failcnt) = (lc($3), $4, $5, $6, $7, $8); my ($name, $held, $maxheld, $bar, $lim, $failcnt) = (lc($3), $4, $5, $6, $7, $8);
$ubc->{$name} = { next if $name eq 'dummy';
$ubc->{$vmid}->{failcntsum} += $failcnt;
$ubc->{$vmid}->{$name} = {
held => $held, held => $held,
maxheld => $maxheld, maxheld => $maxheld,
bar => $bar, bar => $bar,
...@@ -191,28 +191,17 @@ sub vmstatus { ...@@ -191,28 +191,17 @@ sub vmstatus {
close($fh); close($fh);
} }
if (my $fh = IO::File->new ("/proc/user_beancounters", "r")) { my $ubchash = read_user_beancounters();
my $vmid; foreach my $vmid (keys %$ubchash) {
while (defined (my $line = <$fh>)) { my $d = $list->{$vmid};
if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) { my $ubc = $ubchash->{$vmid};
$vmid = $2 if defined($2); if ($d && defined($d->{status}) && $ubc) {
next if !$vmid; $d->{failcnt} = $ubc->{failcntsum};
my ($name, $held, $maxheld, $bar, $lim, $failcnt) = ($3, $4, $5, $6, $7, $8); $d->{mem} = int($ubc->{privvmpages}->{held} * 4096);
my $d = $list->{$vmid}; my $phy = int($ubc->{physpages}->{held} * 4096);
if ($d && defined($d->{status})) { $d->{swap} = $phy > $d->{maxmem} ? $phy - $d->{maxmem} : 0;
$d->{failcnt} += $failcnt; $d->{nproc} = $ubc->{numproc}->{held};
if ($name eq 'privvmpages') { # mem + swap - really?
$d->{mem} = int($held * 4096);
} elsif ($name eq 'physpages') {
my $phy = int($held * 4096);
$d->{swap} = $phy > $d->{maxmem} ? $phy - $d->{maxmem} : 0;
} elsif ($name eq 'numproc') {
$d->{nproc} = $held;
}
}
}
} }
close($fh);
} }
if (my $fh = IO::File->new ("/proc/vz/vzquota", "r")) { if (my $fh = IO::File->new ("/proc/vz/vzquota", "r")) {
......
pve-manager (2.0-7) unstable; urgency=low
* imlement openvz GUI
-- Proxmox Support Team <support@proxmox.com> Fri, 07 Oct 2011 13:56:03 +0200
pve-manager (2.0-6) unstable; urgency=low pve-manager (2.0-6) unstable; urgency=low
* implemented openvz vnc console * implemented openvz vnc console
......
...@@ -2,7 +2,7 @@ RELEASE=2.0 ...@@ -2,7 +2,7 @@ RELEASE=2.0
VERSION=2.0 VERSION=2.0
PACKAGE=pve-manager PACKAGE=pve-manager
PACKAGERELEASE=6 PACKAGERELEASE=7
BINDIR=${DESTDIR}/usr/bin BINDIR=${DESTDIR}/usr/bin
PERLLIBDIR=${DESTDIR}/usr/share/perl5 PERLLIBDIR=${DESTDIR}/usr/share/perl5
......
...@@ -57,6 +57,7 @@ JSSRC= \ ...@@ -57,6 +57,7 @@ JSSRC= \
node/TimeView.js \ node/TimeView.js \
node/TimeEdit.js \ node/TimeEdit.js \
node/StatusView.js \ node/StatusView.js \
node/BCFailCnt.js \
node/Summary.js \ node/Summary.js \
node/ServiceView.js \ node/ServiceView.js \
node/NetworkEdit.js \ node/NetworkEdit.js \
...@@ -87,6 +88,7 @@ JSSRC= \ ...@@ -87,6 +88,7 @@ JSSRC= \
openvz/Options.js \ openvz/Options.js \
openvz/Network.js \ openvz/Network.js \
openvz/DNS.js \ openvz/DNS.js \
openvz/BeanCounterGrid.js \
openvz/Config.js \ openvz/Config.js \
openvz/CreateWizard.js \ openvz/CreateWizard.js \
storage/ContentView.js \ storage/ContentView.js \
......
/*jslint confusion: true */
Ext.define('PVE.node.BCFailCnt', {
extend: 'Ext.grid.GridPanel',
alias: ['widget.pveNodeBCFailCnt'],
initComponent : function() {
var me = this;
var nodename = me.pveSelNode.data.node;
if (!nodename) {
throw "no node name specified";
}
var store = new Ext.data.Store({
model: 'pve-openvz-ubc',
proxy: {
type: 'pve',
url: '/api2/json/nodes/' + nodename + '/ubcfailcnt'
},
sorters: [
{
property : 'id',
direction: 'ASC'
}
]
});
var reload = function() {
store.load();
};
Ext.applyIf(me, {
store: store,
stateful: false,
columns: [
{
header: 'Container',
width: 100,
dataIndex: 'id'
},
{
header: 'failcnt',
flex: 1,
dataIndex: 'failcnt'
}
],
listeners: {
show: reload,
itemdblclick: function(v, record) {
var ws = me.up('pveStdWorkspace');
ws.selectById('openvz/' + record.data.id);
},
}
});
me.callParent();
}
}, function() {
Ext.define('pve-openvz-ubc', {
extend: "Ext.data.Model",
fields: [ 'id', { name: 'failcnt', type: 'number' } ]
});
});
...@@ -48,6 +48,11 @@ Ext.define('PVE.node.Config', { ...@@ -48,6 +48,11 @@ Ext.define('PVE.node.Config', {
title: 'Task History', title: 'Task History',
itemId: 'tasks', itemId: 'tasks',
xtype: 'pveNodeTasks' xtype: 'pveNodeTasks'
},
{
title: 'UBC',
itemId: 'ubc',
xtype: 'pveNodeBCFailCnt'
} }
] ]
}); });
......
/*jslint confusion: true */
Ext.define('PVE.openvz.BeanCounterGrid', {
extend: 'Ext.grid.GridPanel',
alias: ['widget.pveBeanCounterGrid'],
renderUbc: function(value, metaData, record, rowIndex, colIndex, store) {
if (value === 9223372036854775807) {
return '-';
}
if (record.id.match(/pages$/)) {
return PVE.Utils.format_size(value*4096);
}
if (record.id.match(/(size|buf)$/)) {
return PVE.Utils.format_size(value);
}
return value;
},
initComponent : function() {
var me = this;
if (!me.url) {
throw "no url specified";
}
var store = new Ext.data.Store({
model: 'pve-openvz-ubc',
proxy: {
type: 'pve',
url: me.url
},
sorters: [
{
property : 'id',
direction: 'ASC'
}
]
});
var reload = function() {
store.load();
};
Ext.applyIf(me, {
store: store,
stateful: false,
columns: [
{
header: 'Ressource',
width: 100,
dataIndex: 'id'
},
{
header: 'held',
width: 100,
renderer: me.renderUbc,
dataIndex: 'held'
},
{
header: 'maxheld',
width: 100,
renderer: me.renderUbc,
dataIndex: 'maxheld'
},
{
header: 'barrier',
width: 100,
renderer: me.renderUbc,
dataIndex: 'bar'
},
{
header: 'limit',
width: 100,
renderer: me.renderUbc,
dataIndex: 'lim'
},
{
header: 'failcnt',
width: 100,
dataIndex: 'failcnt'
}
],
listeners: {
show: reload
}
});
me.callParent();
}
}, function() {
Ext.define('pve-openvz-ubc', {
extend: "Ext.data.Model",
fields: [ 'id',
{ name: 'held', type: 'number' },
{ name: 'maxheld', type: 'number' },
{ name: 'bar', type: 'number' },
{ name: 'lim', type: 'number' },
{ name: 'failcnt', type: 'number' }
]
});
});
...@@ -47,6 +47,12 @@ Ext.define('PVE.openvz.Config', { ...@@ -47,6 +47,12 @@ Ext.define('PVE.openvz.Config', {
itemId: 'options', itemId: 'options',
xtype: 'pveOpenVZOptions' xtype: 'pveOpenVZOptions'
}, },
{
title: 'UBC',
itemId: 'ubc',
xtype: 'pveBeanCounterGrid',
url: '/api2/json/nodes/' + nodename + '/openvz/' + vmid + '/status/ubc'
},
{ {
xtype: 'pveOpenVZConsole', xtype: 'pveOpenVZConsole',
title: 'Console', title: 'Console',
......
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