Commit de5d8ab1 authored by Dietmar Maurer's avatar Dietmar Maurer

add GUI for user_beancounters

parent 3172ae64
......@@ -15,6 +15,7 @@ use PVE::RESTHandler;
use PVE::RPCEnvironment;
use PVE::JSONSchema qw(get_standard_option);
use PVE::AccessControl;
use PVE::OpenVZ;
use PVE::API2::Services;
use PVE::API2::Network;
use PVE::API2::Tasks;
......@@ -99,6 +100,7 @@ __PACKAGE__->register_method ({
{ name => 'upload' },
{ name => 'qemu' },
{ name => 'openvz' },
{ name => 'ubcfailcnt' },
{ name => 'network' },
{ name => 'network_changes' },
];
......@@ -106,6 +108,47 @@ __PACKAGE__->register_method ({
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({
name => 'network_changes',
path => 'network_changes',
......
......@@ -650,7 +650,9 @@ __PACKAGE__->register_method({
# test if VM exists
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');
}});
......
......@@ -59,18 +59,18 @@ sub load_config {
return $conf;
}
sub read_container_beancounters {
my ($vmid) = @_;
sub read_user_beancounters {
my $ubc = {};
if (my $fh = IO::File->new ("/proc/user_beancounters", "r")) {
my $cid;
my $vmid;
while (defined (my $line = <$fh>)) {
if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) {
$cid = $2 if defined($2);
next if !$cid || $cid != $vmid;
$vmid = $2 if defined($2);
next if !defined($vmid);
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,
maxheld => $maxheld,
bar => $bar,
......@@ -191,28 +191,17 @@ sub vmstatus {
close($fh);
}
if (my $fh = IO::File->new ("/proc/user_beancounters", "r")) {
my $vmid;
while (defined (my $line = <$fh>)) {
if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) {
$vmid = $2 if defined($2);
next if !$vmid;
my ($name, $held, $maxheld, $bar, $lim, $failcnt) = ($3, $4, $5, $6, $7, $8);
my $d = $list->{$vmid};
if ($d && defined($d->{status})) {
$d->{failcnt} += $failcnt;
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;
}
}
}
my $ubchash = read_user_beancounters();
foreach my $vmid (keys %$ubchash) {
my $d = $list->{$vmid};
my $ubc = $ubchash->{$vmid};
if ($d && defined($d->{status}) && $ubc) {
$d->{failcnt} = $ubc->{failcntsum};
$d->{mem} = int($ubc->{privvmpages}->{held} * 4096);
my $phy = int($ubc->{physpages}->{held} * 4096);
$d->{swap} = $phy > $d->{maxmem} ? $phy - $d->{maxmem} : 0;
$d->{nproc} = $ubc->{numproc}->{held};
}
close($fh);
}
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
* implemented openvz vnc console
......
......@@ -2,7 +2,7 @@ RELEASE=2.0
VERSION=2.0
PACKAGE=pve-manager
PACKAGERELEASE=6
PACKAGERELEASE=7
BINDIR=${DESTDIR}/usr/bin
PERLLIBDIR=${DESTDIR}/usr/share/perl5
......
......@@ -57,6 +57,7 @@ JSSRC= \
node/TimeView.js \
node/TimeEdit.js \
node/StatusView.js \
node/BCFailCnt.js \
node/Summary.js \
node/ServiceView.js \
node/NetworkEdit.js \
......@@ -87,6 +88,7 @@ JSSRC= \
openvz/Options.js \
openvz/Network.js \
openvz/DNS.js \
openvz/BeanCounterGrid.js \
openvz/Config.js \
openvz/CreateWizard.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', {
title: 'Task History',
itemId: 'tasks',
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', {
itemId: 'options',
xtype: 'pveOpenVZOptions'
},
{
title: 'UBC',
itemId: 'ubc',
xtype: 'pveBeanCounterGrid',
url: '/api2/json/nodes/' + nodename + '/openvz/' + vmid + '/status/ubc'
},
{
xtype: 'pveOpenVZConsole',
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