Install Debian as a Xen HVM
This guide presents a method to install Debian as a "Xen HVM domU" (a VM !), which is very close to what many do on bare metal : insert an external media like a CD or USB key, and install on permanent storage like a local hard disk.
This is not the most efficient or faster method to install a VM ! But it aims to be the most noob-friendly possible, to leave no one behind the hypervisor train.
Other methods may be using debootstrap, xen-tools, or any orchestration system.
The instructions and commands try to be as generic and failproof as possible, so you can copy/paste almost everything as-is and it should "just work".
You will see that some code blocks only contain variables. It is important to set them for the next commands to work !
If you come from the "desktop hypervisors" world, you will see the steps are similar : you configure a VM, add virtual disks, attach an ISO, and install Debian manually, but graphically.
Except we'll not be using a GUI to -manage- the VM (create, config, start, etc), only some file editing and a few commands in the shell.
If you really want to use a GUI, try apt install virt-manager, then use your brain to translate the commands into the correct click-clicks !
You should be able to do everything from virt-manager, including the disks and network config. But although perfectly fine for day-to-day ops, I think you will learn less using a GUI for this guide.
Contents
Summary
- fill prerequisites
- download a Debian ISO
- create the virtual hard disks
- create the VM config file
- boot the VM
- install Debian
Prerequisites
Obviously, you need a working Xen installation first, see Xen#Quickstart.
Working folder
We need to store a few files on dom0 :
- the VM config file
- the Debian ISO
- the virtual hard disk
So let's create a folder :
mkdir -p /vm/deb-hvm
This folder will be dubbed "the VM folder" further on.
Remote control
We need a VNC client to see the VM output. There are many, which one is a matter of taste, and you may already have one or more installed. Run ls -l /etc/alternatives/vncviewer to see which one is set, if any.
Some examples :
apt install gvncviewer
apt install tigervnc-viewer
apt install virt-viewer
apt install xtightvncviewer
Networking
Network access in the VM is not really essential, as all the Debian ISOs install a working system (although don't expect X from a netinst). If all you want is to try an installation, just skip this part entirely. You can always come back later, and set the network after Debian is installed.
Network is set up in two steps: create a bridge in dom0, then attach a network interface to it.
In this part, you may have to do things manually, and network connectivity will break temporarily. But everything is easily reverted by a dom0 reboot so don't worry.
1. Create a bridge
ip link add name br-deb0 type bridge || echo "Error: can't create the bridge."
ip link set dev br-deb0 up || echo "Error: can't bring the bridge up."
2. Attach the network card to the bridge
Run this :
( netif=$(ip r | grep "default via" | sed -E 's/.* dev ([^ ]+) .*$/\1/') && echo $netif ) || echo "Error: no iface found."
Looks ugly, but all it does is getting your NIC name. If you get the error message, configure internet access (in other words set a default gateway on any interface available), then retry.
If it still doesn't work, do this before continuing:
# display the list of interfaces
ip a
# hopefully you get more than localhost listed here
# let's say there's eth0, but great chances it's a funky systemd name instead
# set the var for the next commands - adapt eth0 to your interface name
( netif="eth0" && echo $netif ) || echo "Error: still no iface name !"
The next commands will temporarily break the network, but should restore it. When you move a NIC on a bridge, its IP configuration gets reset (not erased), and you need to set an IP on the bridge instead.
# better safe than sorry
[[ -z $netif ]] && echo "Error: netif not set, use above commands to set it"
# save the current NIC IP+mask
curr_ip=$(ip a show $netif | grep "scope global" | grep "inet\b" | awk '{print $2};') || echo "Error: no current IP"
# bring the NIC down
ip link set dev $netif down || echo "Error: can't bring $netif down"
# attach the NIC to the bridge
ip link set dev $netif master br-deb0 || echo "Error: can't add slave $netif to master br-deb0"
# set the IP on the bridge
ip a add $curr_ip dev $netif || echo "Error: can't set IP on the bridge. No network in dom0 !"
1. Download a Debian ISO
Any one will do, depending on what you want for a VM. This guide expects installing a GUI-based VM offline, so let's pick the DVD version. No network will be required during the install for X and co. Any flavor of the LiveCD would be equivalent.
If you have a working network config, better use the smaller and faster netinst ISO.
First, select an architecture :
# architecture
arch=amd64
#arch=arm64
Then, select -one- flavor :
# netinst
base_path=https://cdimage.debian.org/debian-cd/current/$arch/iso-cd
pattern="debian-[0-9]{2}"
# DVD
base_path=https://cdimage.debian.org/debian-cd/current/$arch/iso-dvd/
pattern="DVD-1.iso$"
# LiveCD - XFCE
base_path=https://cdimage.debian.org/debian-cd/current-live/$arch/iso-hybrid/
pattern="xfce.iso$"
#pattern="mate.iso$"
Download the files :
# better safe than sorry
[[ -z $base_path || -z $pattern ]] && echo "Error: vars not set"
# set working dir in the VM folder
cd /vm/deb-hvm || echo "Error: no VM folder"
# get the checksum and signature files
wget -c $base_path/SHA512SUMS || echo "Error: SHA-cksum file DL failed"
wget -c $base_path/SHA512SUMS.sign || echo "Error: SHA-sign file DL failed"
# extract the iso filename from the sha cksum file
iso_file=$(awk '{print $2};' SHA512SUMS | grep -E "$pattern")
# download corresponding iso
wget -c $base_path/$iso_file || echo "Error: DL failed for ISO file. Run the command again to resume a partial download."
# verify ISO
sha512sum --ignore-missing -c SHA512SUMS
# verify signature
gpg --verify SHA512SUMS.sign
2. Virtual disks
Disks will be of type RAW, for simplicity, and created as sparse, to minimize disk usage.
The first disk is where Debian will get installed. 40G is plenty, adjust if unhappy. You can always expand the size later, even after the install. The opposite may be trickier !
dd /vm/deb-hvm/disk-deb-hvm0.img 40G
Create a second disk for swap. It is optional, but has a few benefits. One is as backing up swap is usually useless, you can exclude the files from backups. You may also choose to store the file in a different location.
Usual swap rules apply, which means there's no universal size. If you plan on hibernating the VM, set at least as much as the domain RAM size.
dd /vm/deb-hvm/disk-deb-swap0.img 4G
3. Create the config file
A VM has a name, a number of vCPUs, RAM, disks, network interfaces, etc. These characteristics are set in a config file, usually with a ".cfg" extension.
The example config file below should work in most cases, and can be used almost directly. Except the ISO filename, no edits needed.
It's not full featured, but enough to install and test a basic Debian GUI VM.
Create a text file and save as "/vm/deb-hvm/deb-hvm.cfg".
Lines starting with # are comments.
## NAME - TYPE
# fun fact: the name is the only required parameter in a config file
name = 'deb-hvm'
# type of guest - here Hardware Virtual Machine
type = 'hvm'
## CPU - RAM
# 4 virtual CPUs, 4G RAM
vcpus = 4
memory = 4096
## QUIRKS
# Workaround bug #983357 in the Debian installer
vkb_device=0
## DISKs
# the HDDs and the ISO
# remove the swap line if not needed, but more importantly adjust the ISO filename !
disk = [
'/vm/deb-hvm/disk-deb-hvm0.img,,xvda' ,
'/vm/deb-hvm/disk-swap.img,,xvdb' ,
'/vm/deb-hvm/debian-12.5.0-amd64-netinst.iso,,xvdc' ,
]
## NETWORK
# if you created a bridge "br-deb0" in dom0, uncomment the next three lines to get networking
#vif = [
# 'bridge=br-deb0,mac=00:16:3e:de:bd:eb,vifname=deb-hvm'
#]
## BOOT ORDER
# c: hard disk ; d: cdrom ; n: network
boot = "cd"
# PXE boot
# boot = "n"
## DISPLAY
# vGPU
vga = 'stdvga'
videoram = '128'
# FRAMEBUFFER - VNC
vfb = [ 'vnc=1,127.0.0.1:1' ]
# FRAMEBUFFER - SDL
#vfb = [ 'sdl=1,opengl=1' ]
## MISC
# For smooth pointer integration with VNC
usb = 1
usbdevice = [ 'tablet' ]
## AUDIO
# optional, and some VNC clients cannot forward sound
#soundhw="hda"
4. Start the domain
Use the xl command to start the domain.
xl create /vm/deb-hvm/deb-hvm.cfg
To see what's happening, run
xentop -d 1
Use a VNC viewer to connect to the domU paravirtual framebuffer (ie. the video output).
vncviewer :1
From now on, it's like a normal Debian install, so you're on your own ! Text or graphical mode, install a GUI or not, etc. There's nothing particular to be aware of, except maybe the drives names : install on xvda, the CD-rom will be named xvdc, and if you chose to use a dedicated swap partition, it will be xvdb.
When the install is done, you can reboot.
If your VNC client has the auto-reconnect feature, just chill, if it doesn't, the window will close and you'll have to reconnect manually.
You should see the normal Debian GRUB menu, which should then auto boot Debian. Congrats, your first Xen VM is ready, and can now be configured as usual ! If you're sure the install went fine but you're back into the installer, are you sure you didn't edit the "boot" option ?
You may want to remove the Debian ISO, or the CD-rom drive. Edit the domain config file, you have two choices :
- if you dont need a CD-rom drive, or only rarely, remove or comment the line
- else keep the line but delete the path. The drive will appear as an empty CD-rom, and you'll be able to live mount ISOs from dom0
Note that even if you choose to remove the CD-rom drive completely, you will always be able to hotplug a CD-rom drive at runtime, with or without an ISO preloaded (see xl block-attach).
