[pve-devel] [PATCH qemu-server] cloudinit: add sshdeletehostkeys option

aderumier at odiso.com aderumier at odiso.com
Wed Feb 3 09:28:27 CET 2021


Le lundi 01 février 2021 à 17:12 +0100, aderumier at odiso.com a écrit :
> > 
> > [0] https://cloudinit.readthedocs.io/en/latest/topics/cli.html#clea
> > n
> 
> 
> The main problem currently is indeed that we change instance-id at
> each rebuild of the cloud-init disk.
> But I'm not sure that's it's possible to change ip address when
> keeping same instance-id, because ip configuration is done
> at the cloudinit-init-local service, at it's already done once. 
> Maybe this was the historic reason why we change the the instance-id
> each time, I don't remember exactly.
> I'll check that tomorrow to be sure, but indeed, keeping the
> instance-id should be the clean way.


Hi, I have redone tests with cloud-init.
So, the problem with networking config, is it's really only done
once by instance-id , and they are no way to change that.
(it's done in cloud-init local, and it's not possible to change that
like the others modules).

So, we really need to change instance-id each time.


Also, the ssh module manage both user ssh public keys,
and host private keys. So the only way is the trick of this patch to
disable the host key generation after first boot.


Currently I'm not using cloud-init, but I wonder if it's really
the good tool to manage configuration after the first boot.
(It's has been created by cloud-provider to really only run once at
first boot, and after that the configuration don't change).

I have looked on the net, and found than opennebula provide a nice 
tool to manage configuration at boot, but also changes in live.

https://github.com/OpenNebula/addon-context-linux

It's only simple a simple iso config drive with environment variables +
bash script + service for boot + udev rules to handle cdrom media
changes/nic plug/unplug live events.

Historically, opennebula was using cloud-init too (they are also an
opennebula config drive driver in cloud-init)
https://cloudinit.readthedocs.io/en/latest/topics/datasources/opennebula.html
 but it was not matching their workload, so they have created their own
script.
https://forum.opennebula.io/t/one-context-vs-cloud-init/1641


I have tested it, with a small patch in CloudInit.pm to generate the
cloudera context format, it's just working out of the box.
I can manage ips,hostname,sshkeys,resize partition  dynamically without
any trick.

I really like it, and with simple bash script + env var in config
drive, it's possible to easily adapt them for special need.
(I have some tricky network config in my production network)

a windows version is available too:
https://github.com/OpenNebula/addon-context-windows



What do you think to add this new datasource format support in current
Cloudinit.pm ? 

Here a sample (not cleaned yet):



+sub generate_opennebula {
+    my ($conf, $vmid, $drive, $volname, $storeid) = @_;
+
+    my ($hostname, $fqdn) = get_hostname_fqdn($conf, $vmid);
+
+    my $content = "";
+
+    my $username = $conf->{ciuser};
+    my $password = encode_base64($conf->{cipassword});

+        $keys = [map { my $key = $_; chomp $key; $key } split(/\n/,
$keys)];
+        $keys = [grep { /\S/ } @$keys];
+        $content .= "SSH_PUBLIC_KEY=\"";
+
+        foreach my $k (@$keys) {
+            $content .= "$k\n";
+        }
+        $content .= "\"\n";
+
+    }
+
+    my ($searchdomains, $nameservers) = get_dns_conf($conf);
+    if ($nameservers && @$nameservers) {
+        $nameservers = join(' ', @$nameservers);
+        $content .= "DNS=\"$nameservers\"\n";
+    }
+
+    $content .= "NETWORK=YES\n";
+    $content .= "SET_HOSTNAME=prout2\n";
+
+    if ($searchdomains && @$searchdomains) {
+        $searchdomains = join(' ', @$searchdomains);
+        $content .= "SEARCH_DOMAIN=\"$searchdomains\"\n";
+    }
+
+    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"});
+        my $ethid = "ETH$id";
+
+       my $mac = lc $net->{hwaddr};
+        if ($net->{ip}) {
+            if ($net->{ip} eq 'dhcp') {
+                $content .= "\n";  #opennebule don't handle DHCP
config.....
+            } else {
+                my ($addr, $mask) = split_ip4($net->{ip});
+               $content .= $ethid."_IP=$addr\n";
+               $content .= $ethid."_MASK=$mask\n";
+               $content .= $ethid."_MAC=$mac\n";
+               $content .= $ethid."_GATEWAY=$net->{gw}\n" if $net-
>{gw};
+            }
+        }
+
+    }
+
+    my $files = {
+       '/context.sh' => $content,
+    };
+    commit_cloudinit_disk($conf, $vmid, $drive, $volname, $storeid,
$files, 'CONTEXT');
+}
+
@@ -461,13 +531,14 @@ sub read_cloudinit_snippets_file {
 my $cloudinit_methods = {
     configdrive2 => \&generate_configdrive2,
     nocloud => \&generate_nocloud,
+    opennebula => \&generate_opennebula,
 };











More information about the pve-devel mailing list