1 package PVE
::API2
::LXC
::Status
;
7 use PVE
::Tools
qw(extract_param run_command);
8 use PVE
::Exception
qw(raise raise_param_exc);
10 use PVE
::Cluster
qw(cfs_read_file);
11 use PVE
::AccessControl
;
15 use PVE
::RPCEnvironment
;
18 use PVE
::JSONSchema
qw(get_standard_option);
20 use base
qw(PVE::RESTHandler);
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
;
31 __PACKAGE__-
>register_method({
36 description
=> "Directory index",
41 additionalProperties
=> 0,
43 node
=> get_standard_option
('pve-node'),
44 vmid
=> get_standard_option
('pve-vmid'),
52 subdir
=> { type
=> 'string' },
55 links
=> [ { rel
=> 'child', href
=> "{subdir}" } ],
61 my $conf = PVE
::LXC
::Config-
>load_config($param->{vmid
});
64 { subdir
=> 'current' },
65 { subdir
=> 'start' },
67 { subdir
=> 'shutdown' },
68 { subdir
=> 'reboot' },
69 { subdir
=> 'migrate' },
75 __PACKAGE__-
>register_method({
80 protected
=> 1, # /proc entries are only readable by root
81 description
=> "Get virtual machine status.",
83 check
=> ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
86 additionalProperties
=> 0,
88 node
=> get_standard_option
('pve-node'),
89 vmid
=> get_standard_option
('pve-vmid'),
95 %$PVE::LXC
::vmstatus_return_properties
,
97 description
=> "HA manager service status.",
106 my $vmid = $param->{vmid
};
107 my $conf = PVE
::LXC
::Config-
>load_config($vmid);
109 my $vmstatus = PVE
::LXC
::vmstatus
($vmid);
110 my $status = $vmstatus->{$vmid};
112 $status->{ha
} = PVE
::HA
::Config
::get_service_status
("ct:$vmid");
117 __PACKAGE__-
>register_method({
123 description
=> "Start the container.",
125 check
=> ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
128 additionalProperties
=> 0,
130 node
=> get_standard_option
('pve-node'),
131 vmid
=> get_standard_option
('pve-vmid', { completion
=> \
&PVE
::LXC
::complete_ctid_stopped
}),
132 skiplock
=> get_standard_option
('skiplock'),
136 description
=> "If set, enables very verbose debug log-level on start.",
147 my $rpcenv = PVE
::RPCEnvironment
::get
();
148 my $authuser = $rpcenv->get_user();
150 my $node = extract_param
($param, 'node');
151 my $vmid = extract_param
($param, 'vmid');
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';
157 die "CT $vmid already running\n" if PVE
::LXC
::check_running
($vmid);
159 PVE
::Cluster
::check_cfs_quorum
();
161 if (PVE
::HA
::Config
::vm_is_ha_managed
($vmid) && $rpcenv->{type
} ne 'ha') {
166 print "Requesting HA start for CT $vmid\n";
168 my $cmd = ['ha-manager', 'set', "ct:$vmid", '--state', 'started'];
169 PVE
::Tools
::run_command
($cmd);
172 return $rpcenv->fork_worker('hastart', $vmid, $authuser, $hacmd);
179 PVE
::LXC
::Config-
>lock_config($vmid, sub {
180 syslog
('info', "starting CT $vmid: $upid\n");
182 my $conf = PVE
::LXC
::Config-
>load_config($vmid);
184 die "you can't start a CT if it's a template\n"
185 if PVE
::LXC
::Config-
>is_template($conf);
187 if (!$skiplock && !PVE
::LXC
::Config-
>has_lock($conf, 'mounted')) {
188 PVE
::LXC
::Config-
>check_lock($conf);
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
};
199 PVE
::LXC
::vm_start
($vmid, $conf, $skiplock, $param->{debug
});
203 return $rpcenv->fork_worker('vzstart', $vmid, $authuser, $realcmd);
207 __PACKAGE__-
>register_method({
213 description
=> "Stop the container. This will abruptly stop all processes running in the container.",
215 check
=> ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
218 additionalProperties
=> 0,
220 node
=> get_standard_option
('pve-node'),
221 vmid
=> get_standard_option
('pve-vmid', { completion
=> \
&PVE
::LXC
::complete_ctid_running
}),
222 skiplock
=> get_standard_option
('skiplock'),
223 'overrule-shutdown' => {
224 description
=> "Try to abort active 'vzshutdown' tasks before stopping.",
237 my $rpcenv = PVE
::RPCEnvironment
::get
();
238 my $authuser = $rpcenv->get_user();
239 my $node = extract_param
($param, 'node');
240 my $vmid = extract_param
($param, 'vmid');
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';
246 my $overrule_shutdown = extract_param
($param, 'overrule-shutdown');
248 die "CT $vmid not running\n" if !PVE
::LXC
::check_running
($vmid);
250 if (PVE
::HA
::Config
::vm_is_ha_managed
($vmid) && $rpcenv->{type
} ne 'ha') {
252 raise_param_exc
({ 'overrule-shutdown' => "Not applicable for HA resources." })
253 if $overrule_shutdown;
258 print "Requesting HA stop for CT $vmid\n";
260 my $cmd = ['ha-manager', 'crm-command', 'stop', "ct:$vmid", '0'];
261 PVE
::Tools
::run_command
($cmd);
264 return $rpcenv->fork_worker('hastop', $vmid, $authuser, $hacmd);
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;
279 PVE
::LXC
::Config-
>lock_config($vmid, sub {
280 syslog
('info', "stopping CT $vmid: $upid\n");
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);
287 PVE
::LXC
::vm_stop
($vmid, 1);
291 return $rpcenv->fork_worker('vzstop', $vmid, $authuser, $realcmd);
295 __PACKAGE__-
>register_method({
296 name
=> 'vm_shutdown',
301 description
=> "Shutdown the container. This will trigger a clean shutdown " .
302 "of the container, see lxc-stop(1) for details.",
304 check
=> ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
307 additionalProperties
=> 0,
309 node
=> get_standard_option
('pve-node'),
310 vmid
=> get_standard_option
('pve-vmid', { completion
=> \
&PVE
::LXC
::complete_ctid_running
}),
312 description
=> "Wait maximal timeout seconds.",
319 description
=> "Make sure the Container stops.",
332 my $rpcenv = PVE
::RPCEnvironment
::get
();
333 my $authuser = $rpcenv->get_user();
335 my $node = extract_param
($param, 'node');
336 my $vmid = extract_param
($param, 'vmid');
338 my $timeout = extract_param
($param, 'timeout') // 60;
340 die "CT $vmid not running\n" if !PVE
::LXC
::check_running
($vmid);
342 if (PVE
::HA
::Config
::vm_is_ha_managed
($vmid) && $rpcenv->{type
} ne 'ha') {
346 print "Requesting HA stop for CT $vmid\n";
348 my $cmd = ['ha-manager', 'crm-command', 'stop', "ct:$vmid", "$timeout"];
349 PVE
::Tools
::run_command
($cmd);
352 return $rpcenv->fork_worker('hastop', $vmid, $authuser, $hacmd);
358 PVE
::LXC
::Config-
>lock_config($vmid, sub {
359 syslog
('info', "shutdown CT $vmid: $upid\n");
361 my $conf = PVE
::LXC
::Config-
>load_config($vmid);
362 PVE
::LXC
::Config-
>check_lock($conf);
364 PVE
::LXC
::vm_stop
($vmid, 0, $timeout, $param->{forceStop
});
368 return $rpcenv->fork_worker('vzshutdown', $vmid, $authuser, $realcmd);
371 __PACKAGE__-
>register_method({
372 name
=> 'vm_suspend',
377 description
=> "Suspend the container. This is experimental.",
379 check
=> ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
382 additionalProperties
=> 0,
384 node
=> get_standard_option
('pve-node'),
385 vmid
=> get_standard_option
('pve-vmid', { completion
=> \
&PVE
::LXC
::complete_ctid_running
}),
394 my $rpcenv = PVE
::RPCEnvironment
::get
();
395 my $authuser = $rpcenv->get_user();
397 my $node = extract_param
($param, 'node');
398 my $vmid = extract_param
($param, 'vmid');
400 die "CT $vmid not running\n" if !PVE
::LXC
::check_running
($vmid);
405 PVE
::LXC
::Config-
>lock_config($vmid, sub {
406 syslog
('info', "suspend CT $vmid: $upid\n");
408 my $conf = PVE
::LXC
::Config-
>load_config($vmid);
409 PVE
::LXC
::Config-
>check_lock($conf);
411 my $cmd = ['lxc-checkpoint', '-n', $vmid, '-s', '-D', '/var/lib/vz/dump'];
416 return $rpcenv->fork_worker('vzsuspend', $vmid, $authuser, $realcmd);
419 __PACKAGE__-
>register_method({
425 description
=> "Resume the container.",
427 check
=> ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
430 additionalProperties
=> 0,
432 node
=> get_standard_option
('pve-node'),
433 vmid
=> get_standard_option
('pve-vmid', { completion
=> \
&PVE
::LXC
::complete_ctid_stopped
}),
442 my $rpcenv = PVE
::RPCEnvironment
::get
();
443 my $authuser = $rpcenv->get_user();
445 my $node = extract_param
($param, 'node');
446 my $vmid = extract_param
($param, 'vmid');
448 die "CT $vmid already running\n" if PVE
::LXC
::check_running
($vmid);
453 syslog
('info', "resume CT $vmid: $upid\n");
455 my $cmd = ['lxc-checkpoint', '-n', $vmid, '-r', '--foreground', '-D', '/var/lib/vz/dump'];
459 my $upid = $rpcenv->fork_worker('vzresume', $vmid, $authuser, $realcmd);
464 __PACKAGE__-
>register_method({
470 description
=> "Reboot the container by shutting it down, and starting it again. Applies pending changes.",
472 check
=> ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
475 additionalProperties
=> 0,
477 node
=> get_standard_option
('pve-node'),
478 vmid
=> get_standard_option
('pve-vmid',
479 { completion
=> \
&PVE
::LXC
::complete_ctid_running
}),
481 description
=> "Wait maximal timeout seconds for the shutdown.",
494 my $rpcenv = PVE
::RPCEnvironment
::get
();
495 my $authuser = $rpcenv->get_user();
497 my $node = extract_param
($param, 'node');
498 my $vmid = extract_param
($param, 'vmid');
500 die "VM $vmid not running\n" if !PVE
::LXC
::check_running
($vmid);
505 syslog
('info', "requesting reboot of CT $vmid: $upid\n");
506 PVE
::LXC
::vm_reboot
($vmid, $param->{timeout
});
510 return $rpcenv->fork_worker('vzreboot', $vmid, $authuser, $realcmd);