Guix - hpaluch/hpaluch.github.io GitHub Wiki
Guix
Guix is special package manager and also OS based on that package manager. Unlike standard distributions every package has unique path based on its input, so it is naturally possible to have many versions of same packages.
To use packages one has to create profile - which is basically folder with set of links to active packages.
It has several advantages:
- coexistence of any number and any versions of packages - there is never path conflict - providing many (not all!) benefits of Containers Without Containers
- fully utilizing sharing files - shared libraries and even hard-linking duplicate files (because repository copy is always "read only"). Compare that with Ubuntu Snap that is unable to use shared libraries (Flatpack has partial support for "Runtimes").
- "hermetic" builds: all package dependencies must be declared to ensure that nothing is missing
- independent collections of packages ("profiles") - so you can have as many python versions as you want - not just single (pointing on ArchLinux and/or Fedora - these are seriously affected by this limitation)
- real transactional updates - just symlink target changes when update or rollback is finished
- easy rollback to previous state (just symlink changes)
- concurrent work with package
But there are also serious challenges:
- it is impossible to follow Linux filesystem standard that expects files in traditional locations
- packages that depend on specific absolute paths (runtime loaded shared libraries, or expecting data in hardcoded location) need tweaks and fixes
- this problem includes for example Icon path for Xfce launchers or for Audacious player (see below)
Homepage: https://guix.gnu.org/
It is similar to Nix (package manager) and NixOS (OS based on Nix packages and declarative configuration). However Guix uses Lisp dialect (Guile as Scheme interpreter)
To better understand main 2 components of Guix using Nix glossary:
- Nix - package manager -> Guix
- NixOS - operating system ->
Guix System(formerly known asGuixSD), please see also: https://en.wikipedia.org/wiki/GNU_Guix_System
To understand how Guix packages works I strongly suggest following Video: YT: Everyday Use of GNU Guix, Chris Marusich, SeaGL 2018 GNU archive unofficial 803 subscribers
Package Manager example
Scenario: openSUSE LEAP 16 removed Audio player audacious. We
can install Guix package manager and install audacious as Guix
package without conflict with existing SUSE packages.
Here is example how to install just Guix package manager:
Host OS: openSUSE LEAP 16.0
Following: https://guix.gnu.org/manual/1.5.0/en/html_node/Binary-Installation.html
# as normal user
cd
sudo zypper in curl wget
curl -fLO https://guix.gnu.org/guix-install.sh
chmod +x guix-install.sh
sudo ./guix-install.sh
# answer lot of questions
guix pull
# ooops: In procedure getaddrinfo: Servname not supported for ai_socktype
Cause: SUSE's version of /etc/services contains rubbish placeholder (instead
of list of services).
Fix:
sudo zypper in netcfg # install /usr/etc/services
# make proper link replacing userless rubbish text placeholder
sudo ln -fs /usr/etc/services /etc/services
And run again:
guix pull
It should finish without error.
Now logout and login and verify that your PATH includes ~/.guix-profile/bin:
$ echo "$PATH" | grep -o .guix-profile/bin
.guix-profile/bin
If yes you can now install and use Guix packages, for example:
# run as regular user that will run Audio player:
guix install audacious
# list installed packages:
guix package -I
audacious 4.4.2 out /gnu/store/fs0c5wnxz5958w8pn1girr4dph4d2ci0-audacious-4.4.2
Fix to see audacious application in Xfce:
# Application Lanucher
ln -s ~/.guix-profile/share/applications/audacious.desktop ~/.local/share/applications/
# Application Icon
mkdir -p ~/.local/share/icons/hicolor/scalable/apps
ln -s ~/.guix-profile/share/icons/hicolor/scalable/apps/audacious.svg ~/.local/share/icons/hicolor/scalable/apps/
WARNING! To get button icons for Audacious are restorted to:
guix install gnome-themes-extra
mkdir -p ~/.local/share/icons/hicolor/256x256/actions
cp /gnu/store/6c9pdg4hn4h26rcw69nxksy1b21qjj4m-gnome-themes-extra-3.28/share/icons/HighContrast/256x256/actions/* \
~/.local/share/icons/hicolor/256x256/actions
Now moment of truth - simply try running audacious if it will work (requires GUI - X11).
One can solve similar LEAP 16 defect - missing 32-bit Wine (because SUSE totally removed all 32-bit runtime). Fix with single command:
guix install wine
WARNING! If running winecfg command will throw error:
bash: /home/ansible/.guix-profile/bin/winecfg: cannot execute binary file: Exec format error
You need to install grub add-on that will enable kernel 32-bit ABI:
sudo zypper in grub2-compat-ia32
sudo reboot
# after reboot verify that following kernel boot parameter is active:
fgrep -o ia32_emulation=1 /proc/cmdline
ia32_emulation=1
Any Wine command (including winecfg) should now run fine...
Install notes
This applies only when installing Guix System (as operating system). Tested
guix-system-install-1.5.0.x86_64-linux.iso:
It hangs on NVidia GT218 (just black screen with blinking cursor - forever) - following PCI ID:
VGA compatible controller [0300]: NVIDIA Corporation GT218 [GeForce 210] [10de:0a65] (rev a2)
- I have to add
nouveauto blacklist in GRUB menu to proceed.
Updating system
guix pull # fetch all updates
guix package -u # update packages
sudo guix system reconfigure /etc/config.scm # update system
sudo reboot
guix gc # remove obsolete packages
# optional - get more info on your system:
guix system describe
guix system list-generations
Setting up and running VM
Used example from https://stumbles.id.au/getting-started-with-guix-deploy.html
In my example you should first generate ssh keypair as ~/.ssh/id_rsa_guix
;; Guix VM example. Modified version based on:
;; - Author: Ben Sturmfels
;; - Source: https://stumbles.id.au/getting-started-with-guix-deploy.html
;; Modification: enabled serial console
(use-modules (gnu))
(use-service-modules networking ssh)
(use-package-modules bootloaders ssh)
(operating-system
(host-name "vm")
(timezone "Etc/UTC")
(bootloader (bootloader-configuration
(bootloader grub-bootloader)
(target "/dev/vda")
(terminal-outputs '(console))))
(kernel-arguments (list "console=ttyS0,115200"))
(file-systems (cons (file-system
(mount-point "/")
(device "/dev/vda1")
(type "ext4"))
%base-file-systems))
(services
(append (list (service dhcp-client-service-type)
(service openssh-service-type
(openssh-configuration
(openssh openssh-sans-x)
(permit-root-login #t)
(authorized-keys
;; Authorise our SSH key.
`(("root" ,(local-file "../.ssh/id_rsa_guix.pub")))))))
%base-services)))
Above SCM file ( with top-level operating-system ) can be used with one of:
guix system image ...- will build just disk image - outputs its nameguix system vm ...- will build both image and shell script to run vm - outputs its name
To build Image and VM script (script to run VM) you can use:
guix system vm --save-provenance --image-type=qcow2 --root=run-vm.sh --no-graphic gs-deploy.scm
Note: --root parameter will create symbolic link to command output:
- for
guix system imageoutput is Disk image (so using--rooot=disk.qcow2is sensible) - for
guix system vmoutput is QEMU Wrapper script (so using--root=run-vm.shis reasonable)
You can run VM with symlink shell wrapper ./run-vm.sh,
but we will enable SSH port forwarding (Host port 2222, target vm port 22):
./run-vm.sh -nic user,hostfwd=tcp::2222-:22
Now you can login using any of:
- on console as
rootwithout password - or using command like
ssh -p 2222 -i ~/.ssh/id_rsa_guix [email protected]
Guix deploy example
Deploy expects SCM file in following format:
(list (machine (operating-system %system) ... ) )
So there is no top-level (operating-system ...) but rather (list ...) of machines
TODO: ...
Playing with REPL
Sooner or later you will be hit with weird error. Here is how you can use REPL - interactive guile shell to find basic info:
$ guile
;; must use absolute pathname to *.scm
scheme@(guile-user)> ,load "/home/ansible/os-deploy/gs-deploy.scm"
/home/ansible/os-deploy/gs-deploy.scm:12:26: warning: the 'target' field is deprecated, please use 'targets' instead
scheme@(guile-user)> ,pretty-print %base-file-systems
$2 = (#<<file-system> device: "none" mount-point: "/dev/pts" type: "devpts" flags: () options: "gid=996,mode=620" mount?: #t mount-may-fail?: #f ne>
#<<file-system> device: "none" mount-point: "/sys/kernel/debug" type: "debugfs" flags: () options: #f mount?: #t mount-may-fail?: #f needed-f>
#<<file-system> device: "tmpfs" mount-point: "/dev/shm" type: "tmpfs" flags: (no-suid no-dev) options: "size=50%" mount?: #t mount-may-fail?:>
#<<file-system> device: "efivarfs" mount-point: "/sys/firmware/efi/efivars" type: "efivarfs" flags: () options: #f mount?: #t mount-may-fail?>
#<<file-system> device: "/gnu/store" mount-point: "/gnu/store" type: "none" flags: (read-only bind-mount no-atime) options: #f mount?: #t mou)
Ctrl-D to exit guile
Note: it is common habit to prefix global variables with (%) - so
%base-file-systems should be global variable that we attempt to print.
To study:
Guile scheme reference
It is hard to found, finally got something:
- https://www.gnu.org/software/mit-scheme/
- standard libraries: https://www.gnu.org/software/guile/manual/html_node/SRFI-Support.html