John Kehayias — January 6, 2023
GNU Guix is diversified from most diversified GNU/Linux distributions and in all likelihood nowhere is that
more obvious than the group of the filesystem: Guix does now now not conform to the
Filesystem Hierarchy Usual (FHS). In
functional phrases, this means there is not the type of thing as a world /lib
containing libraries, /bin
containing binaries,¹ and lots of others. Here’s extraordinarily mighty on the core of how Guix works and some
of the convenient components, be pleased per-user set up of capabilities (diversified variations,
as an illustration) and a declarative machine configuration where the machine is droop from a
configuration file.
Alternatively, this also ends in a disagreement in what number of pieces of machine quiz their world
to mark be pleased, counting on finding a library in /lib
or an exterior machine in /bin
. When
these are laborious coded and now now not overcome with applicable build choices, we patch code to
discuss to absolute paths in the retailer, be pleased
/gnu/retailer/hrgqa7m498wfavq4awai3xz86ifkjxdr-grep-3.6/bin/grep
, to withhold the entire lot
consistently contained throughout the retailer.
All of it works nice and is because of the the laborious work of all people that has contributed to
Guix. But what if we want a more FHS-be pleased atmosphere for rising, attempting out, or running
a allotment of machine?
To that quit, we procure now now not too lengthy in the past
added (on hand in Guix 1.4.0)
a brand fresh possibility for guix shell
(previously known as guix atmosphere
):
--emulate-fhs
(or -F
). This possibility is frail alongside with the
--container
(or -C
)
possibility which creates an remoted, you guessed it, container. The fresh --emulate-fhs
possibility will residing up an environment in the container that follows FHS expectations, so as that
libraries are considered in /lib
in the container, as an illustration.
Here’s a extraordinarily straightforward example:
$ guix shell --container --emulate-fhs coreutils -- ls /bin | head
[
b2sum
base32
base64
basename
basenc
cat
catchsegv
chcon
chgrp
and
$ guix shell --container --emulate-fhs coreutils -- ls /lib | head
Mcrt1.o
Scrt1.o
audit
crt1.o
crti.o
crtn.o
gconv
gcrt1.o
ld-2.33.so
ld-linux-x86-64.so.2
Contrast that with /bin
on a Guix system:
$ ls /bin -l
total 4
lrwxrwxrwx 1 root root 61 Dec 12 09:57 sh ->
/gnu/store/d99ykvj3axzzidygsmdmzxah4lvxd6hw-bash-5.1.8/bin/sh*
and /lib
$ ls /lib
ls: cannot access '/lib': No such file or directory
Or, if you like to see it more in motion, here’s a gif (courtesy of Ludovic Courtès):
Additionally, for the more technically-minded, the glibc
used in this
container
will read from a global cache in /etc/ld.so.cache
contrary to the behavior in
Guix
otherwise. This can help ensure that libraries are found when querying the ld cache or
using the output of ldconfig -p
, for example.
There are several uses that spring to mind for such a container in Guix. For developers,
or those aspiring to hack on a project, this is a helpful tool when needing to emulate a
different (non-Guix) environment. For example, one could use this to more easily follow
build instructions meant for a general distribution, say when a Guix package is not (yet)
available or easy to write immediately.
Another usage is to be able to use tools that don’t really fit into Guix’s model, like
ones that use pre-built binaries. There are many reasons why this is not ideal and Guix
strives to replace or supplement such tools, but practically speaking they can be hard to
avoid entirely. The FHS container helps bridge this gap, providing an isolated and
reproducible environment as needed.
Users not interested in development will also find the FHS container useful. For example,
there may be software that is free and conforms to the Free System Distribution
Guidelines (FSDG) Guix
follows, yet is not feasible to be
packaged by our standards.
JavaScript and particularly Electron applications are not
yet packaged for Guix due to the
difficulties of a properly
source-based and bootstrapable approach in this ecosystem.
As a more interesting example for this last point, let’s dive right into a big one: the
popular VSCodium editor. This is a freely
licensed build of Microsoft’s
VS Code editor. This is based on Electron and pre-built AppImages
are available. Downloading and making the
AppImage executable (with a chmod x
), we can run it in a container with
guix shell --container --network --emulate-fhs
--development ungoogled-chromium gcc:lib
--preserve='^DISPLAY$' --preserve='^XAUTHORITY$' --expose=$XAUTHORITY
--preserve='^DBUS_' --expose=/var/run/dbus
--expose=/sys/dev --expose=/sys/devices --expose=/dev/dri
-- ./VSCodium-1.74.0.22342.glibc2.17-x86_64.AppImage --appimage-extract-and-run
The second line is a handy cheat to get lots of libraries often needed for graphical
applications (development inputs of the package ungoogled-chromium
) though it can be
overkill if the AppImage does actually bundle everything (they don’t!). The next line is
for display on the host’s X server, the one after for DBus communication, and lastly
exposing some of the host hardware for rendering. This last part may be different on
different hardware. That should do it, at least to see basic functionality of VSCodium.
Note that we can’t run an AppImage without the --appimage-extract-and-run
option as it
will want to use FUSE to
mount the image which is not possible from the container.²
The FHS container is also useful to be able to run the exact same binary as anyone else,
as you might want to for privacy reasons with the Tor
Browser. While there is a long-standing set of
patches to build the Tor Browser from source, with a
container we can run the official build directly. After
downloading, checking the
signature, and
unpacking, we can launch the Tor Browser
from the root of the unpacked directory with:
guix shell --container --network --emulate-fhs
--preserve='^DISPLAY$' --preserve='^XAUTHORITY$' --expose=$XAUTHORITY
alsa-lib bash coreutils dbus-glib file gcc:lib
grep gtk libcxx pciutils sed
-- ./start-tor-browser.desktop -v
Here we’ve used a more minimal set of package inputs, rather than the ungoogled-chromium
trick above. Usually this is found through some trial and error, looking at log output,
maybe tracing, and sometimes from documentation. Though documentation of needed packages
often has some assumptions on what is already available on typical systems. (Thanks to Jim
Newsome for pointing out this example on the guix-devel mailing
list.)
Another example is to get the latest nightly builds of Rust, via rustup
.
$ mkdir ~/temphome
$ guix shell --network --container --emulate-fhs
bash coreutils curl grep nss-certs gcc:lib gcc-toolchain
pkg-config glib cairo atk pango@1.48.10 gdk-pixbuf gtk git
--share=$HOME/temphome=$HOME
~/temphome [env]$ curl --proto '=https' --tlsv1.2 -sSf | sh
First we created a ~/temphome
list to make employ of as $HOME
in the container after which
included a bunch of libraries in the container for the subsequent example.
This might possibly occasionally proceed with out dispute and we are going to behold
info: downloading installer
Welcome to Rust!
This might possibly occasionally download and set up the pleasant compiler for the Rust
programming language, and its equipment manager, Cargo.
...
Rust is installed now. Astronomical!
To get began you might possibly well possibly presumably also want to restart your most modern shell.
This might possibly possibly reload your PATH atmosphere variable to incorporate
Cargo's bin list ($HOME/.cargo/bin).
To configure your most modern shell, speed:
source "$HOME/.cargo/env"
After updating the shells atmosphere as suggested, we are able to behold all of it worked
~/temphome [env]$ rustc --model
rustc 1.65.0 (897e37553 2022-11-02)
as Guix’s most modern Rust is at 1.61.0 and we did now not even comprise Rust in the
container, obviously.
Lastly, we are able to construct a Rust venture of desktop widgets, ElKowars wacky widgets
(eww), following their
directions. By hook or by crook this uses honest appropriate the long-established cargo build --initiate
and builds after downloading all of the a truly great libraries.
~/temphome/eww [env]$ git clone https://github.com/elkowar/eww
...
~/temphome/eww [env]$ cd eww
~/temphome/eww [env]$ cargo build --initiate
info: syncing channel updates for 'nightly-2022-08-27-x86_64-unknown-linux-gnu'
info: most modern update on 2022-08-27, rust model 1.65.0-nightly (c07a8b4e0 2022-08-26)
...
Finished initiate [optimized] design(s) in 2m 06s
With this being a gentle container, you will want to construct some directories that in total
exist, be pleased ~/.config
and ~/.cache
on this case. For popular present enhance, it is
ample so that you might possibly possibly add --preserve='^DISPLAY$' --preserve='^XAUTHORITY$' --notify=$XAUTHORITY
to
the container initiate choices and speed the first example widget in the
documentation.
As we are able to behold, with containers more most frequently now we want to provide the nice inputs and
choices as the atmosphere is entirely specified at advent. If you take to pray to speed
one thing that needs hardware from the host or to get entry to host files, the container becomes
more and more porous for more functionality. Here’s absolutely a change-off, but one which
now we procure company with a container we wouldn’t get in some other case.
The FHS possibility offers one other possibility to construct a container in Guix to gain diversified
environments, even these with a vastly diversified philosophy of the muse filesystem! This
is one more machine in the Guix toolbox for controlled and reproducible environments that
also let’s us pause some things we couldn’t (with out complications) pause in some other case.
Notes
¹ Rather than a symlink for sh
from the bash
equipment, for compatibility reasons.
² In fact, one can employ flatpak-spawn
from
flatpak-xdg-utils
to initiate one thing
on the host and get the AppImage to mount itself. Alternatively, it is now now not considered from the identical
container. Or, we are able to employ a long-established mounting
course of
outdoors of the container to seek the contents, but AppImages can procure an offset. We
can employ the FHS container possibility to get this offset after which mount in a single line with mount VSCodium-1.74.0.22342.glibc2.17-x86_64.AppImage
About GNU Guix
GNU Guix is a transactional equipment manager and
an developed distribution of the GNU machine that respects user
freedom.
Guix might possibly well well also moreover be frail on prime of any machine running the Hurd or the Linux
kernel, or it will probably even moreover be frail as a standalone working machine distribution
for i686, x86_64, ARMv7, AArch64, and POWER9 machines.
To boot to to long-established equipment administration components, Guix supports
transactional upgrades and roll-backs, unprivileged equipment administration,
per-user profiles, and rubbish series. When frail as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless arrangement to
working machine configuration administration. Guix is extremely customizable
and hackable by Guile
programming interfaces and extensions to the
Plan language.
Except in some other case acknowledged, blog posts on this location are
copyrighted by their respective authors and printed below the phrases of
the CC-BY-SA 4.0 license and these of the GNU Free Documentation License (model 1.3 or later, with out a Invariant Sections, no
Front-Duvet Texts, and no Support-Duvet Texts).