api2: add cloudinit_update

This allow to regenerate the config drive with 1 api call.

This also avoid to delete drive first, and recreate it again.

As it's a readonly drive, we can simply live update it,
and eject/replace it with qemu monitor

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
Alexandre Derumier 2022-06-22 13:52:04 +02:00 committed by Thomas Lamprecht
parent 2be1fb0af4
commit 9687287bb3
3 changed files with 73 additions and 1 deletions

View File

@ -1379,6 +1379,49 @@ __PACKAGE__->register_method({
return $res;
}});
__PACKAGE__->register_method({
name => 'cloudinit_update',
path => '{vmid}/cloudinit',
method => 'PUT',
protected => 1,
proxyto => 'node',
description => "Regenerate and change cloudinit config drive.",
permissions => {
check => ['perm', '/vms/{vmid}', 'VM.Config.Cloudinit'],
},
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid'),
},
},
returns => { type => 'null' },
code => sub {
my ($param) = @_;
my $rpcenv = PVE::RPCEnvironment::get();
my $authuser = $rpcenv->get_user();
my $vmid = extract_param($param, 'vmid');
my $updatefn = sub {
my $conf = PVE::QemuConfig->load_config($vmid);
PVE::QemuConfig->check_lock($conf);
my $storecfg = PVE::Storage::config();
PVE::QemuServer::vmconfig_update_cloudinit_drive($storecfg, $conf, $vmid);
};
PVE::QemuConfig->lock_config($vmid, $updatefn);
return;
}});
# POST/PUT {vmid}/config implementation
#
# The original API used PUT (idempotent) an we assumed that all operations

View File

@ -984,7 +984,8 @@ our $cmddef = {
cloudinit => {
dump => [ "PVE::API2::Qemu", 'cloudinit_generated_config_dump', ['vmid', 'type'], { %node }, sub { print "$_[0]\n"; }],
pending => [ "PVE::API2::Qemu", 'cloudinit_pending', ['vmid'], { %node }, \&PVE::GuestHelpers::format_pending ]
pending => [ "PVE::API2::Qemu", 'cloudinit_pending', ['vmid'], { %node }, \&PVE::GuestHelpers::format_pending ],
update => [ "PVE::API2::Qemu", 'cloudinit_update', ['vmid'], { node => $nodename }],
},
};

View File

@ -5277,6 +5277,34 @@ sub vmconfig_update_disk {
vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive, $arch, $machine_type);
}
sub vmconfig_update_cloudinit_drive {
my ($storecfg, $conf, $vmid) = @_;
my $cloudinit_ds = undef;
my $cloudinit_drive = undef;
PVE::QemuConfig->foreach_volume($conf, sub {
my ($ds, $drive) = @_;
if (PVE::QemuServer::drive_is_cloudinit($drive)) {
$cloudinit_ds = $ds;
$cloudinit_drive = $drive;
}
});
return if !$cloudinit_drive;
PVE::QemuServer::Cloudinit::generate_cloudinitconfig($conf, $vmid);
my $running = PVE::QemuServer::check_running($vmid);
if ($running) {
my $path = PVE::Storage::path($storecfg, $cloudinit_drive->{file});
if ($path) {
mon_cmd($vmid, "eject", force => JSON::true, id => "$cloudinit_ds");
mon_cmd($vmid, "blockdev-change-medium", id => "$cloudinit_ds", filename => "$path");
}
}
}
# called in locked context by incoming migration
sub vm_migrate_get_nbd_disks {
my ($storecfg, $conf, $replicated_volumes) = @_;