]>
git.proxmox.com Git - pve-manager.git/blob - PVE/API2/Tasks.pm
1 package PVE
:: API2
:: Tasks
;
7 use File
:: ReadBackwards
;
12 use PVE
:: RPCEnvironment
;
13 use PVE
:: JSONSchema
qw(get_standard_option) ;
14 use PVE
:: Exception
qw(raise_param_exc) ;
15 use PVE
:: AccessControl
;
17 use base
qw(PVE::RESTHandler) ;
19 __PACKAGE__-
> register_method ({
24 description
=> "List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/<node> (the <node> the task runs on)." ,
27 description
=> "Read task list for one node (finished tasks)." ,
30 additionalProperties
=> 0 ,
32 node
=> get_standard_option
( 'pve-node' ),
38 description
=> "List tasks beginning from this offset." ,
45 description
=> "Only list this amount of tasks." ,
50 description
=> "Only list tasks from this user." ,
52 vmid
=> get_standard_option
( 'pve-vmid' , {
53 description
=> "Only list tasks for this VM." ,
68 upid
=> { type
=> 'string' , title
=> 'UPID' , },
69 id
=> { type
=> 'string' , optional
=> 1 , title
=> 'ID' , },
70 pid
=> { type
=> 'integer' , optional
=> 1 , title
=> 'PID' , },
71 pstart
=> { type
=> 'integer' , optional
=> 1 , },
72 status
=> { type
=> 'string' , optional
=> 1 , title
=> 'Status' , },
73 type
=> { type
=> 'string' , optional
=> 1 , title
=> 'Type' , },
74 node
=> { type
=> 'string' , optional
=> 1 , title
=> 'Node' , },
75 user
=> { type
=> 'string' , optional
=> 1 , title
=> 'User' , },
76 starttime
=> { type
=> 'integer' , optional
=> 1 , title
=> 'Starttime' , },
77 endtime
=> { type
=> 'integer' , optional
=> 1 , title
=> 'Endtime' , },
80 links
=> [ { rel
=> 'child' , href
=> "{upid}" } ],
85 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
86 my $user = $rpcenv -> get_user ();
90 my $filename = "/var/log/pve/tasks/index" ;
92 my $node = $param ->{ node
};
93 my $start = $param ->{ start
} // 0 ;
94 my $limit = $param ->{ limit
} // 50 ;
95 my $userfilter = $param ->{ userfilter
};
96 my $errors = $param ->{ errors
} // 0 ;
101 my $auditor = $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Audit' ], 1 );
103 my $parse_line = sub {
104 if ( $line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/ ) {
108 if (( my $task = PVE
:: Tools
:: upid_decode
( $upid, 1 ))) {
109 return if $userfilter && $task ->{ user
} !~ m/\Q$userfilter\E/i ;
110 return if !( $auditor || $user eq $task ->{ user
});
112 return if $errors && $status && $status eq 'OK' ;
114 return if $param ->{ vmid
} && (! $task ->{ id
} || $task ->{ id
} ne $param ->{ vmid
});
116 return if $count++ < $start ;
117 return if $limit <= 0 ;
119 $task ->{ upid
} = $upid ;
120 $task ->{ endtime
} = hex ( $endtime ) if $endtime ;
121 $task ->{ status
} = $status if $status ;
128 if ( my $bw = File
:: ReadBackwards-
> new ( $filename )) {
129 while ( defined ( $line = $bw -> readline )) {
134 if ( my $bw = File
:: ReadBackwards-
> new ( " $filename .1" )) {
135 while ( defined ( $line = $bw -> readline )) {
141 $rpcenv -> set_result_attrib ( 'total' , $count );
146 __PACKAGE__-
> register_method ({
147 name
=> 'upid_index' ,
150 description
=> '' , # index helper
151 permissions
=> { user
=> 'all' },
153 additionalProperties
=> 0 ,
155 node
=> get_standard_option
( 'pve-node' ),
156 upid
=> { type
=> 'string' },
165 links
=> [ { rel
=> 'child' , href
=> "{name}" } ],
176 __PACKAGE__-
> register_method ({
180 description
=> 'Stop a task.' ,
182 description
=> "The user needs 'Sys.Modify' permissions on '/nodes/<node>' if the task does not belong to him." ,
188 additionalProperties
=> 0 ,
190 node
=> get_standard_option
( 'pve-node' ),
191 upid
=> { type
=> 'string' },
194 returns
=> { type
=> 'null' },
198 my ( $task, $filename ) = PVE
:: Tools
:: upid_decode
( $param ->{ upid
}, 1 );
199 raise_param_exc
({ upid
=> "unable to parse worker upid" }) if ! $task ;
200 raise_param_exc
({ upid
=> "no such task" }) if ! - f
$filename ;
202 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
203 my $user = $rpcenv -> get_user ();
204 my $node = $param ->{ node
};
206 if ( $user ne $task ->{ user
}) {
207 $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Modify' ]);
210 PVE
:: RPCEnvironment-
> check_worker ( $param ->{ upid
}, 1 );
215 __PACKAGE__-
> register_method ({
216 name
=> 'read_task_log' ,
217 path
=> '{upid}/log' ,
220 description
=> "The user needs 'Sys.Audit' permissions on '/nodes/<node>' if the task does not belong to him." ,
224 description
=> "Read task log." ,
227 additionalProperties
=> 0 ,
229 node
=> get_standard_option
( 'pve-node' ),
230 upid
=> { type
=> 'string' },
251 description
=> "Line number" ,
255 description
=> "Line text" ,
264 my ( $task, $filename ) = PVE
:: Tools
:: upid_decode
( $param ->{ upid
}, 1 );
265 raise_param_exc
({ upid
=> "unable to parse worker upid" }) if ! $task ;
267 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
268 my $user = $rpcenv -> get_user ();
269 my $node = $param ->{ node
};
270 my $start = $param ->{ start
} // 0 ;
271 my $limit = $param ->{ limit
} // 50 ;
273 if ( $user ne $task ->{ user
}) {
274 $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Audit' ]);
277 my ( $count, $lines ) = PVE
:: Tools
:: dump_logfile
( $filename, $start, $limit );
279 $rpcenv -> set_result_attrib ( 'total' , $count );
285 my $exit_status_cache = {};
287 __PACKAGE__-
> register_method ({
288 name
=> 'read_task_status' ,
289 path
=> '{upid}/status' ,
292 description
=> "The user needs 'Sys.Audit' permissions on '/nodes/<node>' if the task does not belong to him." ,
296 description
=> "Read task status." ,
299 additionalProperties
=> 0 ,
301 node
=> get_standard_option
( 'pve-node' ),
302 upid
=> { type
=> 'string' },
312 type
=> 'string' , enum
=> [ 'running' , 'stopped' ],
319 my ( $task, $filename ) = PVE
:: Tools
:: upid_decode
( $param ->{ upid
}, 1 );
320 raise_param_exc
({ upid
=> "unable to parse worker upid" }) if ! $task ;
321 raise_param_exc
({ upid
=> "no such task" }) if ! - f
$filename ;
325 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
326 my $user = $rpcenv -> get_user ();
327 my $node = $param ->{ node
};
329 if ( $user ne $task ->{ user
}) {
330 $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Audit' ]);
333 my $pstart = PVE
:: ProcFSTools
:: read_proc_starttime
( $task ->{ pid
});
334 $task ->{ status
} = ( $pstart && ( $pstart == $task ->{ pstart
})) ?
335 'running' : 'stopped' ;
337 $task ->{ upid
} = $param ->{ upid
}; # include upid
339 if ( $task ->{ status
} eq 'stopped' ) {
340 if (! defined ( $exit_status_cache ->{ $task ->{ upid
}})) {
341 $exit_status_cache ->{ $task ->{ upid
}} =
342 PVE
:: Tools
:: upid_read_status
( $task ->{ upid
});
344 $task ->{ exitstatus
} = $exit_status_cache ->{ $task ->{ upid
}};