otherwise there is no way to find out about (all) active tasks over the
API if their UPIDs were not recorded when the initial API calls happened.

Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
---

Notes:
    changed from v2:
    - set fake 'RUNNING' status for tasks from 'active' source
    
    changed from v1:
    - moved from bool to tri-state as suggested by W.Bumiller
    - previously called 'task index: optionally include active tasks'
    
    this is a nice addition for external monitoring/dashboard/UI
    applications, e.g. see #1997

 PVE/API2/Tasks.pm | 69 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 50 insertions(+), 19 deletions(-)

diff --git a/PVE/API2/Tasks.pm b/PVE/API2/Tasks.pm
index a5acb118..0f2a622b 100644
--- a/PVE/API2/Tasks.pm
+++ b/PVE/API2/Tasks.pm
@@ -58,6 +58,13 @@ __PACKAGE__->register_method({
                default => 0,
                optional => 1,
            },
+           source => {
+               type => 'string',
+               enum => ['archive', 'active', 'all'],
+               default => 'archive',
+               optional => 1,
+               description => 'List archived, active or all tasks.',
+           },
        },
     },
     returns => {
@@ -94,48 +101,72 @@ __PACKAGE__->register_method({
        my $limit = $param->{limit} // 50;
        my $userfilter = $param->{userfilter};
        my $errors = $param->{errors} // 0;
+       my $source = $param->{source} // 'archive';
 
        my $count = 0;
        my $line;
 
        my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ], 1);
 
+       my $filter_task = sub {
+           my $task = shift;
+
+           return 1 if $userfilter && $task->{user} !~ m/\Q$userfilter\E/i;
+           return 1 if !($auditor || $user eq $task->{user});
+
+           return 1 if $errors && $task->{status} && $task->{status} eq 'OK';
+           return 1 if $param->{vmid} && (!$task->{id} || $task->{id} ne 
$param->{vmid});
+
+           return 1 if $count++ < $start;
+           return 1 if $limit <= 0;
+
+           return 0;
+       };
+
        my $parse_line = sub {
            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))) {
-                   return if $userfilter && $task->{user} !~ 
m/\Q$userfilter\E/i;
-                   return if !($auditor || $user eq $task->{user});
-
-                   return if $errors && $status && $status eq 'OK';
-
-                   return if $param->{vmid} && (!$task->{id} || $task->{id} ne 
$param->{vmid});
-
-                   return if $count++ < $start;
-                   return if $limit <= 0;
 
                    $task->{upid} = $upid;
                    $task->{endtime} = hex($endtime) if $endtime;
                    $task->{status} = $status if $status;
-                   push @$res, $task;
-                   $limit--;
+
+                   if (!$filter_task->($task)) {
+                       push @$res, $task;
+                       $limit--;
+                   }
                }
            }
        };
 
-       if (my $bw = File::ReadBackwards->new($filename)) {
-           while (defined ($line = $bw->readline)) {
-               &$parse_line();
+       if ($source eq 'active' || $source eq 'all') {
+           my $recent_tasks = PVE::INotify::read_file('active');
+           for my $task (@$recent_tasks) {
+               next if $task->{saved}; # archived task, already in index(.1)
+               if (!$filter_task->($task)) {
+                   $task->{status} = 'RUNNING' if !$task->{status}; # 
otherwise it would be archived
+                   push @$res, $task;
+                   $limit--;
+               }
            }
-           $bw->close();
        }
-       if (my $bw = File::ReadBackwards->new("$filename.1")) {
-           while (defined ($line = $bw->readline)) {
-               &$parse_line();
+
+       if ($source ne 'active') {
+           if (my $bw = File::ReadBackwards->new($filename)) {
+               while (defined ($line = $bw->readline)) {
+                   &$parse_line();
+               }
+               $bw->close();
+           }
+           if (my $bw = File::ReadBackwards->new("$filename.1")) {
+               while (defined ($line = $bw->readline)) {
+                   &$parse_line();
+               }
+               $bw->close();
            }
-           $bw->close();
        }
 
        $rpcenv->set_result_attrib('total', $count);
-- 
2.20.1


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to