[pve-devel] rfc : implementing a cloudinit metadata server

Emmanuel Kasper e.kasper at proxmox.com
Wed Sep 20 10:41:29 CEST 2017


On 08/30/2017 07:52 AM, Alexandre DERUMIER wrote:
> Hi,
> 
> the previous cloudinit patches used a cdrom for config drive.
> 
> Wolfgang tell me that it could be great to get it work for lxc too.
> 
> 
> So maybe we could try to implement a cloudinit metadataserver, with same api than cloudstack (or amazon ec2, or both)
> 

Hi Alexandre

Not so feature-full like cloud-init, but I am using libguestfs for basic
VMs offline provisioning  (hostname, network, ssh key) and this method
might be of interest to you.
I am using for instance this smallish script in my testlab,

The VM selves expose their name in the namework via Multicast DNS (
avahi-daemon) so I directly connect to them on first boot via "ssh
vm_hostname.local"

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';
use Sys::Guestfs;


use PVE::RPCEnvironment;
use PVE::QemuConfig;
use PVE::QemuServer;
use PVE::Storage;

my $vmid = $ARGV[0] or die "no \$vmid specified";
my $root_authorized_key = $ARGV[1] || "/home/manu/.ssh/id_rsa.pub";

my $vm_conf = PVE::QemuConfig->load_config($vmid);
my $target_hostname = $vm_conf->{name} || "test-vm";

my $boot_disk = $vm_conf->{bootdisk} || "scsi0";
my $parsed_drive = PVE::QemuServer::parse_drive($boot_disk,
$vm_conf->{$boot_disk});
my $volid = $parsed_drive->{file};
my $cfg = PVE::Storage::config();
my $image = PVE::Storage::path($cfg, $volid);


my $g = Sys::Guestfs->new();
$g->add_drive($image);
$g->launch(); # miss a test that VM is powered off

my @roots = $g->inspect_os();
scalar @roots == 1 || die "non recognized rootfs or multiboot disk
detected";
my $root = $roots[0];

my %mount_map = $g->inspect_get_mountpoints($root);
my @fses = sort {length $a <=> length $b} keys(%mount_map);

foreach my $fs (@fses) {
    $g->mount($mount_map{$fs}, $fs);
}

$g->write("/etc/hostname", $target_hostname);
$g->write("/etc/hosts", "127.0.0.1 localhost\n");
$g->write_append("/etc/hosts", "127.0.0.2 $target_hostname\n");


my $net = <<'EOF';
auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp
EOF
$g->write("/etc/network/interfaces", $net);

$g->sh_lines('rm --verbose --force /etc/ssh/ssh_host_*');
$g->write("/etc/rc.local", "#!/bin/sh -e\n");
$g->write_append("/etc/rc.local", "-f ssh_host_ecdsa_key.pub ||
dpkg-reconfigure openssh-server\n");
$g->write_append("/etc/rc.local", "exit 0\n");

$g->upload($root_authorized_key, "/root/.ssh/authorized_keys");
$g->chmod(600, "/root/.ssh/authorized_keys");


say $g->cat("/etc/hostname") . ": successfull provisioning";

$g->shutdown();
$g->close();




More information about the pve-devel mailing list