KVM Automation

Introduction

 This blog post describes one option for automating the build of a KVM guest.

There are alternative ways to automate the build but the method that is described here uses the ability to pass a kickstart file to the virt-install command when creating a new VM. Kickstart is a file contains the answers to all the normal questions that an interactive installer would ask during installation. The kickstart script installs software packages, configures SELinux, auditd, rsyslog etc.

This article has been cross-posted to the GI Architects blog.

Using virt-install with a kickstart file


The virt-install command is used to create new virtual machines / guests; it supports a `--initrd-inject` parameter allows you specify the path to an Anaconda Kickstart file.

An example virt-install command is provided below:

virt-install --connect=qemu:///system \
   --name ${GUEST} \
   --description "${GUEST_DESC}" \
   --os-type=Linux \
   --os-variant=rhel7 \
   --ram=${GUEST_RAM} \
   --vcpus=${GUEST_CPU} \
   --check-cpu \
   --autostart \
   --memballoon virtio \
   --network ${NETWORK} \
   --location "$ISO_DIR/$CENTOS_7_MIN_ISO" \
   --disk "$VHD_DIR/$GUEST-osdisk.img,size=$os_disk_size" \
   --nographics \
   --initrd-inject=/root/scripts/centos-7-min.ks \
   --extra-args="ks=file:/centos-7-min.ks \
       console=tty0 console=ttyS0,115200" \
   --noautoconsole

The key parameters as it pertains to automating the install are:

  • The `--initrd-inject` parameter specifies the path to the kickstart file on the host machine
  • The `--extra-args` parameter then specifies where the kickstart file is on the VM.
  • The `--noautoconsole` parameter specifies to not enter into a console - which is the default behaviour. The reason we disable this is because if we enter into a console it requires manual intervention to exit from the console after the kickstart installation completes in order to continue with the rest of the script for building a encrypted VM.

The Kickstart file


 The format of the Kickstart file will not be covered in detail here however, the key configuration lines that are important for automating the KVM VM build are highlighted below:

  • `text` specifies that a text based installation should be performed
  • `shutdown` specifies that the VM should be shutdown after the kickstart installation completes - this is important as we use this to detect when the installation and configuration is complete before we move on to encrypting the VM operating system disk.
  • `url --url=http://mirror.centos.org/centos/7/os/x86_64/ --proxy http://192.168.0.20:8080/` specifies the URL for the package repository and that it can be reached via the proxy 192.168.0.20 (if you have direct internet access then this line is not required, also if you are using an internal repo then the URL should be modified accordingly)
  • `repo --name=epel --baseurl=http://download.fedoraproject.org/pub/epel/7/x86_64/ --proxy http://192.168.0.20:8080` specifies the location of an additional repo, in this case, the EPEL repo and that it can be accessed via the proxy
  • The line below sets the password for the root user
    `rootpw --iscrypted $6$EaWILovy2GSnzYpr$jqFnyZn89hahnsdfh89y80gan08f90a78hhb.`
  • It is stored in hashed form you can generate this by running the command below:
  • `echo 'import crypt,getpass; print crypt.crypt(getpass.getpass(), "$6$16_CHARACTER_SALT_HERE")' | python -`


There was also a requirement to configure auditing and logging. Some of these files were quite long and so it was too unweildly to simply hardcode the entire contents of the files into the kickstart file and using heredocs to write them out to a file on the guest. In light of this I used base64 encoding and gunzip to encode the file.

The Kickstart file includes blocks of code such as the example below:
```
 echo 'H4sIANJpLVgAA61WX3MaNxB/7n2Kjek0qSd3GP+B1kkzQwA71Nh0wG6baTseodMdKjrpKumwmclD
 3/st+0m60gHG4LSB5h7gTtr9aX+7q92tPKuOuKyOiBkHlc/8BBU4PKjVawcHDbjgejT7/CdAgIdc
 LCQcPeMsR+/hERt+p7mLc5VZWp0fGVF0/uZKlGt2G49v5zYGlFg0Z0Pv9etO/8xfHbjst296nSH4
 vVb/tt45PDipHTVPDusn9cZDGXHZY8tfV03gA44xsfLJZw/9GAHh5XKQOzmpHYeW5iGOc5gxWFKw
 gUHInxSI8txPZ58/s9YRXa8tzApAubDcD0XwD3/sBlN2DQAA' | base64 -d | gunzip > configure-rsyslog.sh
 ```
This command decodes a base64 encoded string and then decompresses it and dumps it to a file; the string contains the code for a shell script. This is a convenient way to included scripts without including the entire code using heredocs.

To create the base64 encoded and compressed script enter the script as is into a file, then run the command:
`cat audisp-install.sh | gzip | base64 > test.sh`

Detecting completion of the kickstart script


After the `virt-install` command is run the virtual machine build script virt-create-guest.sh script waits for the VM to enter the shutdown state (recall that the kickstart file specified that the machine should be shutdown after installation) it does this using the following snippet by running

virsh domstate <guest vm name> and check if it returns "shut off".




Comments