Booting Fedora cloud images with KVM

Here’s how you can play with the Fedora cloud images on your local machine with KVM.

Download a cloud image.

wget https://download.fedoraproject.org/pub/fedora/linux/releases/30/Cloud/x86_64/images/Fedora-Cloud-Base-30-1.2.x86_64.qcow2

Make a new local backing image (so that we don’t write to our downloaded image) called my-disk.qcow2.

qemu-img create -f qcow2 -b Fedora-Cloud-Base-30-1.2.x86_64.qcow2 my-disk.qcow2 20G

The cloud image uses cloud-init to configure itself on boot which sets things like hostname, usernames, passwords and ssh keys, etc. You can also run specific commands at two stages of the boot process (see bootcmd and runcmd below) and output messages (see final_message below) which is useful for scripted testing.

Create a file called meta-data with the following content.

cat > meta-data << EOF
instance-id: Cloud00
local-hostname: cloud-00
EOF

Next, create a file called user-data with the following content (modify as required). This sets the default user to cloud with the password of password (you maybe like to use an encrypted password in the file instead) and unlocks the account so that you can log in at a terminal (without needing SSH). Add your own public SSH key too, if you like.

cat > user-data << EOF
#cloud-config
# Set the default user
system_info:
  default_user:
    name: cloud

# Unlock the default user
chpasswd:
  list: |
     cloud:password
  expire: False

# Other settings
resize_rootfs: True
ssh_pwauth: True
timezone: Australia/Sydney

# Add any ssh public keys
ssh_authorized_keys:
 - ssh-rsa AAA...example...SDvZ user1@domain.com

bootcmd:
 - [ sh, -c, echo "=========bootcmd=========" ]
 
runcmd:
 - [ sh, -c, echo "=========runcmd=========" ]
 
# For pexpect to know when to log in and begin tests
final_message: "SYSTEM READY TO LOG IN"
EOF

Cloud init mounts a CD-ROM on boot, so create an ISO image out of those files using either `genisoimage` or `mkisofs`.

genisoimage -output my-seed.iso -volid cidata -joliet -rock user-data meta-data
mkisofs -J -l -R -V "cidata" -iso-level 4 -o my-seed.iso user-data meta-data

If you want to SSH in you will need a bridge of some kind. If you’re already running libvirtd then you should have a virbr0 network device (used in the example below) to provide a local network for your cloud instance. If you don’t have a bridge set up, you can still boot it without network support (leave off the -netdev and -device lines below).

Now we are ready to boot this!

qemu-kvm -name fedora-cloud \
 -m 1024 \
 -hda my-disk.qcow2 \
 -cdrom my-seed.iso \
 -netdev bridge,br=virbr0,id=net0 \
 -device virtio-net-pci,netdev=net0 \
 -display sdl

You should see a window pop up and Fedora loading and cloud-init configuring the instance. At the login prompt you should be able to log in with the username cloud and password that you set in user-data.

5 thoughts on “Booting Fedora cloud images with KVM

  1. Hi, some time ago I made an automated build for the cloud-init configdrive at: https://gitlab.com/gbraad/cloud-init-configdrive/blob/master/.gitlab-ci.yml, which publishes the iso at http://gbraad.gitlab.io/cloud-init-configdrive/instance00-cidata.iso Clone the repository and change the files to your liking (be aware, do not publish important keys or password as the builds are public). Anyways, thanks for the write-up as I will certainly add some of the config, such as “final_message”.

  2. Hi Chris,
    4 years later, I would kike use the fedora 32 on a raspberry PI4.
    If i start the command:
    qemu-system-aarch64 -machine virt -name fedora-cloud -m 1024 -hda my-disk.qcow2 -cdrom my-seed.iso -netdev bridge, br=virbr0,id=net0 -device virtio-net-pci,netdev=net0
    I have an issue qemu-system-aarch64: br=virbr0,id=net0: drive with bus=0, unit=0 (index=0) exists
    I dont understand the problem.
    Maybe can you help me or explain me what is false.
    Thanks,
    Mdouke

  3. That just means you already have a machine running on `virbr0`, so you probably need to make that `virbr1` or +1 on any other interface you already have, which you should be able to see on your host with `sudo ip l |grep virbr`.

Leave a Reply

Your email address will not be published. Required fields are marked *