dotfiles/Guix.org

9.2 KiB

Guix

GNU Guix is (1) a transactional package manager and (2) a GNU/Linux distribution.

My personal selling points are declarative package configuration and transactional upgrades.

References:

Profiles

A profile is way to group Guix packages. Amongst many advantages, profiles can be defined by manifests, which in turn can be stored in VCS.

References:

Activate profiles

A script to activate guix profiles. Usage:

activate-profiles [profile1] [profile2] ...

Source: David Wilson's config

GREEN='\033[1;32m'
RED='\033[1;30m'
NC='\033[0m'
GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles

profiles=$*
if [[ $# -eq 0 ]]; then
    profiles="$HOME/.config/guix/manifests/*.scm";
fi

for profile in $profiles; do
  # Remove the path and file extension, if any
  profileName=$(basename $profile)
  profileName="${profileName%.*}"
  profilePath="$GUIX_EXTRA_PROFILES/$profileName"
  manifestPath=$HOME/.config/guix/manifests/$profileName.scm

  if [ -f $manifestPath ]; then
    echo
    echo -e "${GREEN}Activating profile:" $manifestPath "${NC}"
    echo

    mkdir -p $profilePath
    guix package --manifest=$manifestPath --profile="$profilePath/$profileName"

    # Source the new profile
    GUIX_PROFILE="$profilePath/$profileName"
    if [ -f $GUIX_PROFILE/etc/profile ]; then
        . "$GUIX_PROFILE"/etc/profile
    else
        echo -e "${RED}Couldn't find profile:" $GUIX_PROFILE/etc/profile "${NC}"
    fi
  else
    echo "No profile found at path" $profilePath
  fi
done

Update profiles

A script to update Guix profiles. Usage:

update-profiles [profile1] [profile2] ...

Source: once again, David Wilson's config.

GREEN='\033[1;32m'
NC='\033[0m'
GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles

profiles=$*
if [[ $# -eq 0 ]]; then
    profiles="$GUIX_EXTRA_PROFILES/*";
fi

for profile in $profiles; do
  profileName=$(basename $profile)
  profilePath=$GUIX_EXTRA_PROFILES/$profileName

  echo
  echo -e "${GREEN}Updating profile:" $profilePath "${NC}"
  echo

  guix package --profile="$profilePath/$profileName" --manifest="$HOME/.config/guix/manifests/$profileName.scm"
done

Channels

Specifying additional channels.

References:

(cons*
 (channel
  (name 'channel-q)
  (url "file:///home/pavel/Code/channel-q"))
 (channel
  (name 'nonguix)
  (url "https://gitlab.com/nonguix/nonguix"))
 %default-channels)

Systems

Configuring systems with Guix.

Again, this part is inspired by David Wilson's config.

Base configuration

The base configuration is shared between all the machines.

To use a configuration derived from base-operating-system, invoke guix system as follows:

sudo -E guix system -L ~/.config/guix/systems reconfigure ~/.config/guix/systems/[system].scm
(define-module (base-system)
  #:use-module (gnu)
  #:use-module (gnu system nss)
  #:use-module (gnu packages version-control)
  #:use-module (gnu packages vim)
  #:use-module (gnu packages wm)
  #:use-module (gnu packages openbox)
  #:use-module (nongnu packages linux)
  #:use-module (nongnu system linux-initrd))

(use-service-modules desktop networking ssh xorg)
(use-package-modules ssh)

Define the base-operating-system:

(define-public base-operating-system
  (operating-system
   ;; Use the full Linux kernel
   (kernel linux)
   (initrd microcode-initrd)
   (firmware (list (linux-firmware)))
   (locale "en_US.utf8")
   (timezone "Europe/Moscow")

   ;; US/RU keyboard layout
   (keyboard-layout (keyboard-layout "us,ru" #:options '("grp:alt_shift_toggle")))

   ;; User accounts
   (users (cons* (user-account
                  (name "pavel")
                  (comment "Pavel")
                  (group "users")
                  (home-directory "/home/pavel")
                  (supplementary-groups
                   '("wheel"  ;; sudo
                     "netdev" ;; network devices
                     "audio"
                     "video"
                     "input"
                     "tty"
                     "docker"
                     "lp")))
                 %base-user-accounts))

   ;; Base packages
   (packages
    (append
     (list nss-certs
	       git
           i3-gaps
           openbox
	       vim)
     %base-packages))

   ;; Services
   (services
    (append
     (list (service openssh-service-type)
           (set-xorg-configuration
            (xorg-configuration
             (keyboard-layout keyboard-layout))))
     %desktop-services))))

blue

A VM on which I test Guix. Will probably be deleted sooner or later.

(define-module (blue)
  #:use-module (base-system)
  #:use-module (gnu))

(operating-system
 (inherit base-operating-system)

 (host-name "blue")

 (bootloader
  (bootloader-configuration
   (bootloader grub-bootloader)
   (target "/dev/sda")
   (keyboard-layout keyboard-layout)))

 (swap-devices
  (list (uuid "d9ca4f8b-4bb1-420e-9371-3558731bada1")))

 (file-systems
  (cons* (file-system
          (mount-point "/")
          (device
           (uuid "179fbd75-3c7f-4de2-8c4f-4c30939b8a3f"
                 'ext4))
          (type "ext4"))
         %base-file-systems)))

Notes on installing software

Category Guix dependency Description
dev patchelf A program to modify existsing ELF executables
dev glibc A lot of stuff, including ELF interpeter and ldd

wakatime-cli

Note Description
TODO Package this for Guix

Before I figure out how to package this for Guix:

  • Clone the repo
  • Run go build
  • Copy the binary to the ~/bin folder

ActivityWatch

Note Description
TODO Package this for Guix

The official binaries work just fine after some patching, except for the aw-qt binary.

Properly building from source is more awkward (PyInstaller? Are you serious? xD), as there are multiple packages with lots of dependencies.

The patching is as follows:

  • Get ELF interpeter patch from guix build glibc, after which patch ELF interpeter path for the required binaries, e.g.:
patchelf --set-interpreter /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 aw-qt
patchelf --set-interpreter /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 aw-server/aw-server
patchelf --set-interpreter /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 aw-server-rust/aw-server-rust
patchelf --set-interpreter /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 aw-watcher-afk/aw-watcher-afk
patchelf --set-interpreter /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 aw-watcher-window/aw-watcher-window

Add libz to RPATH

Category Guix dependency
misc zlib
patchelf --set-rpath /gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11/lib/ aw-qt
patchelf --set-rpath /gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11/lib/ aw-server/aw-server
patchelf --set-rpath /gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11/lib/ aw-server-rust/aw-server-rust
patchelf --set-rpath /gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11/lib/ aw-watcher-afk/aw-watcher-afk
patchelf --set-rpath /gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11/lib/ aw-watcher-window/aw-watcher-window

As aw-qt doesn't work properly, and the only thing it does is makes a tray icon anyhow, here is a script to launch the required components:

~/Programs/activitywatch/aw-server/aw-server &
~/Programs/activitywatch/aw-watcher-afk/aw-watcher-afk &
~/Programs/activitywatch/aw-watcher-window/aw-watcher-window &