[pve-devel] [PATCH 05/19] cloudinit : support any storeid for configdrive

Alexandre Derumier aderumier at odiso.com
Tue May 23 08:57:03 CEST 2017


- changelog:
  - support any storage and not only qcow2

  - cloudinit drive volume no more generated at start.

    we can now enable|disable cloudinit with

    qm set vmid -(ide|sata)x  storeid:cloudinit
    qm set vmid -delete (ide|sata)x

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/API2/Qemu.pm  | 26 +++++++++++++++++-
 PVE/QemuServer.pm | 82 ++++++++++++++++---------------------------------------
 2 files changed, 49 insertions(+), 59 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index c566c4d..2b5f451 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -60,7 +60,9 @@ my $check_storage_access = sub {
 
 	my $volid = $drive->{file};
 
-	if (!$volid || $volid eq 'none') {
+	if (!$volid || ($volid eq 'none' || $volid eq 'cloudinit')) {
+	    # nothing to check
+	} elsif ($volid =~ m/^(([^:\s]+):)?(cloudinit)$/) {
 	    # nothing to check
 	} elsif ($isCDROM && ($volid eq 'cdrom')) {
 	    $rpcenv->check($authuser, "/", ['Sys.Console']);
@@ -128,6 +130,28 @@ my $create_disks = sub {
 	if (!$volid || $volid eq 'none' || $volid eq 'cdrom') {
 	    delete $disk->{size};
 	    $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
+	} elsif ($volid =~ m/^(?:([^:\s]+):)?cloudinit$/) {
+	    my $storeid = $1 || $default_storage;
+	    die "no storage ID specified (and no default storage)\n" if !$storeid;
+	    my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
+	    my $name = "vm-$vmid-cloudinit";
+	    my $fmt = undef;
+	    if ($scfg->{path}) {
+		$name .= ".qcow2";
+		$fmt = 'qcow2';
+	    } else{
+		$fmt = 'raw';
+	    }
+	    # FIXME: Reasonable size? qcow2 shouldn't grow if the space isn't used anyway?
+	    my $cloudinit_iso_size = 5; # in MB
+	    my $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid,
+						    $fmt, $name, $cloudinit_iso_size*1024);
+	    $disk->{file} = $volid;
+	    $disk->{media} = 'cdrom';
+	    push @$vollist, $volid;
+	    delete $disk->{format}; # no longer needed
+	    $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
+
 	} elsif ($volid =~ m!^(([^/:\s]+):)?(\d+(\.\d+)?)$!) {
 	    my ($storeid, $size) = ($2 || $default_storage, $3);
 	    die "no storage ID specified (and no default storage)\n" if !$storeid;
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index c1bf0bc..f47ab7d 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -1255,8 +1255,6 @@ sub get_iso_path {
 	return get_cdrom_path();
     } elsif ($cdrom eq 'none') {
 	return '';
-    } elsif ($cdrom eq 'cloudinit') {
-	return "/tmp/cloudinit/$vmid/configdrive.iso";
     } elsif ($cdrom =~ m|^/|) {
 	return $cdrom;
     } else {
@@ -1268,7 +1266,7 @@ sub get_iso_path {
 sub filename_to_volume_id {
     my ($vmid, $file, $media) = @_;
 
-     if (!($file eq 'none' || $file eq 'cdrom' || $file eq 'cloudinit' ||
+     if (!($file eq 'none' || $file eq 'cdrom' ||
 	  $file =~ m|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
 
 	return undef if $file =~ m|/|;
@@ -3358,8 +3356,6 @@ sub config_to_command {
 	push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
     });
 
-    generate_cloudinit_command($conf, $vmid, $storecfg, $bridges, $devices);
-
     for (my $i = 0; $i < $MAX_NETS; $i++) {
          next if !$conf->{"net$i"};
          my $d = parse_net($conf->{"net$i"});
@@ -6547,23 +6543,6 @@ sub nbd_stop {
     vm_mon_cmd($vmid, 'nbd-server-stop');
 }
 
-# FIXME: Reasonable size? qcow2 shouldn't grow if the space isn't used anyway?
-my $cloudinit_iso_size = 5; # in MB
-
-sub prepare_cloudinit_disk {
-    my ($vmid, $storeid) = @_;
-
-    my $storecfg = PVE::Storage::config();
-    my $imagedir = PVE::Storage::get_image_dir($storecfg, $storeid, $vmid);
-    my $iso_name = "vm-$vmid-cloudinit.qcow2";
-    my $iso_path = "$imagedir/$iso_name";
-    if (!-e $iso_path) {
-	# vdisk_alloc size is in K
-	PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, 'qcow2', $iso_name, $cloudinit_iso_size*1024);
-    }
-    return ($iso_path, 'qcow2');
-}
-
 # FIXME: also in LXCCreate.pm => move to pve-common
 sub next_free_nbd_dev {
     
@@ -6595,52 +6574,39 @@ sub commit_cloudinit_disk {
     die $err if $err;
 }
 
-sub find_cloudinit_storage {
-    my ($conf, $vmid) = @_;
-    foreach my $ds (keys %$conf) {
-	next if !valid_drivename($ds);
-	if ($conf->{$ds} =~ m@^(?:volume=)?([^:]+):\Q$vmid\E/vm-\Q$vmid\E-cloudinit\.qcow2@) {
-	    return $1;
-	}
-    }
-    return undef;
-}
-
 sub generate_cloudinitconfig {
     my ($conf, $vmid) = @_;
 
-    my $storeid = find_cloudinit_storage($conf, $vmid);
-    return if !$storeid;
-
-    my $path = "/tmp/cloudinit/$vmid";
+    foreach_drive($conf, sub {
+        my ($ds, $drive) = @_;
 
-    mkdir "/tmp/cloudinit";
-    mkdir $path;
-    mkdir "$path/drive";
-    mkdir "$path/drive/openstack";
-    mkdir "$path/drive/openstack/latest";
-    mkdir "$path/drive/openstack/content";
-    my $digest_data = generate_cloudinit_userdata($conf, $path)
-		    . generate_cloudinit_network($conf, $path);
-    generate_cloudinit_metadata($conf, $path, $digest_data);
+	my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
 
-    my ($iso_path, $format) = prepare_cloudinit_disk($vmid, $storeid);
-    commit_cloudinit_disk("$path/drive", $iso_path, $format);
-    rmtree("$path/drive");
-}
+	return if $volname !~ m/vm-$vmid-cloudinit/;
 
-sub generate_cloudinit_command {
-    my ($conf, $vmid, $storecfg, $bridges, $devices) = @_;
+	my $path = "/tmp/cloudinit/$vmid";
 
-    return if !$conf->{cloudinit};
+	mkdir "/tmp/cloudinit";
+	mkdir $path;
+	mkdir "$path/drive";
+	mkdir "$path/drive/openstack";
+	mkdir "$path/drive/openstack/latest";
+	mkdir "$path/drive/openstack/content";
+	my $digest_data = generate_cloudinit_userdata($conf, $path)
+			. generate_cloudinit_network($conf, $path);
+	generate_cloudinit_metadata($conf, $path, $digest_data);
 
-    my $path = "/tmp/cloudinit/$vmid/configdrive.iso";
-    my $drive = parse_drive('ide3', 'cloudinit,media=cdrom');
-    my $drive_cmd = print_drive_full($storecfg, $vmid, $drive);
-    push @$devices, '-drive', $drive_cmd;
-    push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
+	my $storecfg = PVE::Storage::config();
+	my $iso_path = PVE::Storage::path($storecfg, $drive->{file});
+	my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
+	my $format = qemu_img_format($scfg, $volname);
+	#fixme : add meta as drive property to compare
+	commit_cloudinit_disk("$path/drive", $iso_path, $format);
+	rmtree("$path/drive");
+    });
 }
 
+
 sub generate_cloudinit_userdata {
     my ($conf, $path) = @_;
 
-- 
2.11.0




More information about the pve-devel mailing list