use PVE::QemuServer::ImportDisk;
use PVE::QemuServer::Monitor qw(mon_cmd);
use PVE::QemuServer::Machine;
+use PVE::QemuServer::Memory qw(get_current_memory);
use PVE::QemuServer::PCI;
use PVE::QemuServer::USB;
use PVE::QemuMigrate;
cipassword => 1,
citype => 1,
ciuser => 1,
+ ciupgrade => 1,
nameserver => 1,
searchdomain => 1,
sshkeys => 1,
proxyto => 'node',
description => "Regenerate and change cloudinit config drive.",
permissions => {
- check => ['perm', '/vms/{vmid}', 'VM.Config.Cloudinit'],
+ check => ['perm', '/vms/{vmid}', ['VM.Config.Cloudinit']],
},
parameters => {
additionalProperties => 0,
my $storecfg = PVE::Storage::config();
- my $defaults = PVE::QemuServer::load_defaults();
-
&$resolve_cdrom_alias($param);
# now try to verify all parameters
}
if ($param->{memory} || defined($param->{balloon})) {
- my $maxmem = $param->{memory} || $conf->{pending}->{memory} || $conf->{memory} || $defaults->{memory};
+
+ my $memory = $param->{memory} || $conf->{pending}->{memory} || $conf->{memory};
+ my $maxmem = get_current_memory($memory);
my $balloon = defined($param->{balloon}) ? $param->{balloon} : $conf->{pending}->{balloon} || $conf->{balloon};
die "balloon value too large (must be smaller than assigned memory)\n"
assert_tag_permissions($vmid, $val, '', $rpcenv, $authuser);
delete $conf->{$opt};
PVE::QemuConfig->write_config($vmid, $conf);
+ } elsif ($opt =~ m/^net\d+$/) {
+ if ($conf->{$opt}) {
+ PVE::QemuServer::check_bridge_access(
+ $rpcenv,
+ $authuser,
+ { $opt => $conf->{$opt} },
+ );
+ }
+ PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force);
+ PVE::QemuConfig->write_config($vmid, $conf);
} else {
PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force);
PVE::QemuConfig->write_config($vmid, $conf);
} elsif ($opt eq 'tags') {
assert_tag_permissions($vmid, $conf->{$opt}, $param->{$opt}, $rpcenv, $authuser);
$conf->{pending}->{$opt} = PVE::GuestHelpers::get_unique_tags($param->{$opt});
+ } elsif ($opt =~ m/^net\d+$/) {
+ if ($conf->{$opt}) {
+ PVE::QemuServer::check_bridge_access(
+ $rpcenv,
+ $authuser,
+ { $opt => $conf->{$opt} },
+ );
+ }
+ $conf->{pending}->{$opt} = $param->{$opt};
} else {
$conf->{pending}->{$opt} = $param->{$opt};
websocket => {
optional => 1,
type => 'boolean',
- description => "starts websockify instead of vncproxy",
+ description => "Prepare for websocket upgrade (only required when using "
+ ."serial terminal, otherwise upgrade is always possible).",
},
'generate-password' => {
optional => 1,
} else {
- $ENV{LC_PVE_TICKET} = $password if $websocket; # set ticket with "qm vncproxy"
+ $ENV{LC_PVE_TICKET} = $password; # set ticket with "qm vncproxy"
$cmd = [@$remcmd, "/usr/sbin/qm", 'vncproxy', $vmid];
my $shutdown = 1;
- # if vm is paused, do not shutdown (but stop if forceStop = 1)
- # otherwise, we will infer a shutdown command, but run into the timeout,
- # then when the vm is resumed, it will instantly shutdown
- #
- # checking the qmp status here to get feedback to the gui/cli/api
- # and the status query should not take too long
+ # sending a graceful shutdown command to paused VMs runs into timeouts, and even worse, when
+ # the VM gets resumed later, it still gets the request delivered and powers off
if (PVE::QemuServer::vm_is_paused($vmid)) {
if ($param->{forceStop}) {
warn "VM is paused - stop instead of shutdown\n";
my $local_disks = {};
# add some more information to the disks e.g. cdrom
- PVE::QemuServer::foreach_volid($vmconf, 1, sub {
+ PVE::QemuServer::foreach_volid($vmconf, sub {
my ($volid, $attr) = @_;
my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
'disk' => [
undef,
$storeid,
- undef,
$drive,
0,
$format,