Guix on LVM - hpaluch/hpaluch.github.io GitHub Wiki

How to install Guix System on LVM

Standard Guix system installer supports only installation to partition not to Logical Volume. We have to use so called Manual Installation.

Note: there is also NixOS on LVM page doing same install on NixOS for comparison.

Tested setup:

  • LibVirt VM with 40GB Virtio-SCSI disk (I use SCSI instead of BLK to easily reduce later install to bare-metal computer - having same /dev/sdX device instead of /dev/vdX)
  • EFI boot
  • planned simple CLI target

I used following resources to get it working:

Used installation ISO: guix-system-install-1.5.0.x86_64-linux.iso

  • in virt-manager I selected Debian 13 as OS (there is no Guix)
  • memory: 4096 MB
  • CPUs: 2
  • disk size: 40GB or more
  • name: guix-lvm-efi, check Customize ...
  • add Hardware -> Controller -> SCSI -> VirtIO SCSI
  • Overview: change Firmware from BIOS to UEFI
  • on VirtIO Disk 1 change Disk Bus: to SCSI
  • click on Begin Installation
  • it WILL fail because there is no signed boot loader on ISO

To remedy that failure:

  • press any key to enter Boot Manager Menu
  • ENTER on Device Manager -> Secure Boot Configuration -> Attempt Secure Boot -> [X]
  • press SPACE to deselect it
  • press ESC several time to return to main menu
  • select and press on Reset
  • it WILL again fail - because virt-manager thought Reset occurred after OS installation so it removed installation ISO
  • on Info tab select SATA CDROM 1 and attach again ISO.
  • go to Boot Options and check on SATA CDROM 1
  • on menu click on Force Reset - now system should finally boot

Once text installer boot you should:

  • Choose the language ... - press ENTER on English
  • user arrows to select United States and press ENTER
  • use arrows to select Install using the shell based process and press ENTER

There will appear 2 important consoles:

  • on Ctrl-Alt-F3 Guix installation manual
  • on Ctrl-Alt-F2 root console

Recommended:

Now from your client machine connect to target using ssh root@IP_OF_TARGET

Now we will use fdisk to create desired layout:

Device       Start        End   Sectors   Size Type
/dev/sda1       34       2047      2014  1007K BIOS boot    # for legacy BIOS boot (not used yet)
/dev/sda2     2048    4196351   4194304     2G EFI System   # for UEFI boot
/dev/sda3  4196352 1000214527 996018176 474.9G Linux LVM    # LVM

To do that, run following commands:

fdisk /dev/sda

g # create GPT partition table
# now create BIOS boot:
n # new
Part No: ENTER for 1
First sector: ENTER (in this case only 2048)
Last sector: +2m
t # toggle id
4 # BIOS boot

n #new partition
Part No: ENTER for 2
First sector: ENTER
Last sector: +2g
t # toggle id
Part No: 2
1 # EFI System

n # new partition
Part No: ENTER for 3
First sector: ENTER
Last sector: ENTER
t # toggle id
Part No: 3
lvm # Linux LVM

# final layout:
Device       Start      End  Sectors Size Type
/dev/sda1     2048     6143     4096   2M BIOS boot
/dev/sda2     6144  4200447  4194304   2G EFI System
/dev/sda3  4200448 41940991 37740544  18G Linux LVM # oops, should be 40GB or more!

# verify and write and quit
v
w # write and quit

You can dump partition table with fdisk -l /dev/sda

Now format EFI:

# NOTE: label "EFI-GUIX" will be later referenced from SCM file!
mkfs.vfat -F 32 -n EFI-GUIX /dev/sda2

Now prepare LVM (installation target):

pvcreate /dev/sda3
# Important: Volume Group name: "vg"
vgcreate guixvg /dev/sda3
# NOTE: you can also use "-L 123G" for size in GB
lvcreate -n guix-root -l 95%FREE guixvg

And here is dump of important LVM info:

root@gnu ~# pvs
  PV         VG     Fmt  Attr PSize  PFree  
  /dev/sda3  guixvg lvm2 a--  17.99g 924.00m
root@gnu ~# vgs
  VG     #PV #LV #SN Attr   VSize  VFree  
  guixvg   1   1   0 wz--n- 17.99g 924.00m # oops should be 40GB or more!!!
root@gnu ~# lvs
  LV        VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  guix-root guixvg -wi-a----- <17.09g                                                    

Now create target filesystem:

mkfs.ext4 -L GUIX-CLI /dev/mapper/guixvg-guix--root

Now we have to mount filesystems (and setup important folders):

mount /dev/mapper/guixvg-guix--root /mnt
mkdir -p /mnt/etc /mnt/boot/efi
mount /dev/sda2 /mnt/boot/efi
df -h /mnt /mnt/boot/efi

  Filesystem                     Size  Used Avail Use% Mounted on
  /dev/mapper/guixvg-guix--root   17G  2.1M   16G   1% /mnt
  /dev/sda2                      2.0G  4.0K  2.0G   1% /mnt/boot/efi

Finally save this snippet to config.scm and copy it to target with scp config.scm root@IP_OF_TARGET:/mnt/etc/config.scm

;; -*- mode: scheme; -*-
;; This is an operating system configuration template
;; for a "bare bones" setup, with no X11 display server.
;; based on:
;; - install ISO /etc/configuration/bare-bones.scm
;; - Guix source: gnu/system/examples/vm-image-efi.tmpl
;; - Kenny Ballou source: https://git.sr.ht/~kennyballou/dotfiles.git/tree/trunk/item/systems/axo.scm

(use-modules (gnu) (gnu packages tmux) (gnu packages vim) (gnu packages mc) )
(use-service-modules networking ssh)
(use-package-modules screen ssh)

(operating-system
  (host-name "guix-cli")
  (timezone "Europe/Berlin")
  (locale "en_US.utf8")

  ;; boot in EFI mode
  (bootloader (bootloader-configuration
	      (bootloader grub-efi-bootloader)
	      (targets '("/boot/efi")) ))

  (mapped-devices
    (list (mapped-device
               ;; source is Volume Group only
               (source "guixvg")
               ;; target is name under /dev/mapper
               (target "guixvg-guix--root")
               (type lvm-device-mapping) )))

  (file-systems (cons* (file-system
                         (mount-point "/")
			 ;; path below must exist at installation time!
                         (device "/dev/mapper/guixvg-guix--root")
                         (type "ext4"))
                       (file-system
                         (mount-point "/boot/efi")
			  ;; label must match that one specified with: mkfs.vfat -n EFI-GUIX ...
                         (device (file-system-label "EFI-GUIX"))
                         (type "vfat"))
                       %base-file-systems))

  ;; This is where user accounts are specified.  The "root"
  ;; account is implicit, and is initially created with the
  ;; empty password.
  (users (cons (user-account
                (name "alice")
                (comment "Bob's sister")
                (group "users")

                ;; Adding the account to the "wheel" group
                ;; makes it a sudoer.  Adding it to "audio"
                ;; and "video" allows the user to play sound
                ;; and access the webcam.
                (supplementary-groups '("wheel"
                                        "audio" "video")))
               %base-user-accounts))

  ;; Globally-installed packages.
  (packages (append (list screen tmux vim mc) %base-packages))

  ;; Add services to the baseline: a DHCP client and an SSH
  ;; server.  You may wish to add an NTP service here.
  (services (append (list (service dhcpcd-service-type)
                          (service openssh-service-type
                                   (openssh-configuration
                                     (openssh openssh-sans-x)
                                     (port-number 22))))
                    %base-services)))

Finally run these commands to install Guix on target:

cd /
herd start cow-store /mnt
guix system init /mnt/etc/config.scm /mnt

It should finish without error...

Next unmount target with:

cd /
umount -lR /mnt

And issue reboot command to reboot to installed system.

On installed system you can:

  • login locally as root without password
  • set password to alice user with passwd alice and then login as alice remotely via SSH To halt system simply run halt as root