This repository contains setup and management instructions for a Guix North American Build Farm.
Go to file
Collin J. Doering ad397cf89b
balg02: Add guix-north-america as a cuirass channel spec
* .guix/guix-na/config/balg02.scm: Extended %cuirass-specs, adding this channel itself as a
cuirass specification. This allows for change to this configuration
channel (guix-north-america) to be validated before deployment. Further, it could be extended
to build operating-system images for balg02 and any other machines, and even running tests on
them to ensure they will deploy and function as expected.
2024-07-22 21:00:46 -04:00
.guix/guix-na/config balg02: Add guix-north-america as a cuirass channel spec 2024-07-22 21:00:46 -04:00
.pubkeys cuirass.genenetwork.org.pub: Add guix-daemon signing key 2024-06-04 22:28:37 -04:00
.gitignore Initial setup (not yet bootstrapped or thoroughly tested) 2024-03-12 00:15:19 -04:00
.guix-authorizations Add rekahsoft-ed25519 key 2024-07-22 18:31:45 -04:00
.guix-channel Make this repository a authenticated Guix channel 2024-03-18 19:29:20 -04:00
channels.scm channels.scm: Update guix channel 2024-05-25 21:12:56 -04:00
news.txt news: Add entry about this authenticated channel 2024-03-18 19:31:40 -04:00
README.org README.org: Adjust how swapfile should be provisioned 2024-05-25 17:26:56 -04:00

Guix North America

This repository contains setup and management instructions for a Guix North American Build Farm.

Install Guix on debian to be used to bootstrap the Guix os installation

Optionally, the below steps can be completed within tmux or screen. Tmux was installed and used in this case using the following.

  sudo apt update
  sudo apt install tmux
  tmux

Following the Binary Installation section from the Guix manual to install guix.

  sudo apt install -y guix

This installs the Debian's packaged version of Guix, which likely is older then what's available upstream. As such, update our installation of Guix (following the Updating Guix documentation specific to foreign distros').

  sudo -i guix pull
  sudo systemctl restart guix-daemon.service

Define Guix operating-system for the machine

See: balg02.scm

Bootloader configuration

For this installation, debian and its bootloader Grub will be left in place. Because we want to retain Guix's interactions with Grub (eg. to allow for restoring from failed upgrades to an earlier generation), we will have debian's Grub chainload Guix's Grub. To do so, we will need to manually adjust Debians' Grub in order to add another menu entry, and set it as the default menu item.

Below is a snippet from debian's /etc/default/grub.

  GRUB_DEFAULT=0
  GRUB_TIMEOUT=5
  GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
  GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200n8"
  GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0,115200n8"
  GRUB_TERMINAL="console serial"
  GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=1 --word=8 --parity=no --stop=1"

From this we extract the necessary guix bootloader configuration options (for serial).

serial-unit
1
serial-speed
115200
terminal-inputs
console serial
terminal-outputs
console serial

Manual modifications to Debian's Grub

Modify grub config on debian to add an additional (and default) option to chainload Guix grub.

  • Add a menuitem for Guix in /etc/grub.d/40_custom, where <EFI-UUID> is replaced with the efi partition UUID.

      menuentry "Gnu Guix" {
          insmod part_gpt
          insmod search_fs_uuid
          insmod chain
          search --fs-uuid --no-floppy --set=root <EFI-UUID>
          chainloader ($root)/EFI/Guix/grubx64.efi
      }
  • Modify /etc/default/grub setting GRUB_DEFAULT="Gnu Guix"
  • Run grub-mkconfig -o /boot/grub/grub.cfg

Network configuration

Using the a snippet taken from /etc/network/interfaces on the existing debian installation (below), we can extract the necessary details to configure Guix's static-networking-service.

Interface
eno8303
Address
216.37.76.55/24
Gateway
216.37.76.1
DNS Name Servers
216.37.64.2 216.37.64.3
DNS Search
genenetwork.org
  # The primary network interface
  allow-hotplug eno8303
  iface eno8303 inet static
          address 216.37.76.55/24
          gateway 216.37.76.1
          # dns-* options are implemented by the resolvconf package, if installed
          dns-nameservers 216.37.64.2 216.37.64.3
          dns-search genenetwork.org

Disk Partitioning

For this installation we are using /dev/sdb (a 1.5T ssd which is faster then the alternative 3.6T ssd in the server).

First, we require a variety of tools to setup and partition the disk destined for Guix installation. These could be installed on debian, however an alternative approach would be to use Guix from debian as a package manager to temporarily provide the prerequisite tools. This can be done using the shell spawned from the following command.

  guix shell parted btrfs-progs dosfstools

Create disk partition table and layout

  parted /dev/sda mklabel gpt

Create partitions

A simple™️ partition layout is used for this installation, consisting of an EFI ESP partition, and the remaining disk partitions for use by btrfs, where btrfs subvolumes and a swapfile will be used.

  parted /dev/sda mkpart primary fat32 0% 512MiB
  parted /dev/sda mkpart primary 512MiB 100%

Create EFI partition

  parted /dev/sda set 1 esp on
  mkfs.fat -F32 /dev/sda1

Create btrfs 'pool' (file-system) and subvolumes

Create btrfs file-system
  mkfs.btrfs --label root /dev/sda2
Create btrfs subvolumes

First mount the btrfs top-level file-system.

  mount /dev/sda2 /mnt

Then create the root subvolume, and a subvolume for swapfiles.

  btrfs subvolume create /mnt/@
  btrfs subvolume create /mnt/@swap

Unmount the top-level btrfs file-system.

  umount /mnt

Mount the root subvolume.

  mount -o subvol=@,compress=zstd /dev/sda2 /mnt

Create nested subvolumes for /gnu/store and /home.

  mkdir -p /mnt/gnu

  btrfs subvolume create /mnt/gnu/store
  btrfs subvolume create /mnt/home
  btrfs subvolume create /mnt/var

Create swap

  mkdir /mnt/swap
  mount -o subvol=@swap /dev/sda2 /mnt/swap
  btrfs filesystem mkswapfile --size 32g --uuid clear /swap/swapfile

Prepare /mnt for Guix installation

Create /boot/efi directory for UEFI boot and mount the ESP partition there.

  mkdir -p /mnt/boot/efi
  mount /dev/sda1 /mnt/boot/efi

Both root and swap are already mounted and ready due to earlier steps.

Testing

To test the configuration in a vm before deployment, the following can be used.

  $(guix time-machine -C channels.scm -- system vm -e '(@ (guix-na config balg02) %system)') -m 2G -smp 2 -nic user,model=virtio-net-pci

Manual Testing of bootstrapping Guix from a Debian VM

To correctly test this deployment, a environment that mimics bal02g should be used. The closest to this is a VM with debian installed, with an additional virtual disk to bootstrap guix onto. This will enable validating bootloader changes required to chainboot Guix's Grub.

This testing could be automated, but was done manually as we do not expect to have to bootstrap a system like this often.

Setup Debian VM

  1. Using qemu, libvirt, virtualbox, etc.. create a VM that boots using UEFI firmware.

    1. Create an additional virtual disk that will be used to bootstrap Guix onto from Debian. This disk should be >20GiB.
    2. Ensure that there is a serial device attached to the VM.
  2. Install Debian 12 on the VM created during step 1 (this can be a minimal server installation, no desktop, etc..).

    1. It's worth noting that for some reason debian didn't setup a efi boot entry for some reason. Not sure why. To create one I used:

        efibootmgr --create --disk /dev/vda -p 1 -L "Debian" -l "\EFI\debian\grub64.efi"

      After which I would have adjusted the boot order with:

        efibootmgr -o X,Y,...

      However, in my case it was not needed as the boot order had debian first.

  3. Reboot VM; further configure Debian.

    1. Enable serial for debian grub

      Modify /etc/default/grub, adjusting GRUB_TERMINAL and GRUB_CMDLINE_LINUX_DEFAULT as follows.

        GRUB_TERMINAL="console serial"
        GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200n8"
    2. Enable getty over serial

        systemctl enable getty@ttyS0.service
        systemctl start getty@ttyS0.service

Test Bootstrapping Gnu Guix from Debian

With the Debian VM setup, we can now apply the documented bootstrapping steps.

  1. Disk Partitioning, but with disks adjusted to match the testing VM.
  2. Bootstrap Guix, ensure <EFI-UUID> matches the VM efi partition used for Guix.
  3. Manual modifications to Debian's Grub, again ensuring <EFI-UUID> matches the VM efi partition used for Guix.
  4. Reboot

Following rebooting the VM, its expected that:

  • Debian Grub boots first, has "Gnu Guix" as its default selected option, which boots Guixs' Grub.
  • Serial access works for:

    • Debian and Guix Grub/s
    • Debian and Guix linux console

As this testing is occurring in a VM, its worth noting things that are NOT expected to to be testable.

  • The network interfaces are not going to match what is on balg02, so its expected that the networking service will not be able to start.

Bootstrap Guix

Using Guix on debian, bootstrap the machine using the configuration in Define Guix operating-system for the machine.

Configure Guix Channels

First, fetch the most recent channel file from the target machine.

  curl -O https://git.rekahsoft.ca/rekahsoft/guix-north-america/raw/branch/master/channels.scm

Create and Bootstrap System

Create a bootstrap.scm file like below, but where <EFI-UUID> is replaced with the efi partition UUID.

  ((@ (guix-na config balg02) balg02) "<EFI-UUID>")

Use guix system init ... to instantiate the system, but using guix time-machine to use pinned dependencies.

  guix time-machine -C channels.scm -- system init bootstrap.scm /mnt

Post Boostrapping

After guix has been bootstrapped, its useful to do an initial guix pull using the same channels that were used during bootstrapping.

  guix pull -C /run/current-system/channels.scm

To ensure your shell refers to the correct guix after its been updated, run hash guix.