In my day job, it’s all about automation. Automate what is repeatable, and move on to more interesting and not-yet-automated tasks. For a while, I’ve run a KVM/libvirt setup at home, running various iterations and distributions of Linux, OpenBSD and FreeBSD for various pet projects. Going through each distribution’s install procedure was getting old, requiring me to input the same parameters, set up the same users and passwords, over and over again. Given I use Ubuntu mostly as a VM guest, I dug into their preseed infrastructure, to be able to automate the installation and get me past the drudgery of adding another VM. Below are the steps and a bit of sample configuration that got me through the process.
I did find some examples of automating this all the way from virt-install (libvirt’s way of adding a VM instance to your cluster), but that is for another time.
[Update 2014-09-13: Even more unattended. Part 2]
Grab a Ubuntu Server ISO from their web site. Mount the ISO locally and rsync its contents to a new directory for your own customization.
mount -o loop /path/to/iso /some/mountpoint rsync -av /cdrom/ /opt/cd-image
Now we’re left with the customization of the install. I wanted the installation to be completely hands-free. I shouldn’t have to enter in any partition information, user names, or network information. Right now my parameters are, for the most part, configured in the preseed file. My eventual goal is the factor those out into my own personal install script so that the command line arguments from my script are passed as kernel options to the install and are read at run-time as opposed to at CD-creation time. Doing it that way alleviates the need to re-create a new ISO with hard-coded values for the host name, domain name, and various network information, among others, each time you want to build a new VM in the preseed file.
LABEL forman-preseed menu label ^Forman Preseed kernel /install/vmlinuz append preseed/file\=/cdrom/preseed/ubuntu-server-custom.seed vga\=788 initrd\=/install/initrd.gz locale\=en_US.UTF-8 console-keymaps-at/keymap\=us console-setup/ask_detect\=false console-setup/layoutcode\=us keyboard-configuration/layout\=USA keyboard-configuration/variant\=USA –
d-i debian-installer/locale string en_US d-i netcfg/choose_interface select eth0 d-i netcfg/get_hostname string preseedhost-1 d-i netcfg/get_domain string foobar.mylan d-i netcfg/wireless_wep string d-i time/zone string US/Eastern d-i clock-setup/ntp boolean true d-i partman/choose_partition select finish d-i partman/confirm boolean true d-i partman/confirm_nooverwrite boolean true d-i partman/default_filesystem string ext4 d-i partman-auto/init_automatically_partition select biggest_free d-i partman-auto/choose_recipe select atomic d-i partman-auto/method string regular d-i partman-auto/select_disk string /dev/vda d-i partman-md/confirm boolean true d-i partman-partitioning/confirm_write_new_label boolean true d-i passwd/root-password-crypted password
This creates a VM with the various properties (highlights for brevity):
- hostname = preseed-host1
- domain name = foobar.mylan
- network = DHCP via eth0
- partitioning scheme = one big / partition, with space leftover for SWAP
- one user with password set, along with root’s password.
- install openssh-server and irssi to confirm package installation works.
Create the CD image:
IMAGE\=custom.iso BUILD\=/opt/cd-image/ mkisofs -r -V “Custom Ubuntu Install CD” -cache-inodes -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o $IMAGE $BUILD
Voila. Boot that as your install CD and behold the magic! Booting from this ISO inside your VM instance should leave you with a fully functionining instance.
The only real hiccups I hit along the way, given the multitude of documentation out there on the Internet, was getting past the keyboard selection prompts. Specifying the keyboard model, layout, and ‘ask_boolean false’ values for that set of questions inside the preseed file had no affect, I was still prompted. Those configuration values seemed to be REQUIRED to be set in the isolinux config, which in my case I stuck in txt.cfg.
Sources (of inspiration):