InstantVM notes (Devuan Chimaera)

I run quite a few Virtual Machines hosted on my own hardware (generally multi-core AMD servers with 32 Gbytes RAM), running KVM / QEMU.

Many years ago a colleague and I created some scripts to make the creation of a new VM easier than it normally is (without using a GUI), but this still leaves you with a blank VM pointing at some installation CD image, which you then need to use to create the working VM.

Setting up a Devuan machine like this can easily take half an hour or so.

I wanted something faster, which would create a server installed and running the way I like it, so I decided to create a disk partition image which can be copied into a blank VM, and when booted, does a few things like set up its network, assign its hostname, and automatically expand the root filesystem to fit whatever size partition you asked for.

The result allows me to create a new VM in under 2 minutes (time is dependent on the hosting hardware, Internet connection speed, and how many packages have been updated since you created the template).

I created templates for Devuan Ascii and Beowulf, but I didn't keep proper notes on the process at the time, therefore these notes are being written as I go through the same procedure to create a Chimaera template. I expect I'll need them again in around a couple of years, once Daedalus has been released.

These notes were written in July 2022, and sure enough in October 2023 I've adapted them for Daedalus.

  1. Create a 2Gbyte partition Chimaera VM and go through the standard Devuan installation process, but do not re-start the server at the end
    • Use DHCP networking on eth0
    • Set the hostname to (literally) MyHostNameGoesHere
    • Leave the domain name blank
    • The root password, the first user and its password, will be replicated on every VM created from this image
    • Select Manual partitioning
      • Create vda1 of as large a size as possible, but leave around 1-2Mbyte free (yes, megabytes) for vda2 - try 2145900KB as the size for vda1
        • Make vda1 an ext4 partition for /
        • Set vda2 to "do not use"
      • Create vdb1 as swap
    • For a 2 Gbyte root FS, the package selector won't offer a desktop environment, but "SSH server" should be selected by default - this is exactly what you want for a server
    • When the installer wants to restart the machine, pause the Grub menu and then just shut down the VM
  2. Use ddrescue or similar to take a copy of the resultant disk image, just in case something goes horribly wrong with the next few steps and you need to start again - this saves you going through the entire Devuan installation process again
  3. Use kpartx to mount the (as yet never-booted-up) root partition and preserve the pristine /var/log directory, copy some files to be unpacked later, and then adjust some configuration files:
    kpartx -a /dev/LVM/VMname
    mount /dev/mapper/LVM-VMname1 /mnt
    rsync -Pav fs.tgz /mnt/
    cd /mnt
    rsync -Pav var/log/ var/log.pristine
    rm -f etc/apt/sources.list etc/apt/sources.list~
    sed -i "s/export PATH/export PATH\nexport HISTSIZE=10000\nexport HISTFILESIZE=10000\nexport HISTCONTROL=none\nexport HISTTIMEFORMAT=\"%F %T \"\nexport QUOTING_STYLE=literal/" etc/profile
    sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/; s/PubkeyAuthentication yes/PubkeyAuthentication yes\nPubkeyAcceptedKeyTypes=+ssh-dss/" etc/ssh/sshd_config
    sed -i "s/HashKnownHosts yes/HashKnownHosts no/" etc/ssh/ssh_config
    sed -i "s/sulogin/sulogin -t 30/" etc/init.d/checkfs.sh
    sed -i "s/#kernel.printk = 3 4 1 3/kernel.printk = 3 4 1 3/" etc/sysctl.conf
    sed -i "s/:root:/:MyHostNameGoesHere:/" etc/passwd
    umount /mnt
    dd if=/dev/zero of=/dev/mapper/LVM-VMname2
    kpartx -d /dev/LVM/VMname
    • Note: The fs.tgz file contains:
      etc/apt/apt.conf.d/42norecommendationsplease
      etc/apt/apt.conf.d/42nosuggestionsplease
      etc/apt/sources.list.d/Devuan-Chimaera.list
      etc/boot.d/firstboot
      etc/cron.midnight/
      etc/cron.midnight/.placeholder
      etc/cron.minutely/
      etc/cron.minutely/.placeholder
      etc/cron.yearly/
      etc/cron.yearly/.placeholder
      etc/cron.daily/backup
      etc/crontab
      etc/fstab
      etc/network/interfaces
      etc/timezone
      etc/rsyslog.d/default.conf
      etc/rsyslog.d/central.conf
      home/youruser/.ssh/authorized_keys
      root/.ssh/authorized_keys
      root/.ssh/backup.id_rsa
      root/.ssh/backup.id_rsa.pub
      root/.ssh/known_hosts
  4. Start the VM and run the following commands on it:
    tune2fs -L rootfs /dev/vda1
    ln -fs /usr/share/zoneinfo/Europe/Berlin /etc/localtime
    cd /
    tar -xvf fs.tgz
    rm -f fs.tgz
    apt-get install -y aptitude
    aptitude install -y less ntp rsync vim
    aptitude purge -y nano vim-tiny
    echo 'syntax off' >>~/.vimrc
    [ -e /etc/default/su ] || echo ALWAYS_SET_PATH=yes >/etc/default/su
    cat /etc/default/su | grep -q ALWAYS_SET_PATH || echo ALWAYS_SET_PATH=yes >>/etc/default/su
    aptitude install -y parted acpi{d,-support-base} sendmail s-nail dnsutils
    echo 'RESUME=LABEL=swap' >/etc/initramfs-tools/conf.d/resume
    update-initramfs -k all -u
  5. Shut down the server

You now have a VM server image which can be ddrescue'd over the top of a blank VM partition (2 Gbytes or bigger), and when booted, will be a usable VM in under 2 minutes, using the NewInstantVM script.


Go up
Return to main index.

Follow-up

After using this procedure for some years, two significant aspects have come to light:

  1. the template is not kept up to date with new package releases, and therefore the time to set up a machine gets longer and longer as time goes by, since the base template gets more and more out of date, with more updates needing to be applied when each machine gets created
  2. some package upgrades present an on-screen prompt (eg: "press q to quit" after displaying changelogs) and not only is this invisible if you don't happen to have connected to the VM console during the upgrade process, but it's actually impossible to quit from the display - none of q, Escape, Ctrl/C or anything else I have tried will exit from the changelog and continue with the upgrade process.

I think that setting DEBIAN_FRONTEND=noninteractive prior to the upgrade process might resolve the latter.