]>
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
:: AccessControl
;
16 use base
qw(PVE::RESTHandler) ;
18 __PACKAGE__-
> register_method ({
23 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)." ,
26 description
=> "Read task list for one node (finished tasks)." ,
29 additionalProperties
=> 0 ,
31 node
=> get_standard_option
( 'pve-node' ),
46 vmid
=> get_standard_option
( 'pve-vmid' , {
47 description
=> "Only list tasks for this VM." ,
61 upid
=> { type
=> 'string' },
64 links
=> [ { rel
=> 'child' , href
=> "{upid}" } ],
69 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
70 my $user = $rpcenv -> get_user ();
74 my $filename = "/var/log/pve/tasks/index" ;
76 my $node = $param ->{ node
};
77 my $start = $param ->{ start
} || 0 ;
78 my $limit = $param ->{ limit
} || 50 ;
79 my $userfilter = $param ->{ userfilter
};
80 my $errors = $param ->{ errors
};
85 my $auditor = $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Audit' ], 1 );
87 my $parse_line = sub {
88 if ( $line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/ ) {
92 if (( my $task = PVE
:: Tools
:: upid_decode
( $upid, 1 ))) {
93 return if $userfilter && $task ->{ user
} !~ m/\Q$userfilter\E/i ;
94 return if !( $auditor || $user eq $task ->{ user
});
96 return if $errors && $status && $status eq 'OK' ;
98 return if $param ->{ vmid
} && (! $task ->{ id
} || $task ->{ id
} ne $param ->{ vmid
});
100 return if $count++ < $start ;
101 return if $limit <= 0 ;
103 $task ->{ upid
} = $upid ;
104 $task ->{ endtime
} = hex ( $endtime ) if $endtime ;
105 $task ->{ status
} = $status if $status ;
112 if ( my $bw = File
:: ReadBackwards-
> new ( $filename )) {
113 while ( defined ( $line = $bw -> readline )) {
118 if ( my $bw = File
:: ReadBackwards-
> new ( " $filename .1" )) {
119 while ( defined ( $line = $bw -> readline )) {
125 $rpcenv -> set_result_attrib ( 'total' , $count );
130 __PACKAGE__-
> register_method ({
131 name
=> 'upid_index' ,
134 description
=> '' , # index helper
135 permissions
=> { user
=> 'all' },
137 additionalProperties
=> 0 ,
139 node
=> get_standard_option
( 'pve-node' ),
140 upid
=> { type
=> 'string' },
149 links
=> [ { rel
=> 'child' , href
=> "{name}" } ],
160 __PACKAGE__-
> register_method ({
164 description
=> 'Stop a task.' ,
166 description
=> "The user needs 'Sys.Modify' permissions on '/nodes/<node>' if the task does not belong to him." ,
172 additionalProperties
=> 0 ,
174 node
=> get_standard_option
( 'pve-node' ),
175 upid
=> { type
=> 'string' },
178 returns
=> { type
=> 'null' },
182 my ( $task, $filename ) = PVE
:: Tools
:: upid_decode
( $param ->{ upid
}, 1 );
183 raise_param_exc
({ upid
=> "unable to parse worker upid" }) if ! $task ;
184 raise_param_exc
({ upid
=> "no such task" }) if ! - f
$filename ;
186 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
187 my $user = $rpcenv -> get_user ();
188 my $node = $param ->{ node
};
190 if ( $user ne $task ->{ user
}) {
191 $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Modify' ]);
194 PVE
:: RPCEnvironment-
> check_worker ( $param ->{ upid
}, 1 );
199 __PACKAGE__-
> register_method ({
200 name
=> 'read_task_log' ,
201 path
=> '{upid}/log' ,
204 description
=> "The user needs 'Sys.Audit' permissions on '/nodes/<node>' if the task does not belong to him." ,
208 description
=> "Read task log." ,
211 additionalProperties
=> 0 ,
213 node
=> get_standard_option
( 'pve-node' ),
214 upid
=> { type
=> 'string' },
233 description
=> "Line number" ,
237 description
=> "Line text" ,
246 my ( $task, $filename ) = PVE
:: Tools
:: upid_decode
( $param ->{ upid
}, 1 );
247 raise_param_exc
({ upid
=> "unable to parse worker upid" }) if ! $task ;
251 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
252 my $user = $rpcenv -> get_user ();
253 my $node = $param ->{ node
};
255 if ( $user ne $task ->{ user
}) {
256 $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Audit' ]);
259 my $fh = IO
:: File-
> new ( $filename, "r" );
260 raise_param_exc
({ upid
=> "no such task - unable to open file - $! " }) if ! $fh ;
262 my $start = $param ->{ start
} || 0 ;
263 my $limit = $param ->{ limit
} || 50 ;
266 while ( defined ( $line = < $fh >)) {
267 next if $count++ < $start ;
270 push @$lines, { n
=> $count, t
=> $line };
276 # HACK: ExtJS store.guaranteeRange() does not like empty array
280 push @$lines, { n
=> $count, t
=> "no content" };
283 $rpcenv -> set_result_attrib ( 'total' , $count );
289 my $exit_status_cache = {};
291 __PACKAGE__-
> register_method ({
292 name
=> 'read_task_status' ,
293 path
=> '{upid}/status' ,
296 description
=> "The user needs 'Sys.Audit' permissions on '/nodes/<node>' if the task does not belong to him." ,
300 description
=> "Read task status." ,
303 additionalProperties
=> 0 ,
305 node
=> get_standard_option
( 'pve-node' ),
306 upid
=> { type
=> 'string' },
316 type
=> 'string' , enum
=> [ 'running' , 'stopped' ],
323 my ( $task, $filename ) = PVE
:: Tools
:: upid_decode
( $param ->{ upid
}, 1 );
324 raise_param_exc
({ upid
=> "unable to parse worker upid" }) if ! $task ;
325 raise_param_exc
({ upid
=> "no such task" }) if ! - f
$filename ;
329 my $rpcenv = PVE
:: RPCEnvironment
:: get
();
330 my $user = $rpcenv -> get_user ();
331 my $node = $param ->{ node
};
333 if ( $user ne $task ->{ user
}) {
334 $rpcenv -> check ( $user, "/nodes/ $node " , [ 'Sys.Audit' ]);
337 my $pstart = PVE
:: ProcFSTools
:: read_proc_starttime
( $task ->{ pid
});
338 $task ->{ status
} = ( $pstart && ( $pstart == $task ->{ pstart
})) ?
339 'running' : 'stopped' ;
341 $task ->{ upid
} = $param ->{ upid
}; # include upid
343 if ( $task ->{ status
} eq 'stopped' ) {
344 if (! defined ( $exit_status_cache ->{ $task ->{ upid
}})) {
345 $exit_status_cache ->{ $task ->{ upid
}} =
346 PVE
:: Tools
:: upid_read_status
( $task ->{ upid
});
348 $task ->{ exitstatus
} = $exit_status_cache ->{ $task ->{ upid
}};