Newbie needs help: systemd-boot + luks + lvm + btrfs howto

Hello,

I am an arch user, trying to install my first nixos to a virtual machine. I would like to create the exact replica of my current system in arch with nixos. I will consider switching to nixos if I am able to do this and use final configuration files for the formating the current production system.

I have difficutty setting up the system with with systemd-boot, luks, lvm, btrfs in libvirt/virt-manager. The configuration presented below stucks at Booting from Hard Disk

I have following partition, mount hierarch on a single disk

  • boot (fat32-boot/efi) (non-encrypted)
  • luks
    • lvm
      • swap
      • root (btrfs)
      • home (btrfs)
      • vm (ext4)
      • data (btfts)

I have created necessary partions and done the relavant formatting for partitions and filesystem. There is no error there. I have a few submodules in btrfs root filesystem which you can observe in hardware-configuration.nix file below.

My current harware-configuration.nix is as follows. I have labeled luks device as luks
After os install and reboot, unfortunately, I can not get to the point where luks password is asked. I am sure I am missing some necessary configuration and the manual just skips these tricky parts.

{ config, lib, pkgs, modulesPath, ... }:

{
  imports =
    [ (modulesPath + "/profiles/qemu-guest.nix")
    ];

  boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
  boot.initrd.kernelModules = [ "dm-snapshot" ];
  boot.initrd.luks.devices = { 
      crypted = {  
        device = "/dev/disk/by-label/luks";
        preLVM = true;
     };
  };
  
  boot.kernelModules = [ "kvm-intel" ];
  boot.extraModulePackages = [ ];

  fileSystems."/" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@" "defaults"  "noatime" "compress=zstd" ];
    };

  fileSystems."/boot" =
    { device = "/dev/disk/by-label/boot";
      fsType = "vfat";
    };

  fileSystems."/nix" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@nix" "defaults" "noatime" "compress=zstd" ];
    };

  fileSystems."/opt" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@opt" "defaults" "noatime" "compress=zstd" ];
    };

  fileSystems."/var" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@var" "defaults" "noatime" "compress=zstd" ];
    };

  fileSystems."/var/log" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@var/log" "defaults"  "noatime" "compress=zstd" ];
    };

  fileSystems."/var/cache" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@var/cache" "defaults" "noatime" "compress=zstd" ];
    };

  fileSystems."/tmp" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@tmp" "defaults" "noatime" "compress=zstd" ];
    };

  fileSystems."/.snapshots" =
    { device = "/dev/vg/lvroot";
      fsType = "btrfs";
      options = [ "subvol=@.snapshots" "defaults" "noatime" "compress=zstd" ];
    };

  fileSystems."/home" =
    { device = "/dev/vg/lvhome";
      fsType = "btrfs";
      options = [ "defaults"  "noatime" "compress=zstd" ];
    };

  fileSystems."/data" =
    { device = "/dev/vg/lvdata";
      fsType = "btrfs";
      options = [ "defaults" "noatime" "compress=zstd" ];
    };

  fileSystems."/vms" =
    { device = "/dev/vg/lvvms";
      fsType = "ext4";
    };

  swapDevices =
    [ { device = "/dev/vg/lvswap"; }
    ];

  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
  # (the default) this is the recommended approach. When using systemd-networkd it's
  # still possible to use this option, but it's recommended to use it in conjunction
  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
  networking.useDHCP = lib.mkDefault true;
  # networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;

  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

my configuration.nix is as follows

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  boot.supportedFilesystems = [ "btrfs" ]; 
  boot.loader.systemd-boot.enable = true;
  boot.loader.systemd-boot.consoleMode = "auto";
  boot.loader.efi.canTouchEfiVariables = true;

  networking.hostName = "nixos-vms-pc"; # Define your hostname.

  users.users.user1 = {
     isNormalUser = true;
     extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
  };

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
     vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
     wget
     tmux
     git
  ];


  services.openssh.enable = true;

  system.stateVersion = "22.11"; # Did you read the comment?
}

Could someone provide a working example for this setup with systemd-boot options. I appreciate any help.

Could you provide more details? How is your VM configured / executed, logs from the boot process (screenshots could be helpful), what part of the boot chain is actually failing, etc.

In general:

  • systemd-boot is not involved in anything filesystem related. Your /boot is a plain vfat unencrypted partition, your kernel/initramfs will be stored there, and systemd-boot’s role is limited to chainloading your kernel. If booting doesn’t even reach systemd-boot, either it hasn’t been installed properly on your ESP, or your VM’s firmware fails to UEFI boot properly.
  • NixOS’s initramfs should log significantly more than just “Booting from Hard Disk”. You can also drop into a shell at various points in the boot process to allow you to debug, see NixOS 22.11 manual | Nix & NixOS
1 Like

Hello,

Thank you for responding. I will give more information as much as I could, but do you
see any missing configuration relevant to systemd-boot, luks configurations. I have a lot of differences in boot directory structure.

In my arch system my /boot directory is as follows

./intel-ucode.img
./EFI
./EFI/systemd
./EFI/systemd/systemd-bootx64.efi
./EFI/BOOT
./EFI/BOOT/BOOTX64.EFI
./EFI/Linux
./loader
./loader/entries
./loader/entries/arch-linux-lts.conf
./loader/entries/arch-linux-lts-fallback.conf
./loader/loader.conf
./loader/random-seed
./loader/entries.srel
./vmlinuz-linux-lts
./initramfs-linux-lts.img
./initramfs-linux-lts-fallback.img

My /boot/loader/entries/arch-linux-lts.conf file is as follows.

title arch linux-lts 
linux /vmlinuz-linux-lts
initrd /intel-ucode.img
initrd /initramfs-linux-lts.img
options root=UUID=9899f9ce-5738-4f69-9410-9e76b76817f1 rw rootflags=subvol=@ cryptdevice=UUID=239d40b4-5231-4b8b-813b-f6fb7ad8db6c:cryptroot zswap.enabled=1 zswap.compressor=lz4 zswap.max_pool_percent=20 zswap.zpool=z3fold ipv6.disable=1

In nixos system, after nixos-install, the /boot directory is as follows. I tried to install the os three times so I guess, I see three generations

/EFI
/EFI/systemd
/EFI/systemd/systemd-bootx64.efi
/EFI
/EFIX64.EFI
/EFI/Linux
/EFI/nixos
/EFI/nixos/fxm9nc2frpsvb1fjzbck0w2jkbkakm3n-linux-5.15.110-bzImage.efi
/EFI/nixos/6rz2wzmdhhr1mcglgl7h6l0g43s5pny1-initrd-linux-5.15.110-initrd.efi
/EFI/nixos/hzax7bs239d0yqh75wa7857vz69rm233-initrd-linux-5.15.110-initrd.efi
/EFI/nixos/.extra-files
/loader
/loader/entries
/loader/entries/nixos-generation-1.conf
/loader/entries/nixos-generation-2.conf
/loader/entries/nixos-generation-3.conf
/loader/loader.conf
/loader/random-seed
/loader/entries.srel

The content of the /boot/loader/entries/nixos-generation-3.conf is as follows.

title NixOS
version Generation 2 NixOS 22.11.4147.9656e85a15a, Linux Kernel 5.15.110, Built on 2023-05-19
linux /efi/nixos/fxm9nc2frpsvb1fjzbck0w2jkbkakm3n-linux-5.15.110-bzImage.efi
initrd /efi/nixos/6rz2wzmdhhr1mcglgl7h6l0g43s5pny1-initrd-linux-5.15.110-initrd.efi
options init=/nix/store/hpp6x86illyhg0sj86vgyb6kdqyy6ax9-nixos-system-nixos-vms-pc-22.11.4147.9656e85a15a/init loglevel=4
machine-id 3735b470f767445f95be9687a99733c4

Option section, according to me what I know from arch missing the luks device and root device inside the luks device.

Do you have any idea about it?

All of that seems to be like I would expect it to be. One thing is that your NixOS install doesn’t have systemd-boot installed as \efi\boot\bootx64.efi in your ESP, which means that your firmware might not be able to find it unless properly configured via NVRAM variables. Maybe you need boot.loader.efi.canTouchEfiVariables = false instead of true?

The boot options that Arch sets via its boot loader entry are unnecessary on NixOS because this is all built into the initrd instead.

1 Like

Hello,

Thank you baring with me?

I mount fat32 boot partition (/dev/vda1) as /boot. Should I mount as /boot/efi? Could you please elaborate? My mount are like this during install… (During installation, I use /mnt/root as installation mount point)

lsblk -f
NAME            FSTYPE      FSVER            LABEL                      UUID                                   FSAVAIL FSUSE% MOUNTPOINTS
loop0           squashfs    4.0                                                                                      0   100% /nix/.ro-store
sr0             iso9660     Joliet Extension nixos-minimal-22.11-x86_64 1980-01-01-00-00-00-00                       0   100% /iso
vda                                                                                                                           
├─vda1          vfat        FAT32            boot                       FB58-1B33                               987.1M     3% /mnt/root/boot
└─vda2          crypto_LUKS 2                luks                       d236d1d3-a0d5-431e-901f-a83f55dc3e21                  
  └─crypted     LVM2_member LVM2 001                                    lfGvNx-fvzu-ScIa-2fNB-pJ94-MUyB-eWrZ1S                
    ├─vg-lvswap swap        1                swap                       3834b3cd-c885-4efa-8095-7f5a976baca5                  [SWAP]
    ├─vg-lvroot btrfs                        root                       fbda7736-0089-4e18-899f-96c31fb5a596      8.6G    12% /mnt/root/.snapshots
    │                                                                                                                         /mnt/root/tmp
    │                                                                                                                         /mnt/root/var/log
    │                                                                                                                         /mnt/root/var/cache
    │                                                                                                                         /mnt/root/var
    │                                                                                                                         /mnt/root/opt
    │                                                                                                                         /mnt/root/nix
    │                                                                                                                         /mnt/root
    ├─vg-lvhome btrfs                        home                       8c10524e-cf69-43d4-a418-add0b2810849      4.5G     0% /mnt/root/home
    ├─vg-lvvm   ext4        1.0              vm                         e936428e-3a38-44ac-92c0-8256ae194b38      4.6G     0% /mnt/root/vm
    └─vg-lvdata btrfs                        data                       9a7cf90a-6a3b-41a1-98c7-06afca01c9f3      4.5G     0% /mnt/root/data

findmt 
├─/mnt/shared                shared                              virtiofs   rw,relatime
└─/mnt/root                  /dev/mapper/vg-lvroot[/@]           btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=256,subvol=/@
  ├─/mnt/root/boot           /dev/vda1                           vfat       rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro
  ├─/mnt/root/vm             /dev/mapper/vg-lvvm                 ext4       rw,relatime
  ├─/mnt/root/nix            /dev/mapper/vg-lvroot[/@nix]        btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=257,subvol=/@nix
  ├─/mnt/root/opt            /dev/mapper/vg-lvroot[/@opt]        btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=258,subvol=/@opt
  ├─/mnt/root/var            /dev/mapper/vg-lvroot[/@var]        btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=259,subvol=/@var
  │ ├─/mnt/root/var/cache    /dev/mapper/vg-lvroot[/@var/cache]  btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=260,subvol=/@var/cache
  │ └─/mnt/root/var/log      /dev/mapper/vg-lvroot[/@var/log]    btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=261,subvol=/@var/log
  ├─/mnt/root/tmp            /dev/mapper/vg-lvroot[/@tmp]        btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=262,subvol=/@tmp
  ├─/mnt/root/.snapshots     /dev/mapper/vg-lvroot[/@.snapshots] btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=263,subvol=/@.snapshots
  ├─/mnt/root/home           /dev/mapper/vg-lvhome               btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=5,subvol=/
  └─/mnt/root/data           /dev/mapper/vg-lvdata               btrfs      rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=5,subvol=/

Based on above information what should be the uuid for marked places or these statements correct in terms of mounting luks. I am not directly referencing /dev/mapper/crypted anywhere… crypted is the mapping alias that comes with cryptsetup open /dev/vda2 crypted. There are two uuids as you know…

  1. /dev/vda2
  2. /dev/mapper/crypted
  boot.initrd.luks.devices = { 
      crypted = {  
        device = "/dev/disk/by-label/luks";   <<<< THE UUID?  (Currently real disk partition /dev/vda2)
        preLVM = true;
     };
  };

  fileSystems."/" =
    { device = "/dev/vg/lvroot";    <<< THE UUID?  IS THIS CORRECT? 
      fsType = "btrfs";
      options = [ "subvol=@" "defaults"  "noatime" "compress=zstd" ];
    };

How can I pass boot.debug parameter to kernel?

Thanks again…

Hello,

I have tried

  1. stock generated configuration files with only adding
 boot.initrd.luks.devices = { 
      crypted = {  
        device = "/dev/disk/by-uuid/luks";  ## /dev/vda2
        preLVM = true;
     };
  };

which did not work.

  1. I tried mount esp to /boot/esp which also did not work.

  2. I changed systemd-boot to grup but still stuck at “Booting from disk”

  3. I do not reach any systemd-boot or grub menu in any case. I am really in need of help. I do not understand what is going on. I am pretty confident about luks/systemd-boot but nixos doing a lot of underhood things which I can not traca with my basic knowledge. I do not even know how I can debug the boot or pass boot paratemeter to grub in nixos.

For each test, I deleted the disk, repartition with the following script which I wrote to simplify the tests. I checked script several times, and its generation. The partitions and the mounts are correct. My virtual machine disk is around 50g.

#!/usr/bin/env bash

DISK=/dev/vda
LUKSPASSWORD='123456'
BOOTSIZE="1G"
SWAPSIZE="3G"
ROOTSIZE="10G"
HOMESIZE="5G"
VMSIZE="5G"
DATASIZE="5G"
BTRFSOPTIONS="defaults,ssd,noatime,compress=zstd"

if [ -z $DISK ]
then
  echo "Disk path is needed!"
  exit 1
fi

if ! [ -b $DISK ]
then
  echo "$DISK is not a block device"
  exit 1
fi

# erase disks and create partitions
echo "STARTING DISK PARTITIONING"
echo "Erasing disk $DISK"
sgdisk -og "$DISK"

echo "Creating boot partition"
sgdisk -n 1::+1G  -c 1:boot -t 1:ef00 $DISK

echo "Creating luks partition"
sgdisk -n 2::0  -c 2:luks -t 2:8309 $DISK

echo "Format luks volume at ${DISK}2"
echo -n $LUKSPASSWORD | cryptsetup --batch-mode luksFormat --label luks "${DISK}2" -

sleep 5

echo "Open luks volume to /dev/mapper/crypted"
echo -n $LUKSPASSWORD | cryptsetup open "${DISK}2" crypted -

sleep 5

echo "CREATE LVM GROUPS"
echo "Create physical volume"
pvcreate /dev/mapper/crypted
pvdisplay

echo "Create virtual volume"
vgcreate vg /dev/mapper/crypted
vgdisplay

echo "Create swap logical volume"
lvcreate --name lvswap --size $SWAPSIZE vg 

echo "Create root logical volume"
lvcreate --name lvroot --size $ROOTSIZE vg 

echo "Create home logical volume"
lvcreate --name lvhome --size $HOMESIZE vg 

echo "Create vm  logical volume"
lvcreate --name lvvm --size $VMSIZE vg 

echo "Create data logical volume"
lvcreate --name lvdata --size $DATASIZE vg

echo "CREATING FILE SYSTEMS"

echo "Format Boot Partitition at ${DISK}1"
mkfs.fat -F 32 -n boot "${DISK}1"

echo "Format and enable swap"
mkswap -L swap /dev/vg/lvswap
swapon -v /dev/vg/lvswap

echo "Format root partition with btrfs"
mkfs.btrfs -L root /dev/vg/lvroot

echo "Format home partition with btrfs"
mkfs.btrfs -L home /dev/vg/lvhome

echo "Format data partition with btrfs"
mkfs.btrfs -L data /dev/vg/lvdata

echo "Format vms partition with ext4"
mkfs.ext4 -L vm /dev/vg/lvvm

echo "Create directory root"
mkdir -p /mnt/root

echo "Mount root"
mount -t btrfs /dev/vg/lvroot /mnt/root

echo "Create hidden/flat btrs subvolumes under root"
btrfs su cr /mnt/root/@
btrfs su cr /mnt/root/@nix
btrfs su cr /mnt/root/@opt
btrfs su cr /mnt/root/@var
btrfs su cr /mnt/root/@var/cache
btrfs su cr /mnt/root/@var/log
btrfs su cr /mnt/root/@tmp
btrfs su cr /mnt/root/@.snapshots

echo "Umount root"
umount /mnt/root

echo "Mount root properly"
mount -t btrfs -o subvol=@,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root

echo "Create necessary root directories for mounting btrfs subvolumes"
mkdir -p /mnt/root/{boot,boot/efi,nix,home,data,vm,opt,var,var/cache,var/log,tmp,.snapshots}

echo "Mount boot/efi"
mount /dev/disk/by-label/boot /mnt/root/boot/efi

echo "Mount btrfs submodules under root" 
mount -t btrfs -o subvol=@nix,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root/nix
mount -t btrfs -o subvol=@opt,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root/opt
mount -t btrfs -o subvol=@var,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root/var
mount -t btrfs -o subvol=@var/cache,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root/var/cache
mount -t btrfs -o subvol=@var/log,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root/var/log
mount -t btrfs -o subvol=@tmp,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root/tmp
mount -t btrfs -o subvol=@.snapshots,${BTRFSOPTIONS} /dev/vg/lvroot /mnt/root/.snapshots

echo "Mount btrfs home partition"
mount -t btrfs -o ${BTRFSOPTIONS} /dev/vg/lvhome /mnt/root/home

echo "Create a subvolume for default user home directory"
btrfs su cr /mnt/root/home/toktay

echo "Mount btrfs data partition"
mount -t btrfs -o ${BTRFSOPTIONS} /dev/vg/lvdata /mnt/root/data

echo "Mount ext4 vm partition"
mount /dev/vg/lvvm /mnt/root/vm # ext4

Hello,

I have decided to start from the most basic configuration, not using btrfs, luks etc, just using fat32 unencrpted boot and second partition with luks+ext4. I have not touched hardware-configuration.nix, it is generated and luks statements are added contrary to lvm option. I only added systemd-boot statements to the configuration and some packages. Detail of the setup is as follows. Unfortunately even this simple setup did not work. I am stuck at “Booting from disk” statement. I am really frustrated.

lsblk -f

NAME        FSTYPE      FSVER            LABEL                      UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
loop0       squashfs    4.0                                                                                    0   100% /nix/.ro-store
sr0         iso9660     Joliet Extension nixos-minimal-22.11-x86_64 1980-01-01-00-00-00-00                     0   100% /iso
vda                                                                                                                     
├─vda1      vfat        FAT32            boot                       C7AC-577C                            1001.8M     2% /mnt/root/boot
└─vda2      crypto_LUKS 2                luks                       bc68762f-d85f-44c3-bebd-9212ad79918f                
  └─crypted ext4        1.0              root                       358e35a6-0ad3-44ea-8ef8-2fcbec272cb7   43.9G     3% /mnt/root

findmnt

TARGET                       SOURCE              FSTYPE     OPTIONS
.
.
├─/mnt/shared                shared              virtiofs   rw,relatime
└─/mnt/root                  /dev/mapper/crypted ext4       rw,relatime
  └─/mnt/root/boot           /dev/vda1           vfat       rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro

generated configuration files

hardware-configuration.nix

{ config, lib, pkgs, modulesPath, ... }:
{
  imports =
    [ (modulesPath + "/profiles/qemu-guest.nix")
    ];

  boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
  boot.initrd.kernelModules = [ ];
  boot.kernelModules = [ "kvm-intel" ];
  boot.extraModulePackages = [ ];

  fileSystems."/" =
    { device = "/dev/disk/by-uuid/358e35a6-0ad3-44ea-8ef8-2fcbec272cb7";
      fsType = "ext4";
    };

  boot.initrd.luks.devices."crypted".device = "/dev/disk/by-uuid/bc68762f-d85f-44c3-bebd-9212ad79918f";

  fileSystems."/boot" =
    { device = "/dev/disk/by-uuid/C7AC-577C";
      fsType = "vfat";
    };

  swapDevices = [ ];

  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

configuration.nix

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  boot.loader.efi.efiSysMountPoint = "/boot";
  boot.loader.systemd-boot.enable = true;

  environment.systemPackages = with pkgs; [
    vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    wget
    curl
    git
  ];
  system.stateVersion = "22.11"; # Did you read the comment?
}

Script to generate partitions

#!/usr/bin/env bash -v

echo "Assuming there is only one  disk"
echo "Assuming disk device is passed as first argument"

DISK=/dev/vda
LUKSPASSWORD='123456'

if [ -z $DISK ]
then
  echo "Disk path is needed!"
  exit 1
fi

if ! [ -b $DISK ]
then
  echo "$DISK is not a block device"
  exit 1
fi

# erase disks and create partitions
echo "STARTING DISK PARTITIONING"
echo "Erasing disk $DISK"
sgdisk -og "$DISK"

echo "Creating boot partition"
sgdisk -n 1::+1G  -c 1:bootdisk -t 1:ef00 $DISK

echo "Creating luks partition"
sgdisk -n 2::0  -c 2:luksdisk -t 2:8309 $DISK

echo "Format luks volume at ${DISK}2"
echo -n $LUKSPASSWORD | cryptsetup --batch-mode luksFormat --label luks "${DISK}2" -

sleep 5

echo "Open luks volume to /dev/mapper/crypted"
echo -n $LUKSPASSWORD | cryptsetup open "${DISK}2" crypted -

sleep 5

echo "Format Boot Partitition at ${DISK}1"
mkfs.fat -F 32 -n boot "${DISK}1"

echo "Format root partition with btrfs"
mkfs.ext4 -L root /dev/mapper/crypted

echo "Create directory root"
mkdir -p /mnt/root

echo "Mount root"
mount /dev/mapper/crypted /mnt/root

echo "Create boot directory"
mkdir /mnt/root/boot

echo "Mount boot"
mount /dev/disk/by-label/boot /mnt/root/boot

Hello,

Because of my utter stupidity, I have forgot to setup virtual machine as uefi system. I blame libvirt as much as myself since the interface is not very intuitive. Since ccording libvirt the guest is bios even though I have set up a gpt/uefi system, it naturally can not find the storage to boot. After recreating the machine with uefi boot, it worked flawlessly.

As you have mentioned, the configuration actually was correct.

Thank you.