[pve-devel] [PATCH 2/2] cloud-init changes
Wolfgang Bumiller
w.bumiller at proxmox.com
Wed Jun 17 13:02:24 CEST 2015
* Changing cidr and gatway setting names to ip, ip6, gw,
gw6, as these are the names we are using for LXC.
* Adding explicit ip=dhcp and ip6=dhcp options.
* Removing the config-update code and instead generating
the ide3 commandline in config_to_command.
- Adding a conflict check to write_vm_config similar to
the one for 'cdrom'.
* Replacing UUID generation with a SHA1 hash of the
concatenated userdata and network configuration. For this
generate_cloudinit_userdata/network now returns the
content variable.
* Finishing ipv6 support in generate_cloudinit_network.
Note that ipv4 now only defaults to dhcp if no ipv6
address was specified. (Explicitly requested dhcp is
always used.)
---
PVE/QemuServer.pm | 71 +++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 51 insertions(+), 20 deletions(-)
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 7956c50..b9738da 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -18,7 +18,6 @@ use Cwd 'abs_path';
use IPC::Open3;
use JSON;
use Fcntl;
-use UUID;
use PVE::SafeSyslog;
use Storable qw(dclone);
use PVE::Exception qw(raise raise_param_exc);
@@ -1382,11 +1381,20 @@ sub parse_net {
$res->{firewall} = $1;
} elsif ($kvp =~ m/^link_down=([01])$/) {
$res->{link_down} = $1;
- } elsif ($kvp =~ m/^cidr=($IPV6RE|$IPV4RE)\/(\d+)$/) {
+ } elsif ($kvp =~ m/^ip=dhcp$/) {
+ $res->{address} = 'dhcp';
+ } elsif ($kvp =~ m/^ip=($IPV4RE)\/(\d+)$/) {
$res->{address} = $1;
$res->{netmask} = $2;
- } elsif ($kvp =~ m/^gateway=($IPV6RE|$IPV4RE)$/) {
+ } elsif ($kvp =~ m/^gw=($IPV4RE)$/) {
$res->{gateway} = $1;
+ } elsif ($kvp =~ m/^ip6=dhcp$/) {
+ $res->{address6} = 'dhcp';
+ } elsif ($kvp =~ m/^ip6=($IPV6RE)\/(\d+)$/) {
+ $res->{address6} = $1;
+ $res->{netmask6} = $2;
+ } elsif ($kvp =~ m/^gw6=($IPV6RE)$/) {
+ $res->{gateway6} = $1;
} else {
return undef;
}
@@ -1995,6 +2003,11 @@ sub write_vm_config {
delete $conf->{cdrom};
}
+ if ($conf->{cloudinit}) {
+ die "option cloudinit conflicts with ide3\n" if $conf->{ide3};
+ delete $conf->{cloudinit};
+ }
+
# we do not use 'smp' any longer
if ($conf->{sockets}) {
delete $conf->{smp};
@@ -3115,6 +3128,8 @@ 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"});
@@ -6297,9 +6312,9 @@ sub generate_cloudinitconfig {
mkdir "$path/drive/openstack";
mkdir "$path/drive/openstack/latest";
mkdir "$path/drive/openstack/content";
- generate_cloudinit_userdata($conf, $path);
- generate_cloudinit_metadata($conf, $path);
- generate_cloudinit_network($conf, $path);
+ my $digest_data = generate_cloudinit_userdata($conf, $path)
+ . generate_cloudinit_network($conf, $path);
+ generate_cloudinit_metadata($conf, $path, $digest_data);
my $cmd = [];
push @$cmd, 'genisoimage';
@@ -6310,10 +6325,18 @@ sub generate_cloudinitconfig {
run_command($cmd);
rmtree("$path/drive");
- my $drive = PVE::QemuServer::parse_drive('ide3', 'cloudinit,media=cdrom');
- $conf->{'ide3'} = PVE::QemuServer::print_drive($vmid, $drive);
- update_config_nolock($vmid, $conf, 1);
+}
+
+sub generate_cloudinit_command {
+ my ($conf, $vmid, $storecfg, $bridges, $devices) = @_;
+ return if !$conf->{cloudinit};
+
+ 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);
}
sub generate_cloudinit_userdata {
@@ -6336,15 +6359,13 @@ sub generate_cloudinit_userdata {
my $fn = "$path/drive/openstack/latest/user_data";
file_write($fn, $content);
-
+ return $content;
}
sub generate_cloudinit_metadata {
- my ($conf, $path) = @_;
+ my ($conf, $path, $digest_data) = @_;
- my ($uuid, $uuid_str);
- UUID::generate($uuid);
- UUID::unparse($uuid, $uuid_str);
+ my $uuid_str = Digest::SHA::sha1_hex($digest_data);
my $content = "{\n";
$content .= " \"uuid\": \"$uuid_str\",\n";
@@ -6353,9 +6374,7 @@ sub generate_cloudinit_metadata {
my $fn = "$path/drive/openstack/latest/meta_data.json";
- return file_write($fn, $content);
-
-
+ file_write($fn, $content);
}
my $ipv4_reverse_mask = [
@@ -6406,14 +6425,26 @@ sub generate_cloudinit_network {
$opt =~ s/net/eth/;
$content .="auto $opt\n";
- if ($net->{address}) {
+ if ($net->{address} && $net->{address} ne 'dhcp') {
$content .="iface $opt inet static\n";
$content .=" address $net->{address}\n";
$content .=" netmask $ipv4_reverse_mask->[$net->{netmask}]\n";
$content .=" gateway $net->{gateway}\n" if $net->{gateway};
- } else {
+ } elsif ($net->{address} eq 'dhcp' || !$net->{address6}) {
+ # don't default to dhcp if an ipv6 address is available, unless explicitly requested
$content .="iface $opt inet dhcp\n";
}
+
+ if ($net->{address6}) {
+ if ($net->{address6} ne 'dhcp') {
+ $content .="iface $opt inet6 static\n";
+ $content .=" address $net->{address6}\n";
+ $content .=" netmask $net->{netmask6}\n";
+ $content .=" gateway $net->{gateway6}\n" if $net->{gateway6};
+ } else {
+ $content .="iface $opt inet6 dhcp\n";
+ }
+ }
}
$content .=" dns-nameservers $conf->{nameserver}\n" if $conf->{nameserver};
@@ -6421,7 +6452,7 @@ sub generate_cloudinit_network {
my $fn = "$path/drive/openstack/content/0000";
file_write($fn, $content);
-
+ return $content;
}
--
2.1.4
More information about the pve-devel
mailing list