]> git.proxmox.com Git - pve-manager.git/blame - PVE/API2/Services.pm
api/services: whitespace cleanup, modern closure call
[pve-manager.git] / PVE / API2 / Services.pm
CommitLineData
aff192e6
DM
1package PVE::API2::Services;
2
3use strict;
4use warnings;
5
6use PVE::Tools;
7use PVE::SafeSyslog;
8use PVE::Cluster;
9use PVE::INotify;
10use PVE::Exception qw(raise_param_exc);
11use PVE::RESTHandler;
12use PVE::RPCEnvironment;
13use PVE::JSONSchema qw(get_standard_option);
14use PVE::AccessControl;
15use IO::File;
16
17use base qw(PVE::RESTHandler);
18
50d4dc17 19my $service_name_list = [
05d5632d 20 'pveproxy',
50d4dc17
DM
21 'pvedaemon',
22 'spiceproxy',
23 'pvestatd',
24 'pve-cluster',
25 'corosync',
26 'pve-firewall',
27 'pvefw-logger',
28 'pve-ha-crm',
29 'pve-ha-lrm',
30 'sshd',
31 'syslog',
32 'cron',
33 'postfix',
04fb6e38 34 'ksmtuned',
28b699bc 35 'systemd-timesyncd',
05d5632d 36];
50d4dc17 37
7a581660
EK
38# since postfix package 3.1.0-3.1 the postfix unit is only here to
39# manage subinstances, of which the default is called "-".
40# This is where we look for the daemon status
41my $unit_extra_names = {
42 postfix => 'postfix@-'
43};
44
50d4dc17
DM
45my $get_full_service_state = sub {
46 my ($service) = @_;
7a581660 47 $service = $unit_extra_names->{$service} if $unit_extra_names->{$service};
50d4dc17 48 my $res;
05d5632d 49
50d4dc17
DM
50 my $parser = sub {
51 my $line = shift;
52 if ($line =~ m/^([^=\s]+)=(.*)$/) {
53 $res->{$1} = $2;
54 }
55 };
56
05d5632d
TL
57 PVE::Tools::run_command(['systemctl', 'show', $service], outfunc => $parser);
58
50d4dc17 59 return $res;
aff192e6
DM
60};
61
50d4dc17
DM
62my $static_service_list;
63
64sub get_service_list {
65
66 return $static_service_list if $static_service_list;
05d5632d 67
50d4dc17
DM
68 my $list = {};
69 foreach my $name (@$service_name_list) {
70 my $ss;
71 eval { $ss = &$get_full_service_state($name); };
72 warn $@ if $@;
73 next if !$ss;
74 next if !defined($ss->{Description});
75 $list->{$name} = { name => $name, desc => $ss->{Description} };
76 }
77
78 $static_service_list = $list;
05d5632d 79
50d4dc17
DM
80 return $static_service_list;
81}
82
83
c661ad50
DM
84my $service_prop_desc = {
85 description => "Service ID",
86 type => 'string',
50d4dc17 87 enum => $service_name_list,
c661ad50
DM
88};
89
aff192e6
DM
90my $service_cmd = sub {
91 my ($service, $cmd) = @_;
92
93 my $initd_cmd;
94
95 die "unknown service command '$cmd'\n"
96 if $cmd !~ m/^(start|stop|restart|reload)$/;
97
50d4dc17 98 if ($service eq 'pvecluster' || $service eq 'pvedaemon' || $service eq 'pveproxy') {
aff192e6 99 if ($cmd eq 'restart') {
50d4dc17 100 # OK
aff192e6
DM
101 } else {
102 die "invalid service cmd '$service $cmd': ERROR";
103 }
50d4dc17
DM
104 }
105
106 PVE::Tools::run_command(['systemctl', $cmd, $service]);
aff192e6
DM
107};
108
109my $service_state = sub {
110 my ($service) = @_;
111
50d4dc17
DM
112 my $ss;
113 eval { $ss = &$get_full_service_state($service); };
114 if (my $err = $@) {
115 return 'unknown';
aff192e6
DM
116 }
117
50d4dc17 118 return $ss->{SubState} if $ss->{SubState};
aff192e6 119
50d4dc17 120 return 'unknown';
aff192e6
DM
121};
122
123__PACKAGE__->register_method ({
124 name => 'index',
125 path => '',
126 method => 'GET',
127 permissions => {
7d020b42 128 check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
aff192e6
DM
129 },
130 description => "Service list.",
131 proxyto => 'node',
132 protected => 1,
133 parameters => {
134 additionalProperties => 0,
135 properties => {
136 node => get_standard_option('pve-node'),
137 },
138 },
139 returns => {
140 type => 'array',
141 items => {
142 type => "object",
143 properties => {},
144 },
145 links => [ { rel => 'child', href => "{service}" } ],
146 },
147 code => sub {
148 my ($param) = @_;
149
150 my $res = [];
151
50d4dc17
DM
152 my $service_list = get_service_list();
153
aff192e6
DM
154 foreach my $id (keys %{$service_list}) {
155 push @$res, {
156 service => $id,
157 name => $service_list->{$id}->{name},
158 desc => $service_list->{$id}->{desc},
159 state => &$service_state($id),
160 };
161 }
162
163 return $res;
164 }});
165
c661ad50
DM
166__PACKAGE__->register_method({
167 name => 'srvcmdidx',
aff192e6
DM
168 path => '{service}',
169 method => 'GET',
c661ad50 170 description => "Directory index",
461e4a46
DM
171 permissions => {
172 check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
173 },
c661ad50
DM
174 parameters => {
175 additionalProperties => 0,
176 properties => {
177 node => get_standard_option('pve-node'),
178 service => $service_prop_desc,
179 },
180 },
181 returns => {
182 type => 'array',
183 items => {
184 type => "object",
185 properties => {
186 subdir => { type => 'string' },
187 },
188 },
189 links => [ { rel => 'child', href => "{subdir}" } ],
190 },
191 code => sub {
192 my ($param) = @_;
193
194 my $res = [
195 { subdir => 'state' },
196 { subdir => 'start' },
197 { subdir => 'stop' },
198 { subdir => 'restart' },
199 { subdir => 'reload' },
200 ];
201
202 return $res;
203 }});
204
205__PACKAGE__->register_method ({
206 name => 'service_state',
207 path => '{service}/state',
208 method => 'GET',
aff192e6 209 permissions => {
7d020b42 210 check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
aff192e6
DM
211 },
212 description => "Read service properties",
213 proxyto => 'node',
214 protected => 1,
215 parameters => {
216 additionalProperties => 0,
217 properties => {
218 node => get_standard_option('pve-node'),
c661ad50 219 service => $service_prop_desc,
aff192e6
DM
220 },
221 },
222 returns => {
223 type => "object",
224 properties => {},
225 },
226 code => sub {
227 my ($param) = @_;
228
50d4dc17
DM
229 my $service_list = get_service_list();
230
aff192e6
DM
231 my $si = $service_list->{$param->{service}};
232 return {
233 service => $param->{service},
234 name => $si->{name},
235 desc => $si->{desc},
236 state => &$service_state($param->{service}),
237 };
238 }});
239
240__PACKAGE__->register_method ({
c661ad50
DM
241 name => 'service_start',
242 path => '{service}/start',
243 method => 'POST',
244 description => "Start service.",
461e4a46
DM
245 permissions => {
246 check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
247 },
aff192e6
DM
248 proxyto => 'node',
249 protected => 1,
250 parameters => {
251 additionalProperties => 0,
252 properties => {
253 node => get_standard_option('pve-node'),
c661ad50
DM
254 service => $service_prop_desc,
255 },
256 },
257 returns => {
258 type => 'string',
259 },
260 code => sub {
261 my ($param) = @_;
262
263 my $rpcenv = PVE::RPCEnvironment::get();
264
265 my $user = $rpcenv->get_user();
266
c661ad50
DM
267 my $realcmd = sub {
268 my $upid = shift;
269
270 syslog('info', "starting service $param->{service}: $upid\n");
271
05d5632d 272 $service_cmd->($param->{service}, 'start');
c661ad50
DM
273
274 };
275
276 return $rpcenv->fork_worker('srvstart', $param->{service}, $user, $realcmd);
277 }});
278
279__PACKAGE__->register_method ({
280 name => 'service_stop',
281 path => '{service}/stop',
282 method => 'POST',
283 description => "Stop service.",
461e4a46
DM
284 permissions => {
285 check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
286 },
c661ad50
DM
287 proxyto => 'node',
288 protected => 1,
289 parameters => {
290 additionalProperties => 0,
291 properties => {
292 node => get_standard_option('pve-node'),
293 service => $service_prop_desc,
294 },
295 },
296 returns => {
297 type => 'string',
298 },
299 code => sub {
300 my ($param) = @_;
301
302 my $rpcenv = PVE::RPCEnvironment::get();
303
304 my $user = $rpcenv->get_user();
305
c661ad50
DM
306 my $realcmd = sub {
307 my $upid = shift;
308
76189130 309 syslog('info', "stopping service $param->{service}: $upid\n");
c661ad50 310
05d5632d 311 $service_cmd->($param->{service}, 'stop');
c661ad50
DM
312
313 };
314
315 return $rpcenv->fork_worker('srvstop', $param->{service}, $user, $realcmd);
316 }});
317
318__PACKAGE__->register_method ({
05d5632d
TL
319 name => 'service_restart',
320 path => '{service}/restart',
c661ad50
DM
321 method => 'POST',
322 description => "Restart service.",
461e4a46
DM
323 permissions => {
324 check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
325 },
c661ad50
DM
326 proxyto => 'node',
327 protected => 1,
328 parameters => {
05d5632d 329 additionalProperties => 0,
c661ad50
DM
330 properties => {
331 node => get_standard_option('pve-node'),
332 service => $service_prop_desc,
aff192e6
DM
333 },
334 },
c661ad50
DM
335 returns => {
336 type => 'string',
337 },
aff192e6
DM
338 code => sub {
339 my ($param) = @_;
c661ad50 340
05d5632d 341 my $rpcenv = PVE::RPCEnvironment::get();
c661ad50
DM
342 my $user = $rpcenv->get_user();
343
c661ad50
DM
344 my $realcmd = sub {
345 my $upid = shift;
c661ad50
DM
346 syslog('info', "re-starting service $param->{service}: $upid\n");
347
05d5632d 348 $service_cmd->($param->{service}, 'restart');
c661ad50
DM
349 };
350
351 return $rpcenv->fork_worker('srvrestart', $param->{service}, $user, $realcmd);
352 }});
353
354__PACKAGE__->register_method ({
05d5632d
TL
355 name => 'service_reload',
356 path => '{service}/reload',
c661ad50
DM
357 method => 'POST',
358 description => "Reload service.",
461e4a46
DM
359 permissions => {
360 check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
361 },
c661ad50
DM
362 proxyto => 'node',
363 protected => 1,
364 parameters => {
05d5632d 365 additionalProperties => 0,
c661ad50
DM
366 properties => {
367 node => get_standard_option('pve-node'),
368 service => $service_prop_desc,
369 },
370 },
371 returns => {
372 type => 'string',
373 },
374 code => sub {
375 my ($param) = @_;
c661ad50 376
05d5632d 377 my $rpcenv = PVE::RPCEnvironment::get();
c661ad50
DM
378 my $user = $rpcenv->get_user();
379
c661ad50
DM
380 my $realcmd = sub {
381 my $upid = shift;
c661ad50
DM
382 syslog('info', "reloading service $param->{service}: $upid\n");
383
05d5632d 384 $service_cmd->($param->{service}, 'reload');
c661ad50
DM
385
386 };
387
388 return $rpcenv->fork_worker('srvreload', $param->{service}, $user, $realcmd);
aff192e6 389 }});