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