[pve-devel] r5739 - in pve-manager/pve2: debian lib/PVE lib/PVE/API2 www/manager

svn-commits at proxmox.com svn-commits at proxmox.com
Tue Mar 22 07:01:42 CET 2011


Author: dietmar
Date: 2011-03-22 07:01:37 +0100 (Tue, 22 Mar 2011)
New Revision: 5739

Modified:
   pve-manager/pve2/debian/control.in
   pve-manager/pve2/lib/PVE/API2/Nodes.pm
   pve-manager/pve2/lib/PVE/REST.pm
   pve-manager/pve2/www/manager/NodeConfig.js
Log:
impl. task list (per node)


Modified: pve-manager/pve2/debian/control.in
===================================================================
--- pve-manager/pve2/debian/control.in	2011-03-22 05:59:50 UTC (rev 5738)
+++ pve-manager/pve2/debian/control.in	2011-03-22 06:01:37 UTC (rev 5739)
@@ -3,7 +3,7 @@
 Section: admin
 Priority: optional
 Architecture: all
-Depends: perl5, libtimedate-perl, apache2-mpm-prefork, libauthen-pam-perl, libintl-perl, rsync, libapache2-request-perl, libjson-perl, libdigest-sha1-perl, vncterm, qemu-server (>= 1.1-1), libwww-perl, wget, libnet-dns-perl, vlan, ifenslave-2.6 (>= 1.1.0-10), liblinux-inotify2-perl, debconf (>= 0.5) | debconf-2.0, libjs-prototype (>= 1.6.0.3-1), netcat-traditional, pve-cluster, libpve-common-perl, libpve-storage-perl, libterm-readline-gnu-perl, libhttp-request-params-perl, libpve-access-control, libio-socket-ssl-perl, libfilesys-df-perl, librrds-perl, rrdcached
+Depends: perl5, libtimedate-perl, apache2-mpm-prefork, libauthen-pam-perl, libintl-perl, rsync, libapache2-request-perl, libjson-perl, libdigest-sha1-perl, vncterm, qemu-server (>= 1.1-1), libwww-perl, wget, libnet-dns-perl, vlan, ifenslave-2.6 (>= 1.1.0-10), liblinux-inotify2-perl, debconf (>= 0.5) | debconf-2.0, libjs-prototype (>= 1.6.0.3-1), netcat-traditional, pve-cluster, libpve-common-perl, libpve-storage-perl, libterm-readline-gnu-perl, libhttp-request-params-perl, libpve-access-control, libio-socket-ssl-perl, libfilesys-df-perl, librrds-perl, rrdcached, libfile-readbackwards-perl
 Conflicts: netcat-openbsd
 Maintainer: Proxmox Support Team <support at proxmox.com>
 Description: The Proxmox Virtual Environment

Modified: pve-manager/pve2/lib/PVE/API2/Nodes.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2/Nodes.pm	2011-03-22 05:59:50 UTC (rev 5738)
+++ pve-manager/pve2/lib/PVE/API2/Nodes.pm	2011-03-22 06:01:37 UTC (rev 5739)
@@ -3,6 +3,7 @@
 use strict;
 use warnings;
 use POSIX;
+use File::ReadBackwards;
 use Filesys::Df;
 use Time::Local qw(timegm_nocheck);
 use PVE::pvecfg;
@@ -49,7 +50,7 @@
     path => '', 
     method => 'GET',
     permissions => { user => 'all' },
-    description => "Cluster index.",
+    description => "Node index.",
     parameters => {
     	additionalProperties => 0,
 	properties => {
@@ -70,6 +71,7 @@
 	my $result = [
 	    { name => 'syslog' },
 	    { name => 'status' },
+	    { name => 'tasks' },
 	    { name => 'rrd' }, # fixme: remove?
 	    { name => 'rrddata' },# fixme: remove?
 	    { name => 'vncshell' },
@@ -160,6 +162,79 @@
     }});
 
 __PACKAGE__->register_method({
+    name => 'tasks', 
+    path => 'tasks', 
+    method => 'GET',
+    permissions => { user => 'all' },
+    description => "Read task list (finished tasks).",
+    proxyto => 'node',
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    node => get_standard_option('pve-node'),
+	    start => {
+		type => 'integer',
+		minimum => 0,
+		optional => 1,
+	    },
+	    limit => {
+		type => 'integer',
+		minimum => 0,
+		optional => 1,
+	    },
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		upid => { type => 'string' },
+	    },
+	},
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $rpcenv = PVE::RPCEnvironment::get();
+	my $user = $rpcenv->get_user();
+
+	my $res = [];
+
+	my $filename = "/var/log/pve/tasks/index";
+
+	my $bw = File::ReadBackwards->new($filename);
+	die "unable to open file '$filename' - $!\n" if !$bw;
+	
+	my $start = $param->{start} || 0;
+	my $limit = $param->{limit} || 50;
+
+	my $count = 0;
+	while (defined (my $line = $bw->readline)) {
+	    if ($line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/) {
+		my $upid = $1;
+		my $endtime = $3;
+		my $status = $5;
+		if ((my $task = PVE::Tools::upid_decode($upid, 1))) {
+		    next if $count++ < $start;
+		    next if $limit <= 0;
+
+		    $task->{upid} = $upid;
+		    $task->{endtime} = hex($endtime) if $endtime;
+		    $task->{status} = $status if $status;
+		    push @$res, $task;
+		    $limit--;
+		}
+	    }
+	}
+	$bw->close();
+
+	$rpcenv->set_result_count($count);
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method({
     name => 'rrd', 
     path => 'rrd', 
     method => 'GET',

Modified: pve-manager/pve2/lib/PVE/REST.pm
===================================================================
--- pve-manager/pve2/lib/PVE/REST.pm	2011-03-22 05:59:50 UTC (rev 5738)
+++ pve-manager/pve2/lib/PVE/REST.pm	2011-03-22 06:01:37 UTC (rev 5739)
@@ -135,7 +135,7 @@
     if (scalar(keys %{$res->{errors}})) {
 	$success = 0;
 	$new->{errors} = $res->{errors};
-    };
+    }
 
     if ($format eq 'extjs' || $format eq 'htmljs') {
 	# HACK: extjs wants 'success' property instead of useful HTTP status codes
@@ -148,6 +148,10 @@
 	$new->{success} = $success;
     }
 
+    if ($success && $res->{total}) {
+	$new->{total} = $res->{total};
+    }
+
     $res->{data} = $new;
 }
 
@@ -375,6 +379,7 @@
     $rpcenv->set_language('C'); # fixme:
     $rpcenv->set_user($username);
     $rpcenv->set_client_ip($clientip);
+    $rpcenv->set_result_count(undef);
 
     my $resp = { 
 	info => $info, # useful to format output
@@ -383,6 +388,10 @@
 
     eval {
 	$resp->{data} = $handler->handle($info, $uri_param);
+
+	if (my $count = $rpcenv->get_result_count()) {
+	    $resp->{total} = $count;
+	}
     };
     my $err = $@;
     if ($err) {

Modified: pve-manager/pve2/www/manager/NodeConfig.js
===================================================================
--- pve-manager/pve2/www/manager/NodeConfig.js	2011-03-22 05:59:50 UTC (rev 5738)
+++ pve-manager/pve2/www/manager/NodeConfig.js	2011-03-22 06:01:37 UTC (rev 5739)
@@ -1322,6 +1322,96 @@
 });
 Ext.reg('pveNodeSummaryView', PVE.NodeSummaryView);
 
+PVE.NodeTasks = Ext.extend(Ext.grid.GridPanel, {
+
+    initComponent : function() {
+	var self = this;
+
+	var nodename = self.nodename;
+
+	if (!nodename) 
+	    throw "no node name specified";
+
+	var fields = [ 
+	    { name: 'starttime', type : 'date', dateFormat: 'timestamp' }, 
+	    { name: 'endtime', type : 'date', dateFormat: 'timestamp' }, 
+	    { name: 'pid', type: 'int' },
+	    'node', 'upid', 'user', 'status', 'type', 'id'];
+
+	var taskstore = new Ext.data.JsonStore({
+	    autoDestroy: true,
+	    url: '/api2/json/nodes/' + nodename + '/tasks',
+	    idProperty: 'upid',
+	    root: 'data',
+	    fields: fields,
+	    restful: true
+	});
+
+	var page_size = 10;
+
+	taskstore.load({
+	    params: {
+		// specify params for the first page load if using paging
+		start: 0,          
+		limit: page_size,
+	    }
+	});
+
+	Ext.apply(self, {
+	    store: taskstore,
+	    border: false,
+	    //columnSort: false,
+	    autoExpandColumn: 'status',
+	    viewConfig: {
+		getRowClass: function(record, index) {
+		    var status = record.get('status');
+
+		    if (status && status != 'OK') 
+			return "x-form-invalid";
+		}
+	    },
+	    bbar: new Ext.PagingToolbar({
+		store: taskstore,       // grid and PagingToolbar using same store
+		displayInfo: true,
+		pageSize: page_size,
+	    }),
+	    columns: [
+		{ header: "Start Time", dataIndex: 'starttime',
+		  width: 100,
+		  renderer: function(value) { return value.format("M d H:i:s"); }
+		},
+		{ header: "End Time", dataIndex: 'endtime',
+		  width: 100,
+		  renderer: function(value, metaData, record) {
+		      return value.format("M d H:i:s"); 
+		  }
+		},
+		{ header: "Node", dataIndex: 'node',
+		  width: 100
+		},
+		{ header: "User", dataIndex: 'user',
+		  width: 150
+		},
+		{ id: 'desc', header: "Description", dataIndex: 'upid', 
+		  width: 400,
+		  renderer: PVE.Utils.render_upid
+		},
+		{ id: 'status', header: "Status", dataIndex: 'status', 
+		  width: 200,
+		  renderer: function(value, metaData, record) { 
+		      if (value == 'OK')
+			  return 'OK';
+		      // metaData.attr = 'style="color:red;"'; 
+		      return "ERROR: " + value;
+		  }
+		}
+	    ]});
+
+	PVE.NodeTasks.superclass.initComponent.call(self);
+    }
+});
+Ext.reg('pveNodeTasks', PVE.NodeTasks);
+
 PVE.NodeConfig = Ext.extend(PVE.ConfigPanel, {
 
     initComponent : function() {
@@ -1366,6 +1456,12 @@
 		    id: 'time',
 		    xtype: 'pveNodeTimeView',
 		    nodename: nodename
+		},
+		{
+		    title: 'Tasks',
+		    id: 'tasks',
+		    xtype: 'pveNodeTasks',
+		    nodename: nodename
 		}
 	    ]
 	});



More information about the pve-devel mailing list