]> git.proxmox.com Git - pve-container.git/blame - src/PVE/API2/LXC/Status.pm
api: stop: reword overrule-shutdown parameter description
[pve-container.git] / src / PVE / API2 / LXC / Status.pm
CommitLineData
52389a07
DM
1package PVE::API2::LXC::Status;
2
3use strict;
4use warnings;
5
6use PVE::SafeSyslog;
7use PVE::Tools qw(extract_param run_command);
8use PVE::Exception qw(raise raise_param_exc);
9use PVE::INotify;
10use PVE::Cluster qw(cfs_read_file);
11use PVE::AccessControl;
12use PVE::Firewall;
13use PVE::Storage;
14use PVE::RESTHandler;
15use PVE::RPCEnvironment;
16use PVE::LXC;
17use PVE::LXC::Create;
52389a07 18use PVE::JSONSchema qw(get_standard_option);
17f1dc40 19
52389a07
DM
20use base qw(PVE::RESTHandler);
21
6c2e9377
WB
22BEGIN {
23 if (!$ENV{PVE_GENERATING_DOCS}) {
24 require PVE::HA::Env::PVE2;
25 import PVE::HA::Env::PVE2;
26 require PVE::HA::Config;
27 import PVE::HA::Config;
28 }
29}
52389a07
DM
30
31__PACKAGE__->register_method({
32 name => 'vmcmdidx',
33 path => '',
34 method => 'GET',
35 proxyto => 'node',
36 description => "Directory index",
37 permissions => {
38 user => 'all',
39 },
40 parameters => {
17f1dc40 41 additionalProperties => 0,
52389a07
DM
42 properties => {
43 node => get_standard_option('pve-node'),
44 vmid => get_standard_option('pve-vmid'),
45 },
46 },
47 returns => {
48 type => 'array',
49 items => {
50 type => "object",
51 properties => {
52 subdir => { type => 'string' },
53 },
54 },
55 links => [ { rel => 'child', href => "{subdir}" } ],
56 },
57 code => sub {
58 my ($param) = @_;
59
60 # test if VM exists
67afe46e 61 my $conf = PVE::LXC::Config->load_config($param->{vmid});
52389a07
DM
62
63 my $res = [
64 { subdir => 'current' },
65 { subdir => 'start' },
66 { subdir => 'stop' },
67 { subdir => 'shutdown' },
f5fe1125 68 { subdir => 'reboot' },
52389a07 69 { subdir => 'migrate' },
17f1dc40 70 ];
52389a07
DM
71
72 return $res;
73 }});
74
75__PACKAGE__->register_method({
76 name => 'vm_status',
77 path => 'current',
78 method => 'GET',
79 proxyto => 'node',
17f1dc40 80 protected => 1, # /proc entries are only readable by root
52389a07
DM
81 description => "Get virtual machine status.",
82 permissions => {
83 check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
84 },
85 parameters => {
17f1dc40 86 additionalProperties => 0,
52389a07
DM
87 properties => {
88 node => get_standard_option('pve-node'),
89 vmid => get_standard_option('pve-vmid'),
90 },
91 },
8233d33d
DM
92 returns => {
93 type => 'object',
94 properties => {
95 %$PVE::LXC::vmstatus_return_properties,
96 ha => {
97 description => "HA manager service status.",
98 type => 'object',
99 },
100 },
101 },
52389a07
DM
102 code => sub {
103 my ($param) = @_;
104
105 # test if VM exists
c83c9007
TL
106 my $vmid = $param->{vmid};
107 my $conf = PVE::LXC::Config->load_config($vmid);
52389a07 108
c83c9007
TL
109 my $vmstatus = PVE::LXC::vmstatus($vmid);
110 my $status = $vmstatus->{$vmid};
52389a07 111
c83c9007 112 $status->{ha} = PVE::HA::Config::get_service_status("ct:$vmid");
52389a07
DM
113
114 return $status;
115 }});
116
117__PACKAGE__->register_method({
118 name => 'vm_start',
119 path => 'start',
120 method => 'POST',
121 protected => 1,
122 proxyto => 'node',
123 description => "Start the container.",
124 permissions => {
125 check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
126 },
127 parameters => {
17f1dc40 128 additionalProperties => 0,
52389a07
DM
129 properties => {
130 node => get_standard_option('pve-node'),
68e8f3c5 131 vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_stopped }),
2de0b3d4 132 skiplock => get_standard_option('skiplock'),
cc9967d2
TL
133 debug => {
134 optional => 1,
135 type => 'boolean',
136 description => "If set, enables very verbose debug log-level on start.",
137 default => 0,
138 },
52389a07
DM
139 },
140 },
141 returns => {
142 type => 'string',
143 },
144 code => sub {
145 my ($param) = @_;
146
147 my $rpcenv = PVE::RPCEnvironment::get();
52389a07
DM
148 my $authuser = $rpcenv->get_user();
149
150 my $node = extract_param($param, 'node');
52389a07
DM
151 my $vmid = extract_param($param, 'vmid');
152
2de0b3d4
WB
153 my $skiplock = extract_param($param, 'skiplock');
154 raise_param_exc({ skiplock => "Only root may use this option." })
155 if $skiplock && $authuser ne 'root@pam';
156
52389a07
DM
157 die "CT $vmid already running\n" if PVE::LXC::check_running($vmid);
158
1e56e83e
WB
159 PVE::Cluster::check_cfs_quorum();
160
52389a07
DM
161 if (PVE::HA::Config::vm_is_ha_managed($vmid) && $rpcenv->{type} ne 'ha') {
162
163 my $hacmd = sub {
164 my $upid = shift;
165
545dd4e1 166 print "Requesting HA start for CT $vmid\n";
52389a07 167
35d2a4e4 168 my $cmd = ['ha-manager', 'set', "ct:$vmid", '--state', 'started'];
52389a07 169 PVE::Tools::run_command($cmd);
52389a07
DM
170 };
171
172 return $rpcenv->fork_worker('hastart', $vmid, $authuser, $hacmd);
173
174 } else {
175
6a4e5293
TL
176 my $realcmd = sub {
177 my $upid = shift;
52389a07 178
7a735681
FW
179 PVE::LXC::Config->lock_config($vmid, sub {
180 syslog('info', "starting CT $vmid: $upid\n");
52389a07 181
7a735681 182 my $conf = PVE::LXC::Config->load_config($vmid);
894aa229 183
7a735681
FW
184 die "you can't start a CT if it's a template\n"
185 if PVE::LXC::Config->is_template($conf);
894aa229 186
7a735681
FW
187 if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) {
188 PVE::LXC::Config->check_lock($conf);
189 }
52389a07 190
7a735681
FW
191 if ($conf->{unprivileged}) {
192 PVE::LXC::Config->foreach_volume($conf, sub {
193 my ($ms, $mountpoint) = @_;
194 die "Quotas are not supported by unprivileged containers.\n"
195 if $mountpoint->{quota};
196 });
197 }
f053a616 198
7a735681
FW
199 PVE::LXC::vm_start($vmid, $conf, $skiplock, $param->{debug});
200 });
52389a07
DM
201 };
202
7a735681 203 return $rpcenv->fork_worker('vzstart', $vmid, $authuser, $realcmd);
52389a07
DM
204 }
205 }});
206
207__PACKAGE__->register_method({
208 name => 'vm_stop',
209 path => 'stop',
210 method => 'POST',
211 protected => 1,
212 proxyto => 'node',
52eb76e5 213 description => "Stop the container. This will abruptly stop all processes running in the container.",
52389a07
DM
214 permissions => {
215 check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
216 },
217 parameters => {
17f1dc40 218 additionalProperties => 0,
52389a07
DM
219 properties => {
220 node => get_standard_option('pve-node'),
68e8f3c5 221 vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_running }),
2de0b3d4 222 skiplock => get_standard_option('skiplock'),
d5fab92b 223 'overrule-shutdown' => {
9dfcefb1 224 description => "Try to abort active 'vzshutdown' tasks before stopping.",
d5fab92b
FW
225 optional => 1,
226 type => 'boolean',
227 default => 0,
228 }
52389a07
DM
229 },
230 },
231 returns => {
232 type => 'string',
233 },
234 code => sub {
235 my ($param) = @_;
236
237 my $rpcenv = PVE::RPCEnvironment::get();
52389a07 238 my $authuser = $rpcenv->get_user();
52389a07 239 my $node = extract_param($param, 'node');
52389a07
DM
240 my $vmid = extract_param($param, 'vmid');
241
2de0b3d4
WB
242 my $skiplock = extract_param($param, 'skiplock');
243 raise_param_exc({ skiplock => "Only root may use this option." })
244 if $skiplock && $authuser ne 'root@pam';
245
d5fab92b
FW
246 my $overrule_shutdown = extract_param($param, 'overrule-shutdown');
247
52389a07
DM
248 die "CT $vmid not running\n" if !PVE::LXC::check_running($vmid);
249
250 if (PVE::HA::Config::vm_is_ha_managed($vmid) && $rpcenv->{type} ne 'ha') {
251
d5fab92b
FW
252 raise_param_exc({ 'overrule-shutdown' => "Not applicable for HA resources." })
253 if $overrule_shutdown;
254
52389a07
DM
255 my $hacmd = sub {
256 my $upid = shift;
257
545dd4e1 258 print "Requesting HA stop for CT $vmid\n";
52389a07 259
f7a6910a 260 my $cmd = ['ha-manager', 'crm-command', 'stop', "ct:$vmid", '0'];
52389a07 261 PVE::Tools::run_command($cmd);
52389a07
DM
262 };
263
264 return $rpcenv->fork_worker('hastop', $vmid, $authuser, $hacmd);
265
266 } else {
267
6a4e5293
TL
268 my $realcmd = sub {
269 my $upid = shift;
fdf71adb 270
d5fab92b
FW
271 if ($overrule_shutdown) {
272 my $overruled_tasks = PVE::GuestHelpers::abort_guest_tasks(
273 $rpcenv, 'vzshutdown', $vmid);
274 my $overruled_tasks_list = join(", ", $overruled_tasks->@*);
275 print "overruled vzshutdown tasks: $overruled_tasks_list\n"
276 if @$overruled_tasks;
277 };
278
7a735681
FW
279 PVE::LXC::Config->lock_config($vmid, sub {
280 syslog('info', "stopping CT $vmid: $upid\n");
fdf71adb 281
7a735681
FW
282 my $conf = PVE::LXC::Config->load_config($vmid);
283 if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) {
284 PVE::LXC::Config->check_lock($conf);
285 }
f053a616 286
7a735681
FW
287 PVE::LXC::vm_stop($vmid, 1);
288 });
52389a07
DM
289 };
290
7a735681 291 return $rpcenv->fork_worker('vzstop', $vmid, $authuser, $realcmd);
52389a07
DM
292 }
293 }});
294
295__PACKAGE__->register_method({
296 name => 'vm_shutdown',
297 path => 'shutdown',
298 method => 'POST',
299 protected => 1,
300 proxyto => 'node',
52eb76e5
EK
301 description => "Shutdown the container. This will trigger a clean shutdown " .
302 "of the container, see lxc-stop(1) for details.",
52389a07
DM
303 permissions => {
304 check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
305 },
306 parameters => {
17f1dc40 307 additionalProperties => 0,
52389a07
DM
308 properties => {
309 node => get_standard_option('pve-node'),
68e8f3c5 310 vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_running }),
52389a07
DM
311 timeout => {
312 description => "Wait maximal timeout seconds.",
313 type => 'integer',
314 minimum => 0,
315 optional => 1,
316 default => 60,
317 },
318 forceStop => {
319 description => "Make sure the Container stops.",
320 type => 'boolean',
321 optional => 1,
322 default => 0,
323 }
324 },
325 },
326 returns => {
327 type => 'string',
328 },
329 code => sub {
330 my ($param) = @_;
331
332 my $rpcenv = PVE::RPCEnvironment::get();
52389a07
DM
333 my $authuser = $rpcenv->get_user();
334
335 my $node = extract_param($param, 'node');
52389a07
DM
336 my $vmid = extract_param($param, 'vmid');
337
6a4e5293 338 my $timeout = extract_param($param, 'timeout') // 60;
52389a07
DM
339
340 die "CT $vmid not running\n" if !PVE::LXC::check_running($vmid);
341
35d2a4e4 342 if (PVE::HA::Config::vm_is_ha_managed($vmid) && $rpcenv->{type} ne 'ha') {
5bcdc2ac
DM
343 my $hacmd = sub {
344 my $upid = shift;
345
545dd4e1 346 print "Requesting HA stop for CT $vmid\n";
5bcdc2ac 347
f7a6910a 348 my $cmd = ['ha-manager', 'crm-command', 'stop', "ct:$vmid", "$timeout"];
5bcdc2ac 349 PVE::Tools::run_command($cmd);
5bcdc2ac
DM
350 };
351
352 return $rpcenv->fork_worker('hastop', $vmid, $authuser, $hacmd);
353 }
354
6a4e5293
TL
355 my $realcmd = sub {
356 my $upid = shift;
52389a07 357
7a735681
FW
358 PVE::LXC::Config->lock_config($vmid, sub {
359 syslog('info', "shutdown CT $vmid: $upid\n");
f053a616 360
7a735681
FW
361 my $conf = PVE::LXC::Config->load_config($vmid);
362 PVE::LXC::Config->check_lock($conf);
52389a07 363
7a735681
FW
364 PVE::LXC::vm_stop($vmid, 0, $timeout, $param->{forceStop});
365 });
f053a616 366 };
52389a07 367
7a735681 368 return $rpcenv->fork_worker('vzshutdown', $vmid, $authuser, $realcmd);
52389a07
DM
369 }});
370
371__PACKAGE__->register_method({
372 name => 'vm_suspend',
373 path => 'suspend',
374 method => 'POST',
375 protected => 1,
376 proxyto => 'node',
692c79d9 377 description => "Suspend the container. This is experimental.",
52389a07 378 permissions => {
4de00d82 379 check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
52389a07
DM
380 },
381 parameters => {
17f1dc40
TL
382 additionalProperties => 0,
383 properties => {
4de00d82 384 node => get_standard_option('pve-node'),
68e8f3c5 385 vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_running }),
17f1dc40 386 },
52389a07
DM
387 },
388 returns => {
17f1dc40 389 type => 'string',
52389a07
DM
390 },
391 code => sub {
4de00d82 392 my ($param) = @_;
52389a07 393
4de00d82
TL
394 my $rpcenv = PVE::RPCEnvironment::get();
395 my $authuser = $rpcenv->get_user();
52389a07 396
4de00d82
TL
397 my $node = extract_param($param, 'node');
398 my $vmid = extract_param($param, 'vmid');
52389a07 399
4de00d82 400 die "CT $vmid not running\n" if !PVE::LXC::check_running($vmid);
52389a07 401
6a4e5293
TL
402 my $realcmd = sub {
403 my $upid = shift;
52389a07 404
7a735681
FW
405 PVE::LXC::Config->lock_config($vmid, sub {
406 syslog('info', "suspend CT $vmid: $upid\n");
52389a07 407
7a735681
FW
408 my $conf = PVE::LXC::Config->load_config($vmid);
409 PVE::LXC::Config->check_lock($conf);
52389a07 410
7a735681
FW
411 my $cmd = ['lxc-checkpoint', '-n', $vmid, '-s', '-D', '/var/lib/vz/dump'];
412 run_command($cmd);
413 });
f053a616 414 };
52389a07 415
7a735681 416 return $rpcenv->fork_worker('vzsuspend', $vmid, $authuser, $realcmd);
52389a07
DM
417 }});
418
419__PACKAGE__->register_method({
420 name => 'vm_resume',
421 path => 'resume',
422 method => 'POST',
423 protected => 1,
424 proxyto => 'node',
425 description => "Resume the container.",
426 permissions => {
427 check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
428 },
429 parameters => {
17f1dc40
TL
430 additionalProperties => 0,
431 properties => {
432 node => get_standard_option('pve-node'),
68e8f3c5 433 vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_stopped }),
17f1dc40 434 },
52389a07
DM
435 },
436 returns => {
17f1dc40 437 type => 'string',
52389a07
DM
438 },
439 code => sub {
4de00d82 440 my ($param) = @_;
52389a07 441
4de00d82
TL
442 my $rpcenv = PVE::RPCEnvironment::get();
443 my $authuser = $rpcenv->get_user();
52389a07 444
4de00d82
TL
445 my $node = extract_param($param, 'node');
446 my $vmid = extract_param($param, 'vmid');
52389a07 447
4de00d82 448 die "CT $vmid already running\n" if PVE::LXC::check_running($vmid);
52389a07 449
6a4e5293
TL
450 my $realcmd = sub {
451 my $upid = shift;
52389a07 452
6a4e5293 453 syslog('info', "resume CT $vmid: $upid\n");
52389a07 454
6a4e5293 455 my $cmd = ['lxc-checkpoint', '-n', $vmid, '-r', '--foreground', '-D', '/var/lib/vz/dump'];
52389a07 456 run_command($cmd);
6a4e5293 457 };
52389a07 458
6a4e5293 459 my $upid = $rpcenv->fork_worker('vzresume', $vmid, $authuser, $realcmd);
52389a07 460
4de00d82 461 return $upid;
52389a07
DM
462 }});
463
f5fe1125
OB
464__PACKAGE__->register_method({
465 name => 'vm_reboot',
466 path => 'reboot',
467 method => 'POST',
468 protected => 1,
469 proxyto => 'node',
470 description => "Reboot the container by shutting it down, and starting it again. Applies pending changes.",
471 permissions => {
472 check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
473 },
474 parameters => {
475 additionalProperties => 0,
476 properties => {
477 node => get_standard_option('pve-node'),
478 vmid => get_standard_option('pve-vmid',
479 { completion => \&PVE::LXC::complete_ctid_running }),
480 timeout => {
481 description => "Wait maximal timeout seconds for the shutdown.",
482 type => 'integer',
483 minimum => 0,
484 optional => 1,
485 },
486 },
487 },
488 returns => {
489 type => 'string',
490 },
491 code => sub {
492 my ($param) = @_;
493
494 my $rpcenv = PVE::RPCEnvironment::get();
495 my $authuser = $rpcenv->get_user();
496
497 my $node = extract_param($param, 'node');
498 my $vmid = extract_param($param, 'vmid');
499
500 die "VM $vmid not running\n" if !PVE::LXC::check_running($vmid);
501
502 my $realcmd = sub {
503 my $upid = shift;
504
505 syslog('info', "requesting reboot of CT $vmid: $upid\n");
506 PVE::LXC::vm_reboot($vmid, $param->{timeout});
507 return;
508 };
509
510 return $rpcenv->fork_worker('vzreboot', $vmid, $authuser, $realcmd);
511 }});
512
513
514
52389a07 5151;