Giving Guix a Go
From the content of previous posts, it’s no secret that I enjoy automating infrastructure to some degree. I have learned a few tools there, notably Terraform, because I value being able to recreate a instance from scratch with a simple setup and just a few commands. However, that does not exist for my personal machines. I’ve been exposed to NixOS via some introductory blog posts and understand the value therein, but have yet to bother with it. When I ran across Guix, my enjoyment lisp (yes, I know Guile is a Scheme) gave me the impetus to try.
Getting a Bootable USB
As a GNU project, Guix only uses free software by default. While it’d be great to use fully free software, I am not particularly a zealot, and I don’t want to replace my laptop. It has a certain network card
# lspci -k
...
02:00.0 Network controller: Intel Corporation Centrino Advance-N 6230 [Rainbow Peak] (rev 34)
Subsystem: Intel Corporation Centrino Advance-N 6230
Kernel driver in use: iwlwifi
Kernel modules: iwlwifi
which means I need iwlwifi to connect to the internet. The reason this is a pain for Guix is that I cannot use their installer1. As far as I know, my next best option is to create my own machine image with the driver built in. That’s an eventual goal anyway, and Guix is very much designed to facilitate this. Luckily, a few examples for using non-free drivers, can be found around the web, so I have some basic guidance.
(operating-system
(host-name "phone-microwave")
(timezone "America/Chicago")
(locale "en_US.utf8")
(kernel linux-nonfree)
(firmware (cons*
iwlwifi-firmware-nonfree
%base-firmware))
; ...
)
You can look at the definitions of linux-nonfree
and iwlwifi-firmware-nonfree
in my source; I merely want to highlight how the operating-system
is configured.
I knew I’d need this from past experience installing Linux on this machine, but I’m not terribly sure how well this would work on any other. If I had a Broadcom chip, how would I figure which driver to use? Remember all this has to be done in advance, because I create the machine image for target computer from a different one. And it can take quite awhile, so iteration is costly. Anyway, it’s nothing I need to worry about this time around.
An annoying part of installing an OS like Linux (okay, maybe just minimal ones like Arch) is having to configure your system
(operating-system
; ...
(packages (cons* curl git man-db man-pages neovim nss-certs sudo %base-packages)))
If I have these, I can work in a mostly familiar manner when trying to troubleshoot on my way to a full setup. I’ll probably end up putting my window manager of choice here as well, but frankly I don’t feel a graphical environment is necessary for exploring what this distro is all about. In fact, none of my machines boot straight into a graphical environment. It’s hardly any extra effort to just type sway
at the tty, and there are less things that can go wrong on startup.
Building
Alrighty, I need to set up my machine to build the image.
$ curl https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh -sO
$ chmod a+x guix-install.sh
$ sudo ./guix-install.sh
# ...
[ PASS ] Guix has successfully been installed!
[ INFO ] Run 'info guix' to read the manual.
$ time guix system build config.scm
# ...
real 118m40.393s
user 0m20.975s
sys 0m1.623s
Wow that took awhile; I just compiled the Linux kernel! ps aux
tells me guix
even had make
using -j 8
. This is certainly a lot more effort than downloading an iso like I’m used to with Arch. I’d imagine there’s a way to configure the kernel compilation process to only compile what I need for this machine. SO. MANY. DRIVERS. Something I hope to figure out down the road.
$ guix system disk-image config.scm
/gnu/store/fb4xwckszly2j04wjh5y910s4l31v686-disk-image
# time dd if=/gnu/store/fb4xwckszly2j04wjh5y910s4l31v686-disk-image of=/dev/sdb status=progress oflag=sync
3933381120 bytes (3.9 GB, 3.7 GiB) copied, 14838 s, 265 kB/s
7682451+0 records in
7682451+0 records out
3933414912 bytes (3.9 GB, 3.7 GiB) copied, 14838.8 s, 265 kB/s
real 247m18.787s
user 1m6.996s
sys 11m44.969s
I will guard this USB stick with my life. After all, while you were out partying, I studied the command line.
Installation
After configuring the BIOS to boot from USB, I finally land in a tty.
login for phone-microwave: root
# which curl
/run/current-system/profile/bin/curl
There’s no root password initially, and it’s pretty neat to see the packages I want are already installed! But this is still just on the USB; I need to move it to my hard drive. And this is usually the part where you need working internet.
# wpa_passphrase "ssid" "password" > /etc/home-wifi.conf
# wpa_supplicant -i wlp2s0 -c /etc/home-wifi.conf -B
Successfully initialized wpa_supplicant
rfkill: WLAN soft blocked
Odd, I’ve never seen that before. A quick search clears it right up though:
# iwconfig wlp2s0 txpower auto
# wpa_supplicant -i wlp2s0 -c /etc/home-wifi.conf -B
Successfully initialized wpa_supplicant
# dhclient wlp2s0
...
Because this machine was already running Arch, the disk is provisioned in a sufficient way. I have one for the entire filesystem and another for swap.
# mkfs.ext4 /dev/sda1
# mount /dev/sda1 /mnt
# mkdir /mnt/etc
# cp /etc/configuration/desktop.scm /mnt/etc/config.scm
# time guix system init /mnt/etc/config.scm /mnt
It didn’t take too long for the program to run out of memory. I foolishly overlooked the warning about running:
# herd start cow-store /mnt
before the system init
. Well, truth be told I tried to run it, but the cow-store
service wasn’t in my image, so I ignored it and moved on.
Ugh back to square one. I build another machine image, this time forking the installer configuration rather than the normal OS.
(operating-system
(inherit installation-os)
; ...
)
After repeating the previous steps (and a lot more waiting),
gnu login: root (automatic login)
Welcome to the installation of GNU Guix
Using this shell, you can carry out the installation process "manually."
Access documentation at any time by pressing Alt-F2
root@gnu ~#
This is a little different, naturally because it’s an installation image. This time I can run the cow-store
service and proceed with the same steps as above. After a few more hours, I finally have a working Guix system.
Configuration
Thanks to operating-system
, I was most of the way there - I just want to try out a graphical environment. Open up /etc/config.scm
and add a few entries:
(packages (cons* font-adobe-source-code-pro
pulseaudio
qutebrowser
sway
swaylock
termite
upower
wl-clipboard
%base-packages))
# guix system reconfigure /etc/config.scm
Now I have a working desktop environment with sway
! After cloning my dotfiles, I’m off to the races.
Thoughts so far
The package manager is SLOW. At this point, I believe it is recompiling a lot of programs from source, which one one hand is evidence that the package definitions are nice and repeatable, but it’s also a bit annoying to wait. And the output isn’t terribly friendly. I bet it’s providing the information I want, but I find the wording obtuse.
A few things such as my lock screen don’t work yet. I have a hunch it’s the difference between init systems - Guix uses Shepherd instead of systemd
. Still got some work to do…
Special thanks to: