]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuServer/Cloudinit.pm
cloudinit: use normal grep
[qemu-server.git] / PVE / QemuServer / Cloudinit.pm
index fbd71eced1ce5ac3d991a24fdf8239f8e4985a4f..52a4203dff9b9506feca0383e13ff69297f404ba 100644 (file)
@@ -11,6 +11,8 @@ use PVE::Tools qw(run_command file_set_contents);
 use PVE::Storage;
 use PVE::QemuServer;
 
+use constant CLOUDINIT_DISK_SIZE => 4 * 1024 * 1024; # 4MiB in bytes
+
 sub commit_cloudinit_disk {
     my ($conf, $vmid, $drive, $volname, $storeid, $files, $label) = @_;
 
@@ -32,25 +34,23 @@ sub commit_cloudinit_disk {
     my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
     my $format = PVE::QemuServer::qemu_img_format($scfg, $volname);
 
-    # required before file_size_info for ceph + krbd as it gets mapped too late otherwise
-    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
-    eval { $plugin->activate_volume($storeid, $scfg, $volname) };
-
-    my $size = eval { PVE::Storage::file_size_info($iso_path) };
-    if ($size <= 0) {
+    my $size = eval { PVE::Storage::volume_size_info($storecfg, $drive->{file}) };
+    if (!defined($size) || $size <= 0) {
        $volname =~ m/(vm-$vmid-cloudinit(.\Q$format\E)?)/;
        my $name = $1;
        $size = 4 * 1024;
        PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $format, $name, $size);
        $size *= 1024; # vdisk alloc takes KB, qemu-img dd's osize takes byte
-       $plugin->activate_volume($storeid, $scfg, $volname);
     }
+    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+    $plugin->activate_volume($storeid, $scfg, $volname);
 
-
+    print "generating cloud-init ISO\n";
     eval {
-       run_command([['genisoimage', '-R', '-V', $label, $path],
-                    ['qemu-img', 'dd', '-n', '-f', 'raw', '-O', $format,
-                     'isize=0', "osize=$size", "of=$iso_path"]]);
+       run_command([
+           ['genisoimage', '-quiet', '-iso-level', '3', '-R', '-V', $label, $path],
+           ['qemu-img', 'dd', '-n', '-f', 'raw', '-O', $format, 'isize=0', "osize=$size", "of=$iso_path"]
+       ]);
     };
     my $err = $@;
     rmtree($path);
@@ -128,7 +128,7 @@ sub cloudinit_userdata {
 
     if (defined(my $keys = $conf->{sshkeys})) {
        $keys = URI::Escape::uri_unescape($keys);
-       $keys = [map { chomp $_; $_ } split(/\n/, $keys)];
+       $keys = [map { my $key = $_; chomp $key; $key } split(/\n/, $keys)];
        $keys = [grep { /\S/ } @$keys];
        $content .= "ssh_authorized_keys:\n";
        foreach my $k (@$keys) {
@@ -171,8 +171,8 @@ sub configdrive2_network {
        $content .= "        dns_search $searchdomains\n";
     }
 
-    my @ifaces = grep(/^net(\d+)$/, keys %$conf);
-    foreach my $iface (@ifaces) {
+    my @ifaces = grep { /^net(\d+)$/ } keys %$conf;
+    foreach my $iface (sort @ifaces) {
        (my $id = $iface) =~ s/^net//;
        next if !$conf->{"ipconfig$id"};
        my $net = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"});
@@ -206,6 +206,13 @@ sub configdrive2_network {
     return $content;
 }
 
+sub configdrive2_gen_metadata {
+    my ($user, $network) = @_;
+
+    my $uuid_str = Digest::SHA::sha1_hex($user.$network);
+    return configdrive2_metadata($uuid_str);
+}
+
 sub configdrive2_metadata {
     my ($uuid) = @_;
     return <<"EOF";
@@ -224,10 +231,7 @@ sub generate_configdrive2 {
     $network_data = configdrive2_network($conf) if !defined($network_data);
 
     if (!defined($meta_data)) {
-       my $digest_data = $user_data . $network_data;
-       my $uuid_str = Digest::SHA::sha1_hex($digest_data);
-
-       $meta_data = configdrive2_metadata($uuid_str);
+       $meta_data = configdrive2_gen_metadata($user_data, $network_data);
     }
     my $files = {
        '/openstack/latest/user_data' => $user_data,
@@ -247,8 +251,8 @@ sub nocloud_network_v2 {
 
     my $dns_done;
 
-    my @ifaces = grep(/^net(\d+)$/, keys %$conf);
-    foreach my $iface (@ifaces) {
+    my @ifaces = grep { /^net(\d+)$/ } keys %$conf;
+    foreach my $iface (sort @ifaces) {
        (my $id = $iface) =~ s/^net//;
        next if !$conf->{"ipconfig$id"};
 
@@ -318,8 +322,8 @@ sub nocloud_network {
     my $content = "version: 1\n"
                 . "config:\n";
 
-    my @ifaces = grep(/^net(\d+)$/, keys %$conf);
-    foreach my $iface (@ifaces) {
+    my @ifaces = grep { /^net(\d+)$/ } keys %$conf;
+    foreach my $iface (sort @ifaces) {
        (my $id = $iface) =~ s/^net//;
        next if !$conf->{"ipconfig$id"};
 
@@ -388,6 +392,13 @@ sub nocloud_metadata {
     return "instance-id: $uuid\n";
 }
 
+sub nocloud_gen_metadata {
+    my ($user, $network) = @_;
+
+    my $uuid_str = Digest::SHA::sha1_hex($user.$network);
+    return nocloud_metadata($uuid_str);
+}
+
 sub generate_nocloud {
     my ($conf, $vmid, $drive, $volname, $storeid) = @_;
 
@@ -396,10 +407,7 @@ sub generate_nocloud {
     $network_data = nocloud_network($conf) if !defined($network_data);
 
     if (!defined($meta_data)) {
-       my $digest_data = $user_data . $network_data;
-       my $uuid_str = Digest::SHA::sha1_hex($digest_data);
-
-       $meta_data = nocloud_metadata($uuid_str);
+       $meta_data = nocloud_gen_metadata($user_data, $network_data);
     }
 
     my $files = {
@@ -458,7 +466,7 @@ sub generate_cloudinitconfig {
 
     my $format = get_cloudinit_format($conf);
 
-    PVE::QemuServer::foreach_drive($conf, sub {
+    PVE::QemuConfig->foreach_volume($conf, sub {
         my ($ds, $drive) = @_;
 
        my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
@@ -472,4 +480,29 @@ sub generate_cloudinitconfig {
     });
 }
 
+sub dump_cloudinit_config {
+    my ($conf, $vmid, $type) = @_;
+
+    my $format = get_cloudinit_format($conf);
+
+    if ($type eq 'user') {
+       return cloudinit_userdata($conf, $vmid);
+    } elsif ($type eq 'network') {
+       if ($format eq 'nocloud') {
+           return nocloud_network($conf);
+       } else {
+           return configdrive2_network($conf);
+       }
+    } else { # metadata config
+       my $user = cloudinit_userdata($conf, $vmid);
+       if ($format eq 'nocloud') {
+           my $network = nocloud_network($conf);
+           return nocloud_gen_metadata($user, $network);
+       } else {
+           my $network = configdrive2_network($conf);
+           return configdrive2_gen_metadata($user, $network);
+       }
+    }
+}
+
 1;