[pve-devel] [PATCH qemu-server 4/6] api2: add cloudinit config api
Mira Limbeck
m.limbeck at proxmox.com
Wed Mar 31 16:13:20 CEST 2021
Why do you add the macaddress here? I couldn't find anything in this nor
in the previous patch series explaining why this is done.
On 3/28/21 5:12 PM, Alexandre Derumier wrote:
> ---
> PVE/API2/Qemu.pm | 73 +++++++++++++++++++++++++++++++++++++
> PVE/CLI/qm.pm | 1 +
> PVE/QemuServer/Cloudinit.pm | 70 +++++++++++++++++++++++++++++++++++
> 3 files changed, 144 insertions(+)
>
> diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
> index ea74c69..b6122fe 100644
> --- a/PVE/API2/Qemu.pm
> +++ b/PVE/API2/Qemu.pm
> @@ -21,6 +21,7 @@ use PVE::ReplicationConfig;
> use PVE::GuestHelpers;
> use PVE::QemuConfig;
> use PVE::QemuServer;
> +use PVE::QemuServer::Cloudinit;
> use PVE::QemuServer::Drive;
> use PVE::QemuServer::CPUConfig;
> use PVE::QemuServer::Monitor qw(mon_cmd);
> @@ -1039,6 +1040,78 @@ __PACKAGE__->register_method({
> return PVE::GuestHelpers::config_with_pending_array($conf, $pending_delete_hash);
> }});
>
> +__PACKAGE__->register_method({
> + name => 'cloudinit_pending',
> + path => '{vmid}/cloudinit',
> + method => 'GET',
> + proxyto => 'node',
> + description => "Get the cloudinit configuration with both current and pending values.",
> + permissions => {
> + check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
> + },
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
> + },
> + },
> + returns => {
> + type => "array",
> + items => {
> + type => "object",
> + properties => {
> + key => {
> + description => "Configuration option name.",
> + type => 'string',
> + },
> + value => {
> + description => "Current value.",
> + type => 'string',
> + optional => 1,
> + },
> + pending => {
> + description => "Pending value.",
> + type => 'string',
> + optional => 1,
> + },
> + delete => {
> + description => "Indicates a pending delete request if present and not 0. " .
> + "The value 2 indicates a force-delete request.",
> + type => 'integer',
> + minimum => 0,
> + maximum => 2,
> + optional => 1,
> + },
> + },
> + },
> + },
> + code => sub {
> + my ($param) = @_;
> +
> + my $vmid = $param->{vmid};
> + my $conf = PVE::QemuConfig->load_config($vmid);
> +
> + if( defined($conf->{cipassword}) &&
> + defined($conf->{cloudinit}->{cipassword}) &&
> + $conf->{cipassword} ne $conf->{cloudinit}->{cipassword}) {
> + $conf->{cipassword} = '********** ';
> + } elsif (defined($conf->{cipassword})) {
> + $conf->{cipassword} = '**********';
> + }
> +
> + $conf->{cloudinit}->{cipassword} = '**********' if defined($conf->{cloudinit}->{cipassword});
> +
> + my $res = [];
> + my $pending = PVE::QemuServer::Cloudinit::get_pending_config($conf, $vmid);
> +
> + foreach my $opt (keys %{$pending}) {
> + push @$res, $pending->{$opt};
> + }
> +
> + return $res;
> + }});
> +
> # POST/PUT {vmid}/config implementation
> #
> # The original API used PUT (idempotent) an we assumed that all operations
> diff --git a/PVE/CLI/qm.pm b/PVE/CLI/qm.pm
> index f8972bd..e24b832 100755
> --- a/PVE/CLI/qm.pm
> +++ b/PVE/CLI/qm.pm
> @@ -996,6 +996,7 @@ our $cmddef = {
> my $data = shift;
> print "$data\n";
> }],
> + pending => [ "PVE::API2::Qemu", 'cloudinit_pending', ['vmid'], { node => $nodename }, \&PVE::GuestHelpers::format_pending ]
> },
>
> };
> diff --git a/PVE/QemuServer/Cloudinit.pm b/PVE/QemuServer/Cloudinit.pm
> index f4bf925..20cf583 100644
> --- a/PVE/QemuServer/Cloudinit.pm
> +++ b/PVE/QemuServer/Cloudinit.pm
> @@ -629,4 +629,74 @@ sub dump_cloudinit_config {
> }
> }
>
> +sub get_pending_config {
> + my ($conf, $vmid) = @_;
> +
> + my $newconf = { %{$conf} };
> + my $cloudinit_current = $newconf->{cloudinit};
> + my @cloudinit_opts = keys %{PVE::QemuServer::cloudinit_config_properties()};
> + push @cloudinit_opts, 'name';
> +
> + #add cloud-init drive
> + my $drives = {};
> + PVE::QemuConfig->foreach_volume($newconf, sub {
> + my ($ds, $drive) = @_;
> + $drives->{$ds} = 1 if PVE::QemuServer::drive_is_cloudinit($drive);
> + });
> +
> + PVE::QemuConfig->foreach_volume($cloudinit_current, sub {
> + my ($ds, $drive) = @_;
> + $drives->{$ds} = 1 if PVE::QemuServer::drive_is_cloudinit($drive);
> + });
> + foreach my $ds (keys %{$drives}) {
> + push @cloudinit_opts, $ds;
> + }
> +
> + $newconf->{name} = "VM$vmid" if !$newconf->{name};
> +
> + my $print_net_addr = sub {
> + my ($conf, $opt, $netid) = @_;
> +
> + if (defined($conf->{$netid})) {
> +
> + my $net = PVE::QemuServer::parse_net($conf->{$netid});
> + if (defined($conf->{$opt})) {
> + $conf->{$opt} .= ",macaddr=".$net->{macaddr} if $net->{macaddr};
> + } else {
> + $conf->{$opt} = "";
> + }
> + }
> + };
> +
> + my $res = {};
> + foreach my $opt (@cloudinit_opts) {
> +
> + #add macaddr to ipconfig
> + if ($opt =~ m/^ipconfig(\d+)/) {
> + my $netid = "net$1";
> + next if !defined($newconf->{$netid}) && !defined($cloudinit_current->{$netid}) && !defined($newconf->{$opt}) && !defined($cloudinit_current->{$opt} );
> +
> + &$print_net_addr($newconf, $opt, $netid);
> + &$print_net_addr($cloudinit_current, $opt, $netid);
> + }
> +
> + my $item = {
> + key => $opt,
> + };
> + if ($cloudinit_current->{$opt}) {
> + $item->{value} = $cloudinit_current->{$opt};
> + if ($newconf->{$opt}) {
> + $item->{pending} = $newconf->{$opt} if $newconf->{$opt} ne $cloudinit_current->{$opt};
> + } else {
> + $item->{delete} = 1;
> + }
> + } else {
> + $item->{pending} = $newconf->{$opt} if $newconf->{$opt}
> + }
> +
> + $res->{$opt} = $item;
> + }
> + return $res;
> +}
> +
> 1;
More information about the pve-devel
mailing list