Guix & Nix

OSes: functional approach

Andrew Tropin

April 25, 2019

whereis

github.com/abcdw/talks

whoami && who

Plan

  • Current state of system distributions
  • State of art
  • Guix perks
  • How to choose?
  • How to install?

Current state

What SD should do?

  • Software (de)installation, execution
  • Service configuration and management

How we manage services?

Mutating global state using config files!

sudo vim /etc/.../postgresql.conf
sudo service postgresql restart

Which can conflict with maintainer version.

How we install software?

Mutating global state using package managers!

apt-get install python python-pip
pip install wakatime
snap install vscode
curl https://nixos.org/nix/install | sh
./configure && make && make install

Which can’t be undone.

Who we can trust?

???

How we deal with

dependencies and conflicts?

  • Try to make things consistent
  • Static linking
  • Custom prefix
  • Give up
  • Isolate environment

Note: (virtualenv, node_modules, docker)

How to get reproducible environment?

  • ???
  • virtualization?
  • shared env?

State of the art

History

of functional package and system management

How package management works

  • No globals state (/bin, /usr/lib)
  • Pure: build runtime isolated
  • Reproducible: binary cache, deduplication, trust

Persistent store

hash(input) + package + version

ldd $(which zsh)
ls /gnu/store
echo $PATH | sed 's/:/\n/g'
readlink ~/.guix-profile
# ...

Solves dependencies problem.

User package management

Binary or source?

guix package -s
guix package -i
guix package -u

Environment

guix environment --ad-hoc gcc@5.5.0 hello tree
# --pure
# --container
# echo /gnu/store/*

Solves reproducible environment problem.

Pack

guix pack
guix pack -f docker
docker load -i

Challenge

guix challenge bash

Partially solves trust problem.

Garbage collection

Remove only unused packages

guix gc

Package definition

(define-public hello
  (package
    (name "hello")
    (version "2.10")
    (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/hello/hello-" version
                                  ".tar.gz"))
              (sha256
               (base32
                "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
    (build-system gnu-build-system)
    (synopsis "Hello, GNU world: An example GNU package")
    (description
     "GNU Hello prints the message \"Hello, world!\" and then exits.  It
serves as an example of standard GNU coding practices.  As such, it supports
command-line arguments, multiple languages, and so on.")
    (home-page "https://www.gnu.org/software/hello/")
    (license gpl3+)))

Hackable package definition

https://github.com/meiyopeng/guix-packages/blob/master/meiyo/packages/linux-nonfree.scm

Import

guix import gem rails

Inside system distribution

Init?

cat $(which shepherd)

System configuration

~/configs/guix/qemu.scm

guix system reconfigure ./config.scm
guix system search ssh

Services

(services (cons* (dhcp-client-service)
                 (service openssh-service-type
                          (openssh-configuration
                            (port-number 2222)))
                 %base-services)))

Remove state from /etc

VM

guix system vm ./config.scm

Explore

guix build -S guix

Problems

How to install?

Partition your drive

parted # && cryptsetup luksFormat ...

Create system configuration

(operating-system
 (host-name "functional-machine")
 (timezone "Europe/Moscow")
 (locale "ru_RU.utf8")
 (bootloader (grub-configuration (device "/dev/sda")))
 (file-systems (cons (file-system
                      (device "my-root")
                      (title ’label)
                      (mount-point "/")
                      (type "ext4"))
                     %base-file-systems))
 (users (cons (user-account
               (name "bob")
               (group "users")
               (home-directory "/home/bob"))
              %base-user-accounts))
 (services (cons* (dhcp-client-service)
                  (service openssh-service-type)
                  %base-services)))

Init the system

guix system init ./config.scm

How to configure?

Define more services

(service openssh-service-type
         (openssh-configuration
          (x11-forwarding? #t)
          (permit-root-login ’without-password)))

Update service list

(operating-system
 ;; ...
 (services (remove (lambda (service)
                           (eq? ntp-service-type
                                (service-kind service)))
                   %desktop-services)))

Wrap service into container

(with-imported-modules
 ’((gnu build linux-container))
  (shepherd-service
   (provision ’(bitlbee))
   (requirement ’(loopback))
   (start #~(make-forkexec-constructor/container
         (list #$(file-append bitlbee "/sbin/bitlbee")
           ...)))
   (stop #~(make-kill-destructor))))

Recap

What is guix?

  • Package definitions + bootstrap binaries
  • Package manager + library
  • GNU/Linux distro with declarative config

on top of minimalistic language

Multiple versions

No DLL-hell

Complete dependencies

No work-for-me packages from dirty envs

Multi-user support

No trojans, but user can install packages

Atomic upgrades and rollbacks

Switch symlinks is atomic

Transparent source/binary deployment

--no-substitute

Pure and Declarative

config -> system

Hackable, introspectable and uniform

Learn the scheme - rule the system

How to pick right1?

Nix vs Guix

  • Package manager vs SD
  • Mac vs Linux
  • Haskell vs Lisp
  • Diversity vs Liberty

Help

contact me

github.com/abcdw/talks