GenVM - Example of personalized virtual machine

This page describe complete procedure to generate a personalized virtual machine.

Virtual machine description

Or future virtual machine is defined by

  • name: webserver
  • size: 10G
  • root password is set to toor
  • architecture: amd64
  • partitions:
    • /, 5G on xfs
    • swap 250M
    • /srv, rest (around 5G) xfs
  • additional packages: apache2, mysql-server, php5, openssh-server
  • configuration IP by dhcp
  • virtual machine started on virtualbox after installation
  • ssh is nated on port 2222 and http on port 8080
  • disk image is on QCow2 format

Create needed files

First of all we create directory to store all files needed to store config files:

fhh@aaricia ~ $ mkdir -p ~/vm/webserver/config

Partitioning file (optional)

Because we want partitions on or virtual machine, we create partitioning file:

fhh@aaricia ~ $ cat > ~/vm/webserver/config/partitions.txt
# /, first partition, 5G, xfs
:5G:xfs
# swap, 250M
sw:250M
# /srv, using all available space, xfs
srv::xfs
^d
Note:
You can set partition schema directly from command line as describe below on Generating virtual machine.

look around GenVM - Partitioning for more informations about partitioning.

Additional packages

We add a file containing list of utile packages:

fhh@aaricia ~ $ cat > ~/vm/webserver/config/packages.lst
# Packages for network :
 ifupdown
 openssh-server
 isc-dhcp-client

# Text editor :
 vim

# log management :
 rsyslog
 logrotate

# Mail system :
 heirloom-mailx
 postfix

# Other packages :
 locales
 ntp
 cron
^d

To stay generic, this file don’t integrate dedicated packages passed to genvm from command line.

Refer to GenVM - Add packages for details about additional packages.

Personalizations scripts

We store scripts on 3rd directory

fhh@aaricia ~ $ mkdir -p ~/vm/webserver/config/3rd

Starting network at boot

The packages “ifupdown” and “isc-dhcp-client” are installed so, we configure the network on /etc/network/interfaces:

fhh@aaricia ~ $ cat > ~/vm/webserver/config/3rd/01.host.network
cat > "${MOUNT_POINT}/etc/network/interfaces" <<_eof_
auto lo eth0                    
 
iface lo inet loopback
 
iface eth0 inet dhcp
_eof_
^d

Personalizing apt-get

Recommended packages aren’t installed on this system:

fhh@aaricia ~ $ cat > ~/vm/webserver/config/3rd/01.chroot.norecommends
cat > /etc/apt/apt.conf.d/02norecommends <<_eof_
APT::Install-Recommends False;
_eof_
^d

Change permissions after installation

Disk image is given to user “fhh” and group “users”:

fhh@aaricia ~ $ cat > ~/vm/webserver/config/3rd/01.post.chown
chown fhh.users "${HD_IMG}"
^d

Modify sshd configuration

To established connection on virtual machine by SSH, copy your ssh public key on “/root/.ssh/authorized_keys” or authorize root connections with password.

fhh@aaricia ~ $ cat > ~/vm/webserver/config/3rd/02.chroot.sshd_config
sed -i.bak -e 's/^PermitRootLogin without-password$/PermitRootLogin yes/' /etc/ssh/sshd_config
^d

Create VM on VirtualBox

The virtual machine is added on virtualbox and configured.

fhh@aaricia ~ $ cat > ~/vm/webserver/config/3rd/50.post.add2vbox
su - fhh -c "/bin/bash <<[*_eof_*]

# If VM exist, unregister it (--delete risk to delete image disk) :
vboxmanage unregistervm ${NAME}

# create new vm:
vboxmanage createvm --name ${NAME} --ostype Debian_64 --register
vboxmanage modifyvm ${NAME} --memory 1024
vboxmanage storagectl ${NAME} --name sata_controller --add sata
vboxmanage storageattach ${NAME} --storagectl sata_controller --port 0 --device 0 --type hdd --medium "${HD_IMG}"

# add nat rules:

vboxmanage modifyvm ${NAME} --natpf1 ssh,tcp,,2222,,22
vboxmanage modifyvm ${NAME} --natpf1 http,tcp,,8080,,80

# to security, sleep 1 second
sleep 1

[*_eof_*]
"
^d
Note:
Virtual machine must be had on simple user (here fhh).

Starting virtual machine

Last script start the virtual machine:

fhh@aaricia ~ $ cat > ~/vm/webserver/config/3rd/99.post.startvm
su - fhh -c "/bin/bash <<[*_eof_*]
vboxmanage startvm ${NAME} --type headless
[*_eof_*]
"
^d

Overview

The final tree is like:

fhh@aaricia ~ $ tree ~/vm  
~/vm
└── webserver
    └── config
        ├── 3rd
        │   ├── 01.chroot.norecommends
        │   ├── 01.host.network
        │   ├── 01.post.chown
        │   ├── 02.chroot.sshd_config
        │   ├── 50.post.add2vbox
        │   └── 99.post.startvm
        ├── packages.lst
        └── partitions.txt

3 directories, 8 files

Download genvm

Download last version of script from GitHub:

fhh@aaricia ~ $ wget -q https://raw.githubusercontent.com/genvm/genvm/master/genvm -O vm/genvm
fhh@aaricia ~ $ chmod 755 vm/genvm

Generating virtual machine

At this step, all config files are available to create or future disk image. We can generate it by the following command :

fhh@aaricia ~ $ su -c "./vm/genvm -s 10G \
> -l vm/webserver/config/packages.lst \
> -n webserver \
> -P vm/webserver/config/partitions.txt \
> -t vm/webserver/config/3rd \
> -A xfsprogs,apache2,mysql-server,php5 \
> -p toor \
> -v \
> vm/webserver/webserver.vmdk"
Password:
...
‘-s’
define size of disk image
‘-l’
set file containing list of additional packages
‘-n’
set the name of virtual machine
‘-P’
for file containing partition definition
‘-t’
localize directory containing the scripts to execute for VM personalization
‘-A’
add some other packages (undefined in file used with ‘-l’)
‘-p’
set root password
‘-v’
active verbose mode
‘vm/webserver/webserver.vmdk’
locate the disk image

The partitions can be define directly from command line by replacing:

...
> -P vm/webserver/config/partitions.txt \
...

by

...
-P :5G:xfs \
-P sw:250M \
-P srv::xfs \
...

Testing virtual machine

At the end of process, GenVM exit successfully and you can test from your web browser the connection to your localhost on port 8080 or try to connect on SSH on localhost too (port 2222).

As you can see on VirtualBox user interface, the virtual machine is registered and running.

You can see the partitioning result:

root@webserver ~ # fstab -l
Disk /dev/sda: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x79484c3f

Device     Boot    Start      End  Sectors  Size Id Type
/dev/sda1  *        2048 10485759 10483712    5G 83 Linux
/dev/sda2       10485762 10997761   512000  250M 82 Linux swap / Solaris
/dev/sda3       10997764 20971517  9973754  4.8G 83 Linux

and the generated fstab:

root@webserver ~ # 
# <file system> <dir>   <type>  <options>       <dump>  <pass>
# /dev/sda2
UUID="090c0ff9-fb88-472f-ae30-27e01216aabd"     none    swap    defaults        0       0
# /dev/sda1
UUID="7c1899ed-95d6-4629-90f2-437514e73386"     /       xfs     defaults        0       1
# /dev/sda3
UUID="c0080219-8323-4ba8-b0df-bba190548dc6"     /srv    xfs     defaults        0       2