[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