[pve-devel] [PATCH pve-manager] PVE::API2::Replication: rework replication status API

Dietmar Maurer dietmar at proxmox.com
Thu Jun 8 07:29:21 CEST 2017


/nodes/<node>/replication => list status of all jobs

/nodes/<node>/replication/<id>/status => individual job status

/nodes/<node>/replication/<id>/log => job log

Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
 PVE/API2/Replication.pm | 191 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 160 insertions(+), 31 deletions(-)

diff --git a/PVE/API2/Replication.pm b/PVE/API2/Replication.pm
index a57237c7..6731f096 100644
--- a/PVE/API2/Replication.pm
+++ b/PVE/API2/Replication.pm
@@ -13,15 +13,89 @@ use PVE::RESTHandler;
 
 use base qw(PVE::RESTHandler);
 
+my $extract_job_status = sub {
+    my ($jobcfg, $jobid) = @_;
+
+    # Note: we modify $jobcfg
+    my $state = delete $jobcfg->{state};
+    my $data = $jobcfg;
+
+    $data->{id} = $jobid;
+
+    foreach my $k (qw(last_sync last_try fail_count error duration)) {
+	$data->{$k} = $state->{$k} if defined($state->{$k});
+    }
+
+    if ($state->{pid} && $state->{ptime}) {
+	if (PVE::ProcFSTools::check_process_running($state->{pid}, $state->{ptime})) {
+	    $data->{pid} = $state->{pid};
+	}
+    }
+
+    return $data;
+};
+
 __PACKAGE__->register_method ({
-    name => 'index',
+    name => 'status',
     path => '',
     method => 'GET',
+    description => "List status of all replication jobs on this node.",
+    permissions => {
+	description => "Requires the VM.Audit permission on /vms/<vmid>.",
+	user => 'all',
+    },
+    protected => 1,
+    proxyto => 'node',
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    node => get_standard_option('pve-node'),
+	    guest => get_standard_option('pve-vmid', {
+		optional => 1,
+		description => "Only list replication jobs for this guest.",
+	    }),
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		id => { type => 'string' },
+	    },
+	},
+	links => [ { rel => 'child', href => "{id}" } ],
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $rpcenv = PVE::RPCEnvironment::get();
+	my $authuser = $rpcenv->get_user();
+
+	my $jobs = PVE::Replication::job_status();
+
+	my $res = [];
+	foreach my $id (sort keys %$jobs) {
+	    my $data = $extract_job_status->($jobs->{$id}, $id);
+	    my $guest = $data->{guest};
+	    next if defined($param->{guest}) && $guest != $param->{guest};
+	    next if !$rpcenv->check($authuser, "/vms/$guest", [ 'VM.Audit' ]);
+	    push @$res, $data;
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'index',
+    path => '{id}',
+    method => 'GET',
     permissions => { user => 'all' },
     description => "Directory index.",
     parameters => {
 	additionalProperties => 0,
 	properties => {
+	    id => get_standard_option('pve-replication-id'),
 	    node => get_standard_option('pve-node'),
 	},
     },
@@ -37,16 +111,17 @@ __PACKAGE__->register_method ({
 	my ($param) = @_;
 
 	return [
+	    { name => 'log' },
 	    { name => 'status' },
-	];
+	    ];
     }});
 
 
 __PACKAGE__->register_method ({
-    name => 'status',
-    path => 'status',
+    name => 'job_status',
+    path => '{id}/status',
     method => 'GET',
-    description => "List replication job status.",
+    description => "Get replication job status.",
     permissions => {
 	description => "Requires the VM.Audit permission on /vms/<vmid>.",
 	user => 'all',
@@ -56,20 +131,13 @@ __PACKAGE__->register_method ({
     parameters => {
 	additionalProperties => 0,
 	properties => {
+	    id => get_standard_option('pve-replication-id'),
 	    node => get_standard_option('pve-node'),
-	    guest => get_standard_option('pve-vmid', {
-		optional => 1,
-		description => "Only list replication jobs for this guest.",
-	    }),
 	},
     },
     returns => {
-	type => 'array',
-	items => {
-	    type => "object",
-	    properties => {},
-	},
-	links => [ { rel => 'child', href => "{id}" } ],
+	type => "object",
+	properties => {},
     },
     code => sub {
 	my ($param) = @_;
@@ -78,27 +146,88 @@ __PACKAGE__->register_method ({
 	my $authuser = $rpcenv->get_user();
 
 	my $jobs = PVE::Replication::job_status();
+	my $jobid = $param->{id};
+	my $jobcfg = $jobs->{$jobid};
 
-	my $res = [];
-	foreach my $id (sort keys %$jobs) {
-	    my $d = $jobs->{$id};
-	    my $state = delete $d->{state};
-	    my $guest = $d->{guest};
-	    next if defined($param->{guest}) && $guest != $param->{guest};
-	    next if !$rpcenv->check($authuser, "/vms/$guest", [ 'VM.Audit' ]);
-	    $d->{id} = $id;
-	    foreach my $k (qw(last_sync last_try fail_count error duration)) {
-		$d->{$k} = $state->{$k} if defined($state->{$k});
-	    }
-	    if ($state->{pid} && $state->{ptime}) {
-		if (PVE::ProcFSTools::check_process_running($state->{pid}, $state->{ptime})) {
-		    $d->{pid} = $state->{pid};
+	die "no such replication job '$jobid'\n" if !defined($jobcfg);
+
+	my $data = $extract_job_status->($jobcfg, $jobid);
+	my $guest = $data->{guest};
+
+	raise_perm_exc() if !$rpcenv->check($authuser, "/vms/$guest", [ 'VM.Audit' ]);
+
+	return $data;
+    }});
+
+__PACKAGE__->register_method({
+    name => 'read_job_log',
+    path => '{id}/log',
+    method => 'GET',
+    permissions => {
+	description => "Requires the VM.Audit permission on /vms/<vmid>, or 'Sys.Audit' on '/nodes/<node>'",
+	user => 'all',
+    },
+    protected => 1,
+    description => "Read replication job log.",
+    proxyto => 'node',
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    id => get_standard_option('pve-replication-id'),
+	    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 => {
+		n => {
+		  description=>  "Line number",
+		  type=> 'integer',
+		},
+		t => {
+		  description=>  "Line text",
+		  type => 'string',
 		}
 	    }
-	    push @$res, $d;
 	}
+    },
+    code => sub {
+	my ($param) = @_;
 
-	return $res;
+	my $rpcenv = PVE::RPCEnvironment::get();
+	my $authuser = $rpcenv->get_user();
+
+	my $jobid = $param->{id};
+	my $filename = PVE::Replication::job_logfile_name($jobid);
+
+	my $cfg = PVE::ReplicationConfig->new();
+	my $data = $cfg->{ids}->{$jobid};
+
+	die "no such replication job '$jobid'\n" if !defined($data);
+
+	my $node = $param->{node};
+
+	my $vmid = $data->{guest};
+	raise_perm_exc() if (!($rpcenv->check($authuser, "/vms/$vmid", [ 'VM.Audit' ]) ||
+			       $rpcenv->check($authuser, "/nodes/$node", [ 'Sys.Audit' ])));
+
+	my ($count, $lines) = PVE::Tools::dump_logfile($filename, $param->{start}, $param->{limit});
+
+	$rpcenv->set_result_attrib('total', $count);
+
+	return $lines;
     }});
 
 1;
-- 
2.11.0




More information about the pve-devel mailing list