]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuServer/Cloudinit.pm
cloud-init: don't use /tmp for config files
[qemu-server.git] / PVE / QemuServer / Cloudinit.pm
index 9fcb817be3df6d3ce62074d79f3f1851160d3be0..7758b84222464301e0409acbd56b8e553af37685 100644 (file)
@@ -12,7 +12,20 @@ use PVE::Storage;
 use PVE::QemuServer;
 
 sub commit_cloudinit_disk {
-    my ($conf, $drive, $volname, $storeid, $file_path, $label) = @_;
+    my ($vmid, $conf, $drive, $volname, $storeid, $files, $label) = @_;
+
+    my $path = "/run/pve/cloudinit/$vmid/";
+    mkpath $path;
+    foreach my $filepath (keys %$files) {
+       if ($filepath !~ m@^(.*)\/[^/]+$@) {
+           die "internal error: bad file name in cloud-init image: $filepath\n";
+       }
+       my $dirname = $1;
+       mkpath "$path/$dirname";
+
+       my $contents = $files->{$filepath};
+       file_set_contents("$path/$filepath", $contents);
+    }
 
     my $storecfg = PVE::Storage::config();
     my $iso_path = PVE::Storage::path($storecfg, $drive->{file});
@@ -21,9 +34,14 @@ sub commit_cloudinit_disk {
 
     my $size = PVE::Storage::file_size_info($iso_path);
 
-    run_command([['genisoimage', '-R', '-V', $label, $file_path],
-                ['qemu-img', 'dd', '-f', 'raw', '-O', $format,
-                 'isize=0', "osize=$size", "of=$iso_path"]]);
+    eval {
+       run_command([['genisoimage', '-R', '-V', $label, $path],
+                    ['qemu-img', 'dd', '-f', 'raw', '-O', $format,
+                     'isize=0', "osize=$size", "of=$iso_path"]]);
+    };
+    my $err = $@;
+    rmtree($path);
+    die $err if $err;
 }
 
 sub get_cloudinit_format {
@@ -44,26 +62,30 @@ sub get_cloudinit_format {
     return 'nocloud';
 }
 
-sub get_fqdn {
+sub get_hostname_fqdn {
     my ($conf) = @_;
-    my $fqdn = $conf->{hostname};
-    if (!defined($fqdn)) {
-       $fqdn = $conf->{name};
-       if (my $search = $conf->{searchdomain}) {
-           $fqdn .= ".$search";
-       }
+    my $hostname = $conf->{name};
+    my $fqdn;
+    if ($hostname =~ /\./) {
+       $fqdn = $hostname;
+       $hostname =~ s/\..*$//;
+    } elsif (my $search = $conf->{searchdomain}) {
+       $fqdn = "$hostname.$search";
     }
-    return $fqdn;
+    return ($hostname, $fqdn);
 }
 
 sub cloudinit_userdata {
     my ($conf) = @_;
 
-    my $fqdn = get_fqdn($conf);
+    my ($hostname, $fqdn) = get_hostname_fqdn($conf);
 
     my $content = "#cloud-config\n";
     $content .= "manage_resolv_conf: true\n";
 
+    $content .= "hostname: $hostname\n";
+    $content .= "fqdn: $fqdn\n" if defined($fqdn);
+
     my $username = $conf->{ciuser};
     my $password = $conf->{cipassword};
 
@@ -158,20 +180,12 @@ sub generate_configdrive2 {
 
     my $meta_data = configdrive2_metadata($uuid_str);
 
-    mkdir "/tmp/cloudinit";
-    my $path = "/tmp/cloudinit/$vmid";
-    mkdir $path;
-    mkdir "$path/drive";
-    mkdir "$path/drive/openstack";
-    mkdir "$path/drive/openstack/latest";
-    mkdir "$path/drive/openstack/content";
-    file_set_contents("$path/drive/openstack/latest/user_data", $user_data);
-    file_set_contents("$path/drive/openstack/content/0000", $network_data);
-    file_set_contents("$path/drive/openstack/latest/meta_data.json", $meta_data);
-
-    commit_cloudinit_disk($conf, $drive, $volname, $storeid, "$path/drive", 'config-2');
-
-    rmtree("$path/drive");
+    my $files = {
+       '/openstack/latest/user_data' => $user_data,
+       '/openstack/content/0000' => $network_data,
+       '/openstack/latest/meta_data.json' => $meta_data
+    };
+    commit_cloudinit_disk($vmid, $conf, $drive, $volname, $storeid, $files, 'config-2');
 }
 
 sub nocloud_network_v2 {
@@ -324,36 +338,27 @@ sub nocloud_network {
 }
 
 sub nocloud_metadata {
-    my ($uuid, $hostname) = @_;
-    return <<"EOF";
-instance-id: $uuid
-local-hostname: $hostname
-EOF
+    my ($uuid) = @_;
+    return "instance-id: $uuid\n";
 }
 
 sub generate_nocloud {
     my ($conf, $vmid, $drive, $volname, $storeid) = @_;
 
-    my $hostname = $conf->{hostname} // '';
     my $user_data = cloudinit_userdata($conf);
     my $network_data = nocloud_network($conf);
 
-    my $digest_data = $user_data . $network_data . "local-hostname: $hostname\n";
+    my $digest_data = $user_data . $network_data;
     my $uuid_str = Digest::SHA::sha1_hex($digest_data);
 
-    my $meta_data = nocloud_metadata($uuid_str, $hostname);
-
-    mkdir "/tmp/cloudinit";
-    my $path = "/tmp/cloudinit/$vmid";
-    mkdir $path;
-    rmtree("$path/drive");
-    mkdir "$path/drive";
-    file_set_contents("$path/drive/user-data", $user_data);
-    file_set_contents("$path/drive/network-config", $network_data);
-    file_set_contents("$path/drive/meta-data", $meta_data);
-
-    commit_cloudinit_disk($conf, $drive, $volname, $storeid, "$path/drive", 'cidata');
+    my $meta_data = nocloud_metadata($uuid_str);
 
+    my $files = {
+       '/user-data' => $user_data,
+       '/network-config' => $network_data,
+       '/meta-data' => $meta_data
+    };
+    commit_cloudinit_disk($vmid, $conf, $drive, $volname, $storeid, $files, 'cidata');
 }
 
 my $cloudinit_methods = {