How to create image from scratch

This paper describes step-by-step how to create a fresh Linux images for Virtualmaster. As of now, Debian, Ubuntu, CentOS and Fedora are supported distros.


Create a virtual machine with decent resources (let’s say 2G RAM, 4G disk space). Virtual server resources can be lowered just before we create an image. Select whatever image you wish, it will be erased anyway.

After the virtual server is ready, boot in the rescue mode.

New File System

Wipe out the original system and mount empty root filesystem:

mkfs.ext3 -L root /dev/xvda
mkdir -p /mnt/root
mount /dev/xvda /mnt/root

Required Software Tools

In case you are on lenny (see /etc/apt/sources.list), you may want to use newer repos for debootstrap as natty is not included with debootstrap found in lenny

echo "deb stable main" >/etc/apt/sources.list
apt-get update
apt-get --force-yes -y install debian-keyring debian-archive-keyring

Install necessary tools. The debootstrap script is for Debian-likes and the yum package manager is for RedHat-likes.

apt-get update
apt-get --force-yes -y install debootstrap yum

Debian-Based Systems

Debian Squeeze (6.0)

Bootstrap base Debian system (squeeze release):

debootstrap squeeze /mnt/root

Fix apt sources:

cat >/mnt/root/etc/apt/sources.list <<EOF
deb squeeze main contrib non-free
deb squeeze/updates main contrib non-free

Debian Testing

Bootstrap base Debian system (testing rolling release):

debootstrap testing /mnt/root

Fix apt sources:

cat >/mnt/root/etc/apt/sources.list <<EOF
deb testing main contrib non-free
deb testing/updates main contrib non-free

Ubuntu Natty (11.04)

Bootstrap base Ubuntu system (natty release):

debootstrap natty /mnt/root

Fix apt sources:

cat >/mnt/root/etc/apt/sources.list <<EOF
deb natty main universe multiverse
deb natty-updates main universe multiverse

Entering Chroot

Prepare the installation for chrooting:

mount -t proc proc /mnt/root/proc
mount -t sysfs sysfs /mnt/root/sys
mount --bind /dev /mnt/root/dev
mount -t tmpfs tmpfs /mnt/root/dev/shm
mount -t devpts devpts /mnt/root/dev/pts

Copy the firstboot package into the target system:

cp virtualmaster-firstboot_*.deb /mnt/root/root/

Enter the installation:

chroot /mnt/root

Create file systems table:

cat >/etc/fstab <<EOF
/dev/xvda  /     ext3  relatime  1  1
/dev/xvdb  none  swap  sw        0  0

Make sure we won’t be running any services.

echo 'exit 0' >invoke-rc.d
chmod +x invoke-rc.d
export PATH="${PWD}:${PATH}"

Upgrade the system in order to get latest updates:

apt-get update
apt-get -y dist-upgrade

Debian workarounds

Install locales:

apt-get -y install locales

Compile american english, the default language:

sed 's/# en_US.UTF-8/en_US.UTF-8/' -i /etc/locale.gen
locale-gen%p Install the kernel:
apt-get -y install linux-image-xen-`dpkg --print-architecture`

Install the bootloader:

apt-get -y install grub-legacy

Generate bootloader configuration:

mkdir -p /boot/grub
update-grub 0

Fix text consoles configuration:

echo "T0:2345:respawn:/sbin/getty -L hvc0 38400 linux" >>/etc/inittab
sed 's/.* tty[2-6]$/#\0/' -i /etc/inittab

Ubuntu workarounds

Compile american english, the default language (Ubuntu version):

locale-gen en_US.UTF-8

Install the kernel:

apt-get -y install linux-image-virtual

Install the bootloader:

mkdir -p /boot/grub
apt-get -y install grub-legacy-ec2

Start getty on virtual console:

cat >/etc/init/hvc0.conf <<EOF
# hvc0 - getty for Xen
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
exec /sbin/getty -L hvc0 38400 linux

Disable getty on tty[2-6]:

for f in /etc/init/tty[2-6].conf; do
    mv -v "${f}"{,.off}

Common workarounds

Install some basic tools and ssh:

apt-get -y install less vim psmisc ssh ethtool mc sudo kbd

Now install the firstboot package.

dpkg -i virtualmaster-firstboot_*.deb
rm -f virtualmaster-firstboot_*.deb

Hook the firstboot into booting process as new init:

sed 's#\<root=#init=/sbin/init.vmin root=#' -i /boot/grub/menu.lst

Set local time zone:

ln -sf ../usr/share/zoneinfo/Europe/Prague /etc/localtime

Enable password-less sudo:

chmod +w /etc/sudoers
sed 's,#* *%sudo.*,%sudo ALL=(ALL) NOPASSWD: ALL,' -i /etc/sudoers
chmod -w /etc/sudoers

Disable IPv6 autoconfiguration. Our customers share L2 network and could cause a lot of trouble by starting radvd unless all VMs have this option disabled.

cat >>/etc/sysctl.conf <<EOF

# Do not listen to router advertisements.
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.eth0.autoconf = 0

Purge all configuration, ssh keys and remove cached packages:

echo -n     >/etc/network/interfaces
echo -n     >/etc/resolv.conf
echo image  >/etc/hostname
echo -n     >/etc/hosts
rm -f /etc/ssh/*key* /etc/virtualmaster.cfg*
rm -f /root/invoke-rc.d
apt-get clean

Finally, exit the chroot and remove history of commands:

rm -f /mnt/root/root/.bash_history

RedHat-Based Systems

Create file systems table:

mkdir -p /mnt/root/etc
cat >/mnt/root/etc/fstab <<EOF
/dev/xvda  /         ext3    relatime        1  1
/dev/xvdb  none      swap    sw              0  0
tmpfs      /dev/shm  tmpfs   defaults        0  0
devpts     /dev/pts  devpts  gid=5,mode=620  0  0

CentOS 6

Download the CentOS 6 release RPM and install it to the target filesystem:

wget '*.rpm'
rpm --root /mnt/root -ivh centos-release-*.rpm
rpm --root /mnt/root --import /mnt/root/etc/pki/rpm-gpg/*

Fedora 15

Download the Fedora 15 release RPM and install it to the target filesystem:

wget '[0-9]*.rpm'
wget '[0-9]*.rpm'
rpm --root /mnt/root -ivh fedora-release-*.rpm

Common Instructions

Now use yum to install the base system components:

yum -y --installroot=/mnt/root --nogpgcheck install \
yum kernel grub vim /usr/bin/passwd /usr/sbin/sshd \
cronie e2fsprogs mc logrotate sudo

Install our firstboot package:

yum -y --installroot=/mnt/root --nogpgcheck localinstall virtualmaster-firstboot-*.rpm

Chroot to the soon-to-be-system:

chroot /mnt/root

Fix the RPM database:

db_dump ~/.rpmdb/Packages | db_load /var/lib/rpm/Packages
rpm --rebuilddb
rm -rf ~/.rpmdb

Enable sudo:

chmod +w /etc/sudoers
sed 's,#* *\(%wheel.*NOPASSWD\),\1,' -i /etc/sudoers
chmod -w /etc/sudoers

Configure the bootloader:

kernel=$(echo /boot/vmlinuz-*)
initrd=$(echo /boot/initramfs-*)
os="$(sed 's/ release.*//' /etc/redhat-release)"
cat >/boot/grub/menu.lst <<EOF
title ${os} (${kernel#*-})
    root (hd0,0)
    kernel ${kernel} init=/sbin/init.vmin root=/dev/xvda ro console=hvc0
    initrd ${initrd}
ln -sf /boot/grub/grub.conf /etc/grub.conf
ln -f /boot/grub/menu.lst /boot/grub/grub.conf

Enable essential services:

chkconfig sshd on
chkconfig crond on
chkconfig network on

Disable tty[2-6],

sed 's#^\(ACTIVE_CONSOLES\)=.*#\1=/dev/tty1#' -i /etc/sysconfig/init

Purge all configuration and ssh keys:

rm -f /etc/sysconfig/network-scripts/ifcfg-eth*
rm -f /etc/sysconfig/network
rm -f /etc/ssh/*key* /etc/virtualmaster.cfg*
echo -n >/etc/resolv.conf
echo -n >/etc/hosts

Set up root‘s

echo '. /etc/bashrc' >~/.bashrc
echo '. ~/.bashrc' >~/.bash_profile

Leave the chroot:

rm -f /mnt/root/root/.bash_history

Finishing Up

Turn off the rescue system by issuing:


Back in the Virtualmaster web administration interface open a console and confirm the shutdown. Then shrink the VM as much as possible (both memory and disk space) and create an image.