]> git.proxmox.com Git - pve-manager.git/commitdiff
PVE::API2::Replication: rework replication status API
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 8 Jun 2017 05:08:33 +0000 (07:08 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 8 Jun 2017 05:16:39 +0000 (07:16 +0200)
/nodes/<node>/replication => list status of all jobs

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

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

PVE/API2/Replication.pm

index a57237c7356bb6aac3c7fb85cc83d2a2cbd1b254..6731f096071705509be02be16175380a8da307ec 100644 (file)
@@ -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;