[virt-tools-list] [virt-manager PATCH][v2][RFC] Introduction of cloud-init configuration in virt-install

Cole Robinson crobinso at redhat.com
Mon Jun 24 16:12:16 UTC 2019


On 6/21/19 1:18 PM, Athina Plaskasoviti wrote:
> I am sending a v2 of the patch for cloud init basic configuration during cloud image installation, applying previous suggestions.
> 
> Fixed: 
> 
> -the way the installation is triggered (no_install is no longer required):
> 	--install is_cloud=yes ... --import
> 
> -added tmpfile for the files that are being generated in the installation process 
> (meta-data, user-data, config.iso)
> 
> -changed condition in installerinject.py from label='cloud' to cloudinit=True
> 


I did some digging into cloud-init behavior to try and get a better idea
of what the minimal viable config is, and get ideas for future work.


cloud-init behavior
===================

The patch generates an .iso with volume label 'cidata' which is the
magic to make cloud-init search it for config data. cloud-init must find
a 'meta-data' and 'user-data' file in order to consider the iso a valid
data source. There isn't any requirements on the contents though. They
can both basically be empty AFAICT.

This patch is setting meta-data 'instance-id' and 'hostname' fields but
neither are required: instance-id seems to only be needed on real cloud
providers (and cloud-init fills in a 'nocloud' value for us by default).
hostname will predictably set the VM hostname but that's not something
we need to set by default. So in fact meta-data is fine to leave empty
and I think that should be our default behavior.

Every distro cloud image has some default config in
/etc/cloud/cloud.cfg. This is generated from cloud-init.git
tools/render-cloudcfg which generates cloud.cfg from
config/cloud.cfg.tmpl. Basically the only input to the template is the
distro name. For example fedora generates in in the RPM spec with simply:

python3 tools/render-cloudcfg --variant fedora >
$RPM_BUILD_ROOT/%{_sysconfdir}/cloud/cloud.cfg

cloud images seem to have this default behavior:
- ssh is enabled and running
- root account is locked
- cloud.cfg will explicitly disallow ssh to the root account, via
disable_root. Attempts to ssh to root will print an error message
pointing to the default account
- cloud.cfg will create a default account, locked, with full sudo access.

The name of the default account depends on the value passed to the
tools/render-cloudcfg script. For Fedora it's 'fedora', Ubuntu is
'ubuntu'. The openstack page here documents the common ones:
https://docs.openstack.org/image-guide/obtain-images.html

An extra note: I was wrong when I said in other threads that fedora
images have a default password, they just have a default account name
which is locked by default.

The user-data file can be used to set passwords and other user auth
config. For example this user-data file will unlock the default user and
change its password to FOOBAR:

#cloud-config
password: FOOBAR

cloud-init doesn't natively support setting an empty password, though
you can run arbitrary commands in user-data so it's achievable. The
user-data file has explicit support for marking passwords as expired and
for injecting ssh keys, among other things.


virt-install cli
================

I think the virt-install entry point for requesting cloud-init stuff
should actually be its own top level option, like --unattended, because
we may want to add suboptions and I don't want to mix those in with
--install. So I'm thinking:

# does whatever we choose for default behavior, like --install is_cloud
virt-install --cloud-init ...

# User provides their own user-data file. Maybe for meta-data too?
virt-install --cloud-init user-data=/path/to/user-data

# Specify password for the default user. Yeah I know this isn't
# a good pattern to put a password on the cli but we could combine it
# with immediate password expiration so the user has to change it
# on first log in
virt-install --cloud-init password=FOOBAR

# Something like this to inject an ssh key? But honestly I'm not
# convinced we should go down that route and instead just make users
# manually set this themselves like they would for any other VM
virt-install --cloud-init sshkey=/path/to/key


--cloud-init default behavior
=============================

This is the bit I'm not really sure about. We need to manipulate some
password in some way for the user to be able to log in.

For starters I think no matter what option we choose we should set the
password to expire on first log in, thus forcing the user to choose a
password of their own.

The safest: generate a long random password for the default user. Print
it to the virt-install console. 'virt-builder fedora-30' does this, for
example, using what looks like 16 char [a-zA-Z0-9]. User has to
transcribe it into the VM twice (once for initial login, once for
immediate password expiration). We probably want to pause for a couple
seconds after we print it to the console so the user actually notices it
was there before we launch the graphical console and steal their
attention. Having to hand type a password into a graphical console kinda
sucks because copy/paste isn't going to work out of the box with the
minimal cloud images. This interaction can be improved if we use 'virsh
console' by default for cloud images, which for Fedora at least are
smart enough to print to the serial console, I suspect others are as well.

The simplest: use the guest name as the default password. It's not
hardcoded, it's simple to type. Less safe though because the VM is
exposed to ssh for that first bootup with a possibly predictable password.

Some of the general downsides of the 'default user' approach is that we
need to communicate the default user name to the user as well, which is
different per distro image. This means we will need to track it in
libosinfo. This seems worthwhile to do anyways. In the mean time we
could just print a warning about looking it up, or take a guess.

Something involving root: Maybe we don't touch the default user at all
and instead set a root password. The 'root' user is well known, and root
is blocked from ssh by default so there isn't any fear of network
access. but this kinda violates the intentions of the distro disk images
which lock down root by default and want people to use an unprivileged
user but with sudo access. It also means we invalidate some of the
documentation out there about the image's default user name.

So I'm not really sure what to do, I'm interested in suggestions. We
should also consider how this will could possibly be exposed in
virt-manager as well. If we can ever detect that an image needs
cloud-init, we will either need to force the user to provide a password,
or inform them in some way what the default user/pass is


Image detection
===============

Some thoughts on image detection. Right now the only way to do that is
with libguestfs/virt-inspector. For example:

$ virt-inspector --no-applications --no-icon
cloudstuff/Fedora-Cloud-Base-30-1.2.x86_64.qcow2
<?xml version="1.0"?>
<operatingsystems>
  <operatingsystem>
    <root>/dev/sda1</root>
    <name>linux</name>
    <arch>x86_64</arch>
    <distro>fedora</distro>
    <product_name>Fedora 30 (Cloud Edition)</product_name>
    <major_version>30</major_version>
    <minor_version>0</minor_version>
    <package_format>rpm</package_format>
    <package_management>dnf</package_management>
    <hostname>localhost.localdomain</hostname>
    <osinfo>fedora30</osinfo>
    <mountpoints>
      <mountpoint dev="/dev/sda1">/</mountpoint>
    </mountpoints>
    <filesystems>
      <filesystem dev="/dev/sda1">
        <type>ext4</type>
        <uuid>ea711a29-e460-4879-9d70-9da99ae021f9</uuid>
      </filesystem>
    </filesystems>
  </operatingsystem>
</operatingsystems>

For the fedora example we could check for 'Cloud' in the product name.
Ubuntu doesn't have a marker that obvious though. And rather than add
yet more code from virt-install to try and do distro detection, it would
be nice if libosinfo could abstract this, which would likely need to
talk to libguestfs.

Downsides of using detection is that we may try to pass cloud-init data
to a VM that has already been installed, just because it was originally
based on the Fedora (Cloud Edition) for example. '--cloud-init none'
could disable that, but still doing it by default is a bit sketchy
because we could possibly misconfigure someones perfectly working VM. So
there's things to consider

That said adding OS detection from existing disk images is a useful
thing to do anyways, independent of trying to use it to determine if we
should enable --cloud-init or not. So it's something to think about

Thanks,
Cole




More information about the virt-tools-list mailing list