That recipe explains how to perform an unattended Debian GNU/Linux installation (thanks to preseeds) on a virtual machine using libvirt.

libvirt is a virtualization tool/library providing a common API to manage virtual machines over KVM, qemu, LXC, Xen, OpenVZ and many others. A interesting feature of libvirt is virsh, an application that allows to perform most of virtual machine operations from command line. That is good because… you can script virtual machine deployments!

libvirt packages

You need to install:

  • libvirt-bin
  • virtinst
  • virt-viewer

Virtual machine networking

You will need a virtual network to connect virtual machines to the host computer, libvirt comes with a default nat-based virtual network. You may see details of that network using next command:

# export LIBVIRT_DEFAULT_URI=qemu:///system
# virsh net-dumpxml default
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0' />
  <ip address='' netmask=''>
      <range start='' end='' />

It is required to start default network before run installer:

# export LIBVIRT_DEFAULT_URI=qemu:///system
# virsh net-start default


Next command installs a debian net-install in a virtual machine with name node1, RAM 512MB, virtual hard disk with name node1.img with a maximum of 8GB. If you do not specify other network, default is used.

# export LIBVIRT_DEFAULT_URI=qemu:///system
# virt-install \
  --debug \
  --name=node1 \
  --ram=512 \
  --disk ./node1.img,size=8 \

The virt-install script has many options with a lot of detail. The command above is the minimal functional option set that I found, but you probably may improve or customize it.

Now you must connect to the virtual machine console:

# virt-viewer node1

…and continue with the typical Debian installation wizard

Using virsh you are able to do a lot of operation over your virtual machine from command line:

# virsh start node1
# virsh shutdown node1
# virsh reboot node1
# virsh destroy node1
# virsh resume node1
# virsh screenshot node1
# virsh snapshot-create node1
# virsh snapshot-revert node1

And many many others. Also it is possible to manage virtual machines in remote actual computers (even migrate among them!).

Debian installer preseeding

But we want to improve this procedure. We want to get a basic but fully functional Debian installation with absolutely no manual operation. To make that possible we can use the Debian Install Preseeding system. You need to write a configuration file with the answers to all the wizard questions. For this recipe I am using next preseed file:

[ preseed.cfg ]

d-i debian-installer/locale string es_ES
d-i console-keymaps-at/keymap select es
d-i keyboard-configuration/xkb-keymap select es

d-i netcfg/choose_interface select auto
d-i netcfg/get_domain string unassigned-domain

d-i mirror/protocol string http
d-i mirror/country string manual
d-i mirror/http/hostname string
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
d-i mirror/suite select testing

d-i clock-setup/utc boolean true
d-i time/zone string Europe/Eastern
d-i clock-setup/ntp boolean true

d-i partman-auto/method string regular
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/confirm boolean true
d-i partman-auto/choose_recipe select atomic
d-i partman/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true

d-i passwd/make-user boolean false
d-i passwd/root-password-crypted password $1$6vSrqLkZ$qUkEBeV.ptGOMZoyeYZ.b/
tasksel tasksel/first multiselect standard
d-i pkgsel/include string openssh-server puppet
popularity-contest popularity-contest/participate boolean true
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean false
d-i finish-install/reboot_in_progress note

You can get detailed information of all these sentences in the Automating the installation using preseeding document.

Note the root-password-crypted line. This contains the MD5 sum for the root account password. This has been created executing the command:

$ printf "r00tme" | mkpasswd -s -m md5

Serving the preseed.cfg file

You must make this file accesible for the installer. A simple way is to install lighttpd and copy it in /var/www/preseed.cfg.

Other alternative is to run next commad in the directory containing the file.

# python -m SimpleHTTPServer 80

Ask virt-install load preseeds

We are going to repeat the installation using the preseed configuration. The new version of the virt-install command include an extra-args argument that will be passed as kernel options to the virtual machine:

# export LIBVIRT_DEFAULT_URI=qemu:///system
# virt-install \
  --debug \
  --name=node1 \
  --ram=512 \
  --disk ./node1.img,size=8 \
  --location= \
    auto=true priority=critical vga=normal hostname=node1 \

extra-args means:

  • ask only critical installation details.
  • set node1 as hostname. This way you can use the same pressed file to build many virtual machines.
  • URL to fetch the preseed config (at the host webserver in this case).

I want more, please

If you enjoy that, read virsh manpage and take a look to virt-manager … :-)


blog comments powered by Disqus