Guix Introduction Part 4: Try Guix
Contents
This is the fourth part of a brief introduction to the Guix functional package manager, and how it could be used to manage dependencies of projects, much like virtual environments for Python, but with much larger scope.
This time we look at how to install Guix, either in a physical or virtual machine, either as a complete GNU/Linux distribution, or just as a package manager on top of another Linux distribution. We also list some commonly used Guix commands
Get Guix
Refer to System Installation for details on getting Guix running (either the Guix system, or just the Guix package manager), we briefly summarize the main ways below. At the time of writing, the Guix version is 1.2.0.
Run Guix system in qemu virtual machine with pre-made image
Running Guix in a virtual machine is probably the easiest way to try it out. Qemu is a generic and open source emulator and virtualizer that can be used to run a pre-made image.
Refer to Running Guix in a Virtual Machine for more details. At the time of writing, the Guix version of the image is 1.2.0 for x86_64 architecture. We summarize the steps below:
-
install qemu following the instructions at https://www.qemu.org/download/
-
download the guix-system-vm-image-1.2.0.x86_64-linux.xz compressed image
-
decompress to get
guix-system-vm-image-1.2.0.x86_64-linux1xz -d guix-system-vm-image-1.2.0.x86_64-linux.xz -
invoke qemu on the image with
1 2 3 4 5qemu-system-x86_64 \ -nic user,model=virtio-net-pci \ -enable-kvm -m 1024 \ -device virtio-blk,drive=myhd \ -drive if=none,file=./guix-system-vm-image-1.2.0.x86_64-linux,id=myhd -
you can change arguments such as
-mas appropriate to set the amount of memory desired. Note that you may need to tweak the arguments of invoking qemu a bit, depending on your host system. E.g. in MacOS Mojave 10.14.6, I need to use the following:1 2 3 4 5 6qemu-system-x86_64 \ -nic user,model=virtio-net-pci \ -m 1024 \ -device virtio-blk,drive=myhd \ -drive if=none,file=./guix-system-vm-image-1.2.0.x86_64-linux,id=myhd \ -accel hvf -
wait for a while, then you will be in the default xfce desktop of a Guix system, i.e. a GNU/Linux distribution built around Guix. But note that by default, not many packages are installed, e.g. even a web browser is not installed by default. You may install them as needed, e.g. you may install
icecat(the GNU version of Firefox browser) by:1guix package -i icecat -
optional: since the command for invoking qemu can be very long, you may put it into a shell script to more conveniently invoke the VM
-
optional: you may use other front-ends (some are GUI) to more conveniently manage qemu VM, see https://wiki.archlinux.org/index.php/Libvirt#Client
Install the Guix system, the GNU/Linux distribution built on the Guix package manager
You can also install a Guix system in either a virtual or physical machine.
-
Get the Guix system install ISO image
Refer to USB Stick and DVD Installation
-
download the compressed 64-bit ISO from https://ftp.gnu.org/gnu/guix/guix-system-install-1.2.0.x86%5F64-linux.iso.xz
- you may instead get the compressed 32-bit ISO from https://ftp.gnu.org/gnu/guix/guix-system-install-1.2.0.i686-linux.iso.xz
-
optionally verify the authenticity of the image:
-
get the sig file for 64-bit ISO and verify (change
x86_64-linuxtoi686-linuxif you download the 32-bit ISO)1 2wget https://ftp.gnu.org/gnu/guix/guix-system-install-1.2.0.x86_64-linux.iso.xz.sig gpg --verify guix-system-install-1.2.0.x86_64-linux.iso.xz.sig -
if then above command fails, then import the gpg public key first and then re-run the above verification:
1 2wget https://sv.gnu.org/people/viewgpg.php?user_id=15145 \ -qO - | gpg --import -
-
-
decompress the image with
xz -dcommand to getguix-system-install-1.2.0.x86_64-linux.iso1xz -d guix-system-install-1.2.0.x86_64-linux.iso.xz
-
-
Install in a fresh qemu virtual machine
Refer to Installing Guix in a Virtual Machine
-
install qemu following the instructions at https://www.qemu.org/download/
-
create a fresh disk image in qcow2 format, where you can choose an appropriate size, e.g. 50G (the created image file will initially be much smaller, but will grow in size when it is filled up)
1qemu-img create -f qcow2 guix-system.img 50G -
boot the installation ISO image in the VM:
1 2 3 4qemu-system-x86_64 -m 1024 -smp 1 -enable-kvm \ -nic user,model=virtio-net-pci -boot menu=on,order=d \ -drive file=guix-system.img \ -drive media=cdrom,file=guix-system-install-1.2.0.system.iso -
note that you may need to tweak the arguments to
qemu-system-x86_64depending on your host system, e.g. you may need to replace-enable-kvmwith-accel hvfin MacOS. The-enable-kvmis optional anyway, but will significantly improve performance. -
note the few things mentioned in https://guix.gnu.org/manual/en/guix.html#Preparing-for-Installation
- The graphical installer is available on TTY1.
- You can obtain root shells on TTYs 3 to 6 by hitting ctrl-alt-f3, ctrl-alt-f4, etc.
- TTY2 shows the documentation and you can reach it with ctrl-alt-f2.
- Documentation is browsable using the Info reader commands (see Stand-alone GNU Info).
- The installation system runs the GPM mouse daemon, which allows you to select text with the left mouse button and to paste it with the middle button.
-
for simplicity, choose Guided Graphical Installation to finish the installation
-
after the installation, you can get into guix with the default xfce desktop whenever you invoke the VM
-
optional: since the command for invoking qemu can be very long, you may put it into a shell script to more conveniently invoke the VM
-
optional: you may use other front-ends (some are GUI) to more conveniently manage qemu VM, see https://wiki.archlinux.org/index.php/Libvirt#Client
-
-
Install in other virtual machine
You can also install Guix system using the ISO in other types of virtual machines such as:
- VirtualBox (free)
- Parallels (proprietary)
- VmWare (proprietary)
- and many others, see https://en.wikipedia.org/wiki/Comparison%5Fof%5Fplatform%5Fvirtualization%5Fsoftware
Similar to installing in qemu VM:
- note the few things mentioned in https://guix.gnu.org/manual/en/guix.html#Preparing-for-Installation
- The graphical installer is available on TTY1.
- You can obtain root shells on TTYs 3 to 6 by hitting ctrl-alt-f3, ctrl-alt-f4, etc.
- TTY2 shows the documentation and you can reach it with ctrl-alt-f2.
- Documentation is browsable using the Info reader commands (see Stand-alone GNU Info).
- The installation system runs the GPM mouse daemon, which allows you to select text with the left mouse button and to paste it with the middle button.
- for simplicity, choose Guided Graphical Installation to finish the installation
- after the installation, you can get into guix with the default xfce desktop whenever you invoke the VM
-
Install on physical machine
Installing Guix system on physical machine is similar to installing in virtual machine, except that you need to transfer the ISO image to either a USB stick or a DVD. It is recommended that you try to install in a virtual machine first to get familiar with the process, see the preceding subsection.
Refer to https://guix.gnu.org/manual/en/guix.html#USB-Stick-and-DVD-Installation
-
Copying to a USB Stick
- Insert a USB stick of 1 GiB or more into your machine
- if on a Linux machine,
-
determine its device name, e.g.
/dev/sdbor/dev/sdc. Note that it is VERY important to determine the correct device name, otherwise you may mistakenly wipe out another device. -
assuming that the USB stick is known as
/dev/sdX, copy the image with:1 2 3 4# access to /dev/sdX usually requires root privilege # also, /dev/sdX should NOT be mount sudo dd if=guix-system-install-1.2.0.x86_64-linux.iso of=/dev/sdX status=progress sudo sync
-
- if on a different OS or you prefer to use a GUI, you can try these programs:
-
alternative: Burning on a DVD
- Insert a blank DVD into your machine
- if on a Linux machine,
-
determine its device name. Note that it is VERY important to determine the correct device name, otherwise you may mistakenly wipe out another device.
-
assuming that the DVD drive is known as
/dev/srX, copy the image with:1 2# access to /dev/srX usually requires root privilege growisofs -dvd-compat -Z /dev/srX=guix-system-install-1.2.0.x86_64-linux.iso
-
- if on a different OS or you prefer to use a GUI, you can try these programs:
-
Installation
Similar to installing in qemu VM:
- note the few things mentioned in https://guix.gnu.org/manual/en/guix.html#Preparing-for-Installation
- The graphical installer is available on TTY1.
- You can obtain root shells on TTYs 3 to 6 by hitting ctrl-alt-f3, ctrl-alt-f4, etc.
- TTY2 shows the documentation and you can reach it with ctrl-alt-f2.
- Documentation is browsable using the Info reader commands (see Stand-alone GNU Info).
- The installation system runs the GPM mouse daemon, which allows you to select text with the left mouse button and to paste it with the middle button.
- for simplicity, choose Guided Graphical Installation to finish the installation
- after the installation, you can get into guix with the default xfce desktop
- note the few things mentioned in https://guix.gnu.org/manual/en/guix.html#Preparing-for-Installation
-
Install the guix package manager in existing GNU/Linux distribution (possibly in a VM)
Instead of installing a Guix system, you may choose to only install guix package manager on top of a GNU/Linux distribution (named “foreign distro in Guix documentation”, which does not need to be a Guix system, e.g. Debian, Ubuntu, Fedora, ArchLinux, etc).
Refer to Binary Installation
- the easiest way is to use the shell installer script:
-
download and execute the shell installer script as root
1 2 3 4cd /tmp wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh chmod +x guix-install.sh ./guix-install.sh- you may be asked to import gpg key, if so, just follow the instructions, then re-run the installer script
-
after that, check Application Setup for extra configuration you might need
-
- alternatively, you may choose to install the guix package from the package manager of your distribution, if there is one, e.g.:
Brief summary of commonly used commands in Guix
Here we list some common commands and usage of Guix, see Getting Started of the Guix manual for more details.
Basic usage of Guix
-
Help on Guix commands
-
Help on the main usage, to see the available commands
1guix --help -
Help on each command, e.g. the
guix packagecommand1guix package --help
-
-
Search packages
1 2guix search keywords-here # guix package -s keywords-here -
Show information of package(s)
1guix show package1 package2 -
Update channel(s)
To update the channels so that all the package definitions are updated, but the packages themselves are not automatically updated.
1guix pull -
Install package(s)
-
You can install one or more packages in one transaction
1guix install package1 package2 -
An alternative way
1 2guix package -i package1 package2 # guix package --install package1 package2
-
-
Remove package(s)
-
guix remove1guix remove package1 package2 -
An alternative way
1 2guix package -r package1 package2 # guix package --remove package1 package2
-
-
Upgrade package(s)
-
guix upgrade1guix upgrade package1 package2 -
An alternative way
1 2guix package -u package1 package2 # guix package --upgrade package1 package2
-
-
Install/Remove/Upgrade package(s) in one transaction
You can also install/remove/upgrade package(s) in a single transaction, simply list the package(s) with suitable options of
guix package,-ifor installing,-rfor removing,-ufor upgrading:1guix package -i package1 -r package2 -u package3 -
List installed packages
1 2guix package -I # guix package --list-installed -
Rollback to the previous generation
1guix package --roll-back -
List generations
1 2guix package -l # guix package --list-generations -
Switch generations
PATTERNcan be a generation number or+nto go forward n generations; or-nto go backward n generations.
1 2guix package -S PATTERN # guix package --switch-generation=PATTERN- E.g. to go forward one generation
1 2guix package -S +1 # guix package --switch-generation=+1- E.g. to go backward one generation, similar to
--roll-back, but if the specified generation does not exist, the current generation will not change
1 2guix package -S -1 # guix package --switch-generation=-1
Using manifest file to specify a list of package(s)
-
A manifest file is a Scheme file that evaluates to a list of guix packages (as Scheme object).
-
A convenient way is to use the
specifications->manifestfunction which takes a list of package names as strings and returns a list of the corresponding package objects. -
It can be used in a few contexts such as
guix packageto install packages, orguix environmentto spawn a shell with specified packages (see below), through the-mor--manifestoption. -
The advantage of a manifest file is that the list of packages can be easily version controlled (e.g. with
git). -
An example of manifest file (let’s say
pkgs.scm) is:
|
|
-
Install the list of package(s) in a manifest file
Note that the
-mcan be repeated multiple times with different manifest files, and the lists will be concatenated and all will be installed.1guix package -m pkgs.scmNote that a manifest file by itself only specifies the list of packages by name, but not the exact versions. In order to reproduce the exact versions of the list of packages, a manifest file can be combined with
guix time-machineas described below.
Using Guix profiles
Default guix actions (install/upgrade/remove) operate on the
default profile of each user (it is a symbolic link, default
location is at $HOME/.guix-profile), but each user can create
multiple profiles, activate the profiles as needed in similar ways
to Python virtual environments, and specify the profile to
operate on with each action through the -p (or --profile)
option (see Invoking guix package):
-
Create profile
The profile name is basically symbolic link(s) to the real contents of the profile, and we can put it basically anywhere, e.g.
~/my-ds-profile. So it is up to you to organize the profiles in a sensible way. It is also up to you to assign the roles of different profiles, e.g. one profile for each project; or different profiles for different domains of packages (e.g. one profile for data analysis, one profile for entertainment, one profile for graphics editing, etc).A profile will be created when you perform guix package actions specifying a profile, e.g. install
randr-xgboostin the profile~/my-ds-profile, which need not exist before this action:1guix package -i r r-xgboost -p ~/my-ds-profileNote that the created profile is not automatically activated, so you retain the maximum flexibility to activate as needed, or arrange to activate chosen profiles in each shell, see below.
-
Install or upgrade or remove packages in a profile
- Any usual
guix packageactions can be performed on a chosen profile by using the-p(or--profile) option, e.g. to install another packager-yamlto the profile~/my-ds-profilejust created:
1guix package -i r-yaml -p ~/my-ds-profile- E.g. install packages using a manifest file in a profile:
1guix package -m the_manifest_file -p path_to_profile - Any usual
-
List profiles
1guix package --list-profiles -
Activate a profile
Activating a profile amounts to modifying and exporting some environment variables (e.g.
PATH) in the current shell, which is conveniently done by sourcing theetc/profilefile under the profile. The recommended way to activate a profile, e.g.~/my-ds-profile, is to:1GUIX_PROFILE="~/my-ds-profile" ; . "$GUIX_PROFILE"/etc/profileNote that you can activate multiple profiles in the same shell as appropriate. But there is no effective way to deactivate a profile in the same shell, other than exiting the shell. The upside is that the global environment is not “polluted”, and you can start a new shell to activate a profile, then exit the shell afterwards.
Also, you can automatically activate any profile in each spawn shell by adding the activation to your shell initialization, e.g.
.bash_profileor.bashrc. -
Delete a profile
Somehow Guix does not provide a convenient command to delete a profile. Deleting a profile involves removing the profile symbolic link and its siblings that point to specific generations. E.g. to delete the
~/my-ds-profileprofile created above:1rm ~/my-profile ~/my-profile-*-link -
Export current or chosen profile as a manifest file
You can export the list of packages of a profile (if not specified, will use the default profile) to a manifest file. E.g. to export the default profile:
1guix package --export-manifest > pkgs1.scmE.g. to export the above
~/my-ds-profileprofile:1guix package --export-manifest -p ~/my-ds-profile > pkgs2.scm
Using Guix environment
The guix environment command allows you to spawn a new shell with
certain packages (or their dependencies) accessible (by modifying some
environment variables, e.g. PATH), without changing your other
profiles; and you can optionally either just spawn such a shell, or
execute a command inside this shell. Essentially a temporary profile
is created (for the set of packages wanted), so that you do not
“pollute” your other environment. The needed packages will be
automatically built if they are not yet in the cached store. So guix environment is a very convenient way to reproduce a set of packages
in a clean way. For example, this can be used to manage per-project
dependencies, as we will see in a future demo post of this series.
Note that when in a shell spawn by guix environment, the environment
variable GUIX_ENVIRONMENT will have the value of the path to the
temporary profile for the environment, and you can detect it to change
the shell prompt, e.g. add this to your .bashrc:
|
|
-
Spawn a shell with dependencies of some packages E.g. to get the dependencies of
emacsandvim:1 2# guix environment pkg1 pkg2 ... guix environment emacs vimCan also use
-m(possibly multiple times) to specify manifest file(s):1 2# guix environment pkg1 pkg2 ... -m pkgs1.scm -m pkgs2.scm ... guix environment kmahjongg -m pkgs.scmAlso check out the
--loadoption for loading a file for package. -
Spawn a shell with some packages themselves
Use the
--ad-hocoption to get the packages themselves. E.g. to get the gamekmahjonggitself:1 2# guix environment --ad-hoc pkg1 pkg2 ... guix environment --ad-hoc kmahjonggCan also use
-m(possibly multiple times) to specify manifest file(s):1 2# guix environment --ad-hoc pkg1 pkg2 ... -m pkgs1.scm -m pkgs2.scm ... guix environment --ad-hoc kmahjongg -m pkgs.scmAlso check out the
--loadoption for loading a file for package. -
Spawn a shell and directly execute some commands in it
To run commands in the spawn shell, put the command after
--at the end. E.g. to getRand start it1 2# guix environment --ad-hoc pkg1 ... -- pkg1 guix environment --ad-hoc r -- R -
Spawn a shell where original environment variables are unset
Use the
--pureoption, e.g. to get R1 2 3 4 5 6 7 8# show all environment variables currently defined env # guix environment --pure --ad-hoc pkg1 ... -- pkg1 guix environment --pure --ad-hoc r # then in the new shell, the PATH is reduced to only those for the # package, and even basic shell utilities are not in the PATH unless # they are added as one of the packages. echo $PATHYou may use the
--preserveto control the environment variables to keep, checkguix environment --helpfor more details. -
Spawn a shell to run things in an isolated environment
For further isolation, you can use the
--containeroption to run in a container where only the/gnu/storeand (by default) the current directory are mounted. You may checkguix environment --helpfor other relevant options, e.g.--expose,--network,--share,--no-cwd,--user.E.g. to run R in a container:
1 2# guix environment --ad-hoc pkg1 ... -- pkg1 guix environment --container --ad-hoc r -- RBut seems this feature is not very mature yet. When I tried the above command (on guix (GNU Guix) 510e24f973a918391d8122fd6ad515c0567bf23e), it gave this error:
1guix environment: error: mount: mount "/home/peter" on "/tmp/guix-directory.QDXQmx//home/peter": Invalid argument
Using Guix time-machine
The guix time-machine can be used to execute other Guix commands (e.g. guix package, or guix environment) at specified Guix revisions (exact commits of the channels, which can be produced by guix describe)
-
Install package in a particular revision
E.g. to install
emacsat the revision in the filechannels.scm1guix time-machine -C channels.scm -- package -i emacsThe
channels.scmcould be obtained withguix describe, e.g.1guix describe -f channels > channels.scmThe
channels.scmwill look something like (exact content of course depends on your channels) this:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20(list (channel (name 'nonguix) (url "https://gitlab.com/nonguix/nonguix") (commit "05fad6e54d497b7427ab7ea488210c7d43c3f676") (introduction (make-channel-introduction "897c1a470da759236cc11798f4e0a5f7d4d59fbc" (openpgp-fingerprint "2A39 3FFF 68F4 EF7A 3D29 12AF 6F51 20A0 22FB B2D5")))) (channel (name 'guix) (url "https://git.sjtu.edu.cn/sjtug/guix.git") (commit "8a452e156e37568fdd59df169acb4f2092aeb3ac") (introduction (make-channel-introduction "9edb3f66fd807b096b48283debdcddccfea34bad" (openpgp-fingerprint "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA")))))Note that it is possible to hand-edit the file to the commit desired.
-
Use time-machine with guix environment
Assuming there is a manifest file
pkgs.scmcontaining the needed packages, e.g.1 2 3 4 5 6 7 8 9 10(specifications->manifest '( ;; R "r" "r-yaml" "r-xgboost" "r-tidymodels" "r-tidyverse" "r-survminer" ))Then you can open a shell with these packages at the revisions specified in a
channels.scm1 2guix time-machine -C channels.scm -- environment --ad-hoc -m pkgs.scm # in this new shell where the packages are visible, you can run anything as neededAnd you can directly run things in the new shell, e.g. to run R:
|
|
Use Guix to create docker image
Guix can produce a docker image of a set of packages through the guix pack command, see Invoking guix pack and guix pack --help for more
description. In fact, guix pack can produce other formats, see guix pack --list-formats for the possible formats.
-
Produce a docker image of a list of packages
The set of packages can be specified as a list when calling
guix pack. E.g. to getRandxgboost:1 2# guix pack -f docker -S /bin=bin pkg1 pkg2 ... guix pack -f docker -S /bin=bin r r-xgboostThe
-Soption creates a symbolic link to file or directory under the profile (which is otherwise a path with long hash), provided for convenience. In the above example, a symbolic link will be created at/binpointing to thebindirectory in the profile (which will be something like/gnu/store/...-profile/bin), then the user can startRwith/bin/R.The path to the created tar.gz (something like
/gnu/store/...-docker-pack.tar.gzwith a long hash) file is output to stdout of theguix packcall, so we can get it like:1 2PACKLOC=$(guix pack -f docker -S /bin=bin r r-xgboost) # then can easily copy it elsewhereThen the file produced is a docker image that can be loaded into docker:
1 2 3 4 5# assume the file name is shortened to docker-pack.tar.gz docker load < docker-pack.tar.gz # docker will show the image tag after loading # the tag of the image is generated from the set of packages docker run -ti r-r-xgboost /bin/R -
Produce a docker image of packages from a manifest file
The set of packages can also be specified by a manifest file, similar to
guix package, e.g. if we have a manifest filepkgs.scm:1guix pack -f docker -S /bin=bin -m pkgs.scmNOTE: the documentation specifically mention that the set of packages can be specified by either a list of package names as arguments to
guix pack, or through a manifest file, but NOT BOTH. It is strange that there is such a limitation, hopefully it will be changed in the future. -
Also specify an entry point command
The
--entry-pointoption can specify a command to run when the docker image is started, e.g. to run guile:1 2# seems the command is relative to the profile path guix pack -f docker --entry-point=bin/guile guileThen the produced image (say renamed to
pack.tar.gz), can be loaded into docker and run as follows andguilewill start automatically:1 2 3 4docker load -i pack.tar.gz #docker run image-id # assume the image id is "guile" docker run guile -
Also use time-machine to pin package versions
The
guix time-machinecan be used, together with a manifest file, to easily produce a docker image with the set of desired packages pinned to versions at a certain time point.E.g. suppose we have the channel file
channels.scm, and manifest filepkgs.scm:1guix time-machine -C channels.scm -- pack -f docker -S /bin=bin -m pkgs.scmThe above have been tested with
guix (GNU Guix) ff1c7e40252337cb2c992c2d41e0ed4cefe56df0(installed on top of Debian 10 in a qemu VM), and the produced docker images have been tested on MacOS with Docker version 19.03.8, build afacb8b.
What’s next?
In this part we looked at various ways of installing Guix to try it
out, and showed some commonly used Guix commands. Next time we show a
little demo of managing per-project dependency with Guix, through the
guix time-machine and guix environment commands.
Author Peter Lo
LastMod 2021-05-12