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) = @_;
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);
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) {
$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"});
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";
$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,
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"};
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"};
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) = @_;
$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 = {
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);
});
}
+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;