KVM guest // Bootstrap Ubuntu or Debian

this is almost a script

Bootstrap on a loop device

    guest=buster

    mkdir -p /data/guests/$guest/lala/
    cd /data/guests/$guest/
    dd if=/dev/zero of=$guest.img bs=1G count=0 seek=26

losetup -a | grep -v snapd/
    loopdevice=`losetup --find --partscan --show $guest.img`
    echo loopdevice is $loopdevice

    #loopdevice=`losetup -a | grep "$guest.img)$" | cut -f1 -d:`
    #[[ -n $loopdevice ]] && echo loopdevice already exists: $loopdevice
    #[[ -n $loopdevice ]] && echo loopdevice already exists: $loopdevice && exit 1

manual partitioning

fdisk $loopdevice

n
p
ENTER
ENTER
ENTER
a
w

    fdisk -l $loopdevice

as an alternative you could otherwise automate this

total=`fdisk -l $loopdevice | head -1 | awk '{print $7}'`

# 2048 * 512 = 1048576
echo -n writing vda.sfdisk...
cat > vda.sfdisk <<-EOF && echo done
label: dos
label-id: 0x8ae$((RANDOM % 10))$((RANDOM % 10))3cc
device: vda
unit: sectors

/dev/sda1 : start=2048, size=$((total-2048)), type=83, bootable
EOF
sfdisk $loopdevice < vda.sfdisk
#partprobe $loopdevice

prepare the file-system

    # not a file...
    #[[ ! -f ${loopdevice}p1 ]] && echo cannot find ${loopdevice}p1 && exit 1
    mkfs.ext4 ${loopdevice}p1
    mount ${loopdevice}p1 lala/

apt install debian-keyring debian-archive-keyring
ls -lF /usr/share/keyrings/debian-archive-keyring.gpg

# RUSSIA
    mirror=http://ftp.ru.debian.org/debian/
    zone=Europe/Moscow

# MD/RO
mirror=http://ftp.ro.debian.org/debian/
zone=Europe/Bucharest

# FRANCE
    mirror=http://ftp.fr.debian.org/debian/
    #mirror=http://mirror.eu.oneandone.net/debian/
    zone=Europe/Paris

    time debootstrap --arch=amd64 $guest lala/ $mirror
# 1m52,078s on bravo

    echo $guest > lala/etc/hostname # override
mv lala/etc/hosts lala/etc/hosts.dist
    cat > lala/etc/hosts <<-EOF
127.0.0.1       localhost $guest
::1             localhost ip6-localhost ip6-loopback $guest
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
EOF

    cat > lala/etc/fstab <<-EOF # override
    /dev/vda1 / ext4 defaults 0 1
    proc /proc proc defaults 0 0
    tmpfs /tmp tmpfs rw,nodev,nosuid,noatime,relatime 0 0
    devpts /dev/pts devpts gid=5,mode=620 0 0
    EOF

    cat > lala/etc/apt/sources.list <<-EOF
    deb $mirror buster main contrib non-free
    deb $mirror buster-updates main contrib non-free
    # stable-backports
    EOF

    rmdir lala/etc/network/interfaces.d/
    cat > lala/etc/network/interfaces <<-EOF # override
    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet dhcp
    EOF

    ln -sf ../usr/share/zoneinfo/$zone lala/etc/localtime
    echo $zone > lala/etc/timezone # override

    cp -pi lala/etc/bash.bashrc lala/etc/bash.bashrc.dist
    cat >> lala/etc/bash.bashrc <<-EOF

    export LANGUAGE="en_US:en"
    export LC_ALL="C.UTF-8"
    export LC_COLLATE="C.UTF-8"
    export LANG="C.UTF-8"

    alias ll='ls -alhF'
    alias cp='cp -i'
    alias mv='mv -i'
    alias rm='rm -i'

    EOF

we need a kernel in there (this is KVM)

    mkdir lala/lib/modules/

tar xzf /data/kernels/5.10.54.xenreiser4.modules.tar.gz -C lala/lib/modules/
cp /data/kernels/5.10.54.xenreiser4.vmlinuz lala/boot/vmlinuz

let’s proceed with the insider stuff

    chroot lala/

    passwd -d root
    perl -e exit

you might also want those additional packages

    export DEBIAN_FRONTEND=noninteractive
    apt install ifupdown net-tools man-db manpages openssh-server openssh-client mlocate wget vim-nox -y
    cat > /root/.vimrc <<EOF
    set paste
    set mouse=
    EOF

tune the XEN or KVM ubuntu guest userland serial console and exit the chroot

    systemctl set-default multi-user
    systemctl enable serial-getty@ttyS0.service
^D

Boot-blocks

setup the kvm guest boot-loader and kernel-time serial console

    dd if=/usr/lib/syslinux/mbr/mbr.bin of=$loopdevice
    mkdir lala/boot/syslinux/
    extlinux --install lala/boot/syslinux/ --device ${loopdevice}p1
    cp -f /usr/lib/syslinux/modules/bios/mboot.c32 lala/boot/syslinux/
    cp -f /usr/lib/syslinux/modules/bios/libcom32.c32 lala/boot/syslinux/
vi lala/boot/syslinux/syslinux.cfg

serial 0 115200
console 0
nohalt 1

default Linux
prompt 1
timeout 30

label Linux
    linux /boot/vmlinuz
    append root=/dev/vda1 ro console=ttyS0,115200n8 mitigations=off

label XEN
    kernel mboot.c32
    append /xen.gz loglvl=info guest_loglvl=info noreboot=true smt=1 ept=exec-sp com1=115200,8n1 console=com1 --- /vmlinuz root=/dev/vda1 ro console=hvc0 earlyprintk=xen nomodeset mitigations=off

you can also cumulate consoles as such

    # console=tty0 console=ttyS0,115200n8

note for XEN: yes hvc0 even for Dom0, and don’t forget to also tune agetty.

for Ubuntu / Debian also add

            net.ifnames=0 biosdevname=0

https://wiki.xenproject.org/wiki/Xen_FAQ_Console

https://wiki.xenproject.org/wiki/Xen_Serial_Console

umount lala/
rmdir lala/

    du -sh $guest.img
# 371M
# 810M

Ready to go

grep ^proc /proc/cpuinfo | tail -1
cat > $guest.xml <<EOF
<domain type='kvm'>
  <name>$guest</name>
  <memory unit='GiB'>1</memory>
  <currentMemory unit='GiB'>1</currentMemory>
  <vcpu placement='static'>12</vcpu>
  <os>
    <type arch='x86_64' machine='q35'>hvm</type>
    <boot dev='hd'/>
  </os>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/data/guests/$guest/$guest.img'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='bridge'>
      <source bridge='virbr0'/>
      <model type='virtio'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
    <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
  </devices>
</domain>
EOF

virsh create $guest.xml
virsh console $guest

^]

GNS3-ready

eventually make it available for GNS3

Troubleshooting

grub-install: error: unknown filesystem.

==> you need to see the partition, use losetup for that


GUIDES | LECTURES | BENCHMARKS | SMTP HEALTH