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