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