https://guix.gnu.org/feeds/blog/customization.atomGNU Guix — Blog — Customizationfeed author nameGNU Guixhttps://guix.gnu.org/static/base/img/icon.png2020-08-14T21:45:03Zhttps://guix.gnu.org/blog/2019/guix-profiles-in-practice/Guix Profiles in PracticePierre Neidhardt2019-10-25T12:15:00Z2019-10-25T12:15:00Z Note: An updated version of this article is available in the brand new cookbook . Guix provides a very useful feature that may be quite foreign to newcomers:
profiles . They are a way to group package installations together and all users
on the same system are free to use as many profiles as they want. Whether you're a developer or not, you may find that multiple profiles bring you
great power and flexibility. While they shift the paradigm somewhat compared to
traditional package managers , they are very convenient to use once…<p><em>Note: An updated version of this article is available in the brand new <a href="https://guix.gnu.org/cookbook/en/">cookbook</a>.</em></p><p>Guix provides a very useful feature that may be quite foreign to newcomers:
<em>profiles</em>. They are a way to group package installations together and all users
on the same system are free to use as many profiles as they want.</p><p>Whether you're a developer or not, you may find that multiple profiles bring you
great power and flexibility. While they shift the paradigm somewhat compared to
<em>traditional package managers</em>, they are very convenient to use once you've
understood how to set them up.</p><p>If you are familiar with Python's <code>virtualenv</code>, you can think of a profile as a
kind of universal <code>virtualenv</code> that can hold any kind of software whatsoever, not
just Python software. Furthermore, profiles are self-sufficient: they capture
all the runtime dependencies which guarantees that all programs within a profile
will always work at any point in time.</p><p>Multiple profiles have many benefits:</p><ul><li><p>Clean semantic separation of the various packages a user needs for different contexts.</p></li><li><p>Multiple profiles can be made available into the environment either on login
or within a dedicated shell.</p></li><li><p>Profiles can be loaded on demand. For instance, the user can use multiple
shells, each of them running different profiles.</p></li><li><p>Isolation: Programs from one profile will not use programs from the other, and
the user can even install different versions of the same programs to the two
profiles without conflict.</p></li><li><p>Deduplication: Profiles share dependencies that happens to be the exact same.
This makes multiple profiles storage-efficient.</p></li><li><p>Reproducible: when used with declarative manifests, a profile can be fully
specified by the Guix commit that was active when it was set up. This means
that the exact same profile can be <a href="https://guix.gnu.org/blog/2018/multi-dimensional-transactions-and-rollbacks-oh-my/">set up anywhere, anytime</a>, with just the
commit information. See section “Reproducible profiles” below.</p></li><li><p>Easier upgrades and maintenance: Multiple profiles make it easy to keep
package listings at hand and make upgrades completely friction-less.</p></li></ul><p>Concretely, here follows some typical profiles:</p><ul><li><p>The dependencies of a project you are working on.</p></li><li><p>Your favourite programming language libraries.</p></li><li><p>Laptop-specific programs (like <code>powertop</code>) that you don't need on a desktop.</p></li><li><p>TeXlive (this one can be really useful when you need to install just one
package for this one document you've just received over email).</p></li><li><p>Games.</p></li></ul><p>Let's dive in the set up!</p><h1>Basic setup with manifests</h1><p>A Guix profile can be set up <em>via</em> a so-called <em>manifest specification</em> that looks like
this:</p><pre><code class="language-scheme">(specifications->manifest
'("package-1"
;; Version 1.3 of package-2.
"package-2@1.3"
;; The "lib" output of package-3.
"package-3:lib"
; ...
"package-N"))</code></pre><p>See <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-package.html">(guix) Invoking guix package</a> for the syntax details.</p><p>We can create a manifest specification per profile and install them this way:</p><pre><code>GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
mkdir -p "$GUIX_EXTRA_PROFILES"/my-project # if it does not exist yet
guix package --manifest=/path/to/guix-my-project-manifest.scm --profile="$GUIX_EXTRA_PROFILES"/my-project/my-project</code></pre><p>Here we set an arbitrary variable <code>GUIX_EXTRA_PROFILES</code> to point to the directory
where we will store our profiles in the rest of this article.</p><p>Placing all your profiles in a single directory, with each profile getting its
own sub-directory, is somewhat cleaner. This way, each sub-directory will
contain all the symlinks for precisely one profile. Besides, "looping over
profiles" becomes obvious from any programming language (e.g. a shell script) by
simply looping over the sub-directories of <code>$GUIX_EXTRA_PROFILES</code>.</p><p>Note that it's also possible to loop over the output of</p><pre><code>guix package --list-profiles</code></pre><p>although you'll probably have to filter out <code>~/.config/guix/current</code>.</p><p>To enable all profiles on login, add this to your <code>~/.bash_profile</code> (or similar):</p><pre><code>for i in $GUIX_EXTRA_PROFILES/*; do
profile=$i/$(basename "$i")
if [ -f "$profile"/etc/profile ]; then
GUIX_PROFILE="$profile"
. "$GUIX_PROFILE"/etc/profile
fi
unset profile
done</code></pre><p>Note to Guix System users: the above reflects how your default profile
<code>~/.guix-profile</code> is activated from <code>/etc/profile</code>, that latter being loaded by
<code>~/.bashrc</code> by default.</p><p>You can obviously choose to only enable a subset of them:</p><pre><code>for i in "$GUIX_EXTRA_PROFILES"/my-project-1 "$GUIX_EXTRA_PROFILES"/my-project-2; do
profile=$i/$(basename "$i")
if [ -f "$profile"/etc/profile ]; then
GUIX_PROFILE="$profile"
. "$GUIX_PROFILE"/etc/profile
fi
unset profile
done</code></pre><p>When a profile is off, it's straightforward to enable it for an individual shell
without "polluting" the rest of the user session:</p><pre><code>GUIX_PROFILE="path/to/my-project" ; . "$GUIX_PROFILE"/etc/profile</code></pre><p>The key to enabling a profile is to <em>source</em> its <code>etc/profile</code> file. This file
contains shell code that exports the right environment variables necessary to
activate the software contained in the profile. It is built automatically by
Guix and meant to be sourced.
It contains the same variables you would get if you ran:</p><pre><code>guix package --search-paths=prefix --profile=$my_profile"</code></pre><p>Once again, see <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-package.html">(guix) Invoking guix package</a> for the command line options.</p><p>To upgrade a profile, simply install the manifest again:</p><pre><code>guix package -m /path/to/guix-my-project-manifest.scm -p "$GUIX_EXTRA_PROFILES"/my-project/my-project</code></pre><p>To upgrade all profiles, it's easy enough to loop over them. For instance,
assuming your manifest specifications are stored in
<code>~/.guix-manifests/guix-$profile-manifest.scm</code>, with <code>$profile</code> being the name
of the profile (e.g. "project1"), you could do the following in Bourne shell:</p><pre><code>for profile in "$GUIX_EXTRA_PROFILES"/*; do
guix package --profile="$profile" --manifest="$HOME/.guix-manifests/guix-$profile-manifest.scm"
done</code></pre><p>Each profile has its own generations:</p><pre><code>guix package -p "$GUIX_EXTRA_PROFILES"/my-project/my-project --list-generations</code></pre><p>You can roll-back to any generation of a given profile:</p><pre><code>guix package -p "$GUIX_EXTRA_PROFILES"/my-project/my-project --switch-generations=17</code></pre><h1>Required packages</h1><p>Activating a profile essentially boils down to exporting a bunch of
environmental variables. This is the role of the <code>etc/profile</code> within the
profile.</p><p><em>Note: Only the environmental variables of the packages that consume them will
be set.</em></p><p>For instance, <code>MANPATH</code> won't be set if there is no consumer application for man
pages within the profile. So if you need to transparently access man pages once
the profile is loaded, you've got two options:</p><ul><li><p>Either export the variable manually, e.g.</p><pre><code>export MANPATH=/path/to/profile${MANPATH:+:}$MANPATH</code></pre></li><li><p>Or include <code>man-db</code> to the profile manifest.</p></li></ul><p>The same is true for <code>INFOPATH</code> (you can install <code>info-reader</code>),
<code>PKG_CONFIG_PATH</code> (install <code>pkg-config</code>), etc.</p><h1>Default profile</h1><p>What about the default profile that Guix keeps in <code>~/.guix-profile</code>?</p><p>You can assign it the role you want. Typically you would install the manifest
of the packages you want to use all the time.</p><p>Alternatively, you could keep it "manifest-less" for throw-away packages
that you would just use for a couple of days.
This way makes it convenient to run</p><pre><code>guix install package-foo
guix upgrade package-bar</code></pre><p>without having to specify the path to a profile.</p><h1>The benefits of manifests</h1><p>Manifests are a convenient way to keep your package lists around and, say,
to synchronize them across multiple machines using a version control system.</p><p>A common complaint about manifests is that they can be slow to install when they
contain large number of packages. This is especially cumbersome when you just
want get an upgrade for one package within a big manifest.</p><p>This is one more reason to use multiple profiles, which happen to be just
perfect to break down manifests into multiple sets of semantically connected
packages. Using multiple, small profiles provides more flexibility and
usability.</p><p>Manifests come with multiple benefits. In particular, they ease maintenance:</p><ul><li><p>When a profile is set up from a manifest, the manifest itself is
self-sufficient to keep a "package listing" around and reinstall the profile
later or on a different system. For ad-hoc profiles, we would need to
generate a manifest specification manually and maintain the package versions
for the packages that don't use the default version.</p></li><li><p><code>guix package --upgrade</code> always tries to update the packages that have
propagated inputs, even if there is nothing to do. Guix manifests remove this
problem.</p></li><li><p>When partially upgrading a profile, conflicts may arise (due to diverging
dependencies between the updated and the non-updated packages) and they can be
annoying to resolve manually. Manifests remove this problem altogether since
all packages are always upgraded at once.</p></li><li><p>As mentioned above, manifests allow for reproducible profiles, while the
imperative <code>guix install</code>, <code>guix upgrade</code>, etc. do not, since they produce
different profiles every time even when they hold the same packages. See
<a href="https://issues.guix.gnu.org/issue/33285">the related discussion on the matter</a>.</p></li><li><p>Manifest specifications are usable by other <code>guix</code> commands. For example, you
can run <code>guix weather -m manifest.scm</code> to see how many substitutes are
available, which can help you decide whether you want to try upgrading today
or wait a while. Another example: you can run <code>guix pack -m manifest.scm</code> to
create a pack containing all the packages in the manifest (and their
transitive references).</p></li><li><p>Finally, manifests have a Scheme representation, the <code><manifest></code> record type.
They can be manipulated in Scheme and passed to the various Guix <a href="https://en.wikipedia.org/wiki/Api">APIs</a>.</p></li></ul><p>It's important to understand that while manifests can be used to declare
profiles, they are not strictly equivalent: profiles have the side effect that
they "pin" packages in the store, which prevents them from being
<a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-gc.html">garbage-collected</a> and ensures that they will still be available at any point in
the future.</p><p>Let's take an example:</p><ol><li><p>We have an environment for hacking on a project for which there isn't a Guix
package yet. We build the environment using a manifest, and then run <code>guix environment -m manifest.scm</code>. So far so good.</p></li><li><p>Many weeks pass and we have run a couple of <code>guix pull</code> in the mean time.
Maybe a dependency from our manifest has been updated; or we may have run
<code>guix gc</code> and some packages needed by our manifest have been
garbage-collected.</p></li><li><p>Eventually, we set to work on that project again, so we run <code>guix environment -m manifest.scm</code>. But now we have to wait for Guix to build and install
stuff!</p></li></ol><p>Ideally, we could spare the rebuild time. And indeed we can, all we need is to
install the manifest to a profile and use <code>GUIX_PROFILE=/the/profile; . "$GUIX_PROFILE"/etc/profile</code> as explained above: this guarantees that our
hacking environment will be available at all times.</p><p><em>Security warning:</em> While keeping old profiles around can be convenient, keep in
mind that outdated packages may not have received the latest security fixes.</p><h1>Reproducible profiles</h1><p>To reproduce a profile bit-for-bit, we need two pieces of information:</p><ul><li>a manifest,</li><li>a Guix channel specification.</li></ul><p>Indeed, manifests alone might not be enough: different Guix versions (or
different channels) can produce different outputs for a given manifest.</p><p>You can output the Guix channel specification with <code>guix describe --format=channels</code>.
Save this to a file, say <code>channel-specs.scm</code>.</p><p>On another computer, you can use the channel specification file and the manifest
to reproduce the exact same profile:</p><pre><code>GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
GUIX_EXTRA=$HOME/.guix-extra
mkdir "$GUIX_EXTRA"/my-project
guix pull --channels=channel-specs.scm --profile "$GUIX_EXTRA/my-project/guix"
mkdir -p "$GUIX_EXTRA_PROFILES/my-project"
"$GUIX_EXTRA"/my-project/guix/bin/guix package --manifest=/path/to/guix-my-project-manifest.scm --profile="$GUIX_EXTRA_PROFILES"/my-project/my-project</code></pre><p>It's safe to delete the Guix channel profile you've just installed with the
channel specification, the project profile does not depend on it.</p><h1>Special thanks</h1><p>Chris Marusich and Simon Tournier for their thorough feedback.</p><h1>About GNU Guix</h1><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package manager and an advanced distribution of the
GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects user freedom</a>. Guix can be used on top of any system
running the kernel Linux, or it can be used as a standalone operating system
distribution for i686, x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports transactional
upgrades and roll-backs, unprivileged package management, per-user profiles, and
garbage collection. When used as a standalone GNU/Linux distribution, Guix
offers a declarative, stateless approach to operating system configuration
management. Guix is highly customizable and hackable through <a href="https://www.gnu.org/software/guile">Guile</a> programming
interfaces and extensions to the <a href="http://schemers.org/">Scheme</a> language.</p>https://guix.gnu.org/blog/2019/creating-and-using-a-custom-linux-kernel-on-guix-system/Creating and using a custom Linux kernel on Guix SystemEfraim Flashner2019-05-21T12:00:00Z2019-05-21T12:00:00Z Guix is, at its core, a source based distribution with
substitutes ,
and as such building packages from their source code is an expected part
of regular package installations and upgrades. Given this starting
point, it makes sense that efforts are made to reduce the amount of time
spent compiling packages, and recent changes and upgrades to the
building and distribution of substitutes continues to be a topic of
discussion within Guix. One of the packages which I prefer to not build myself is the
Linux-Libre kernel. The kernel, while not requiring an overabundance of
RAM to build, does take a very long…<p>Guix is, at its core, a source based distribution with
<a href="https://www.gnu.org/software/guix/manual/en/html_node/Substitutes.html">substitutes</a>,
and as such building packages from their source code is an expected part
of regular package installations and upgrades. Given this starting
point, it makes sense that efforts are made to reduce the amount of time
spent compiling packages, and recent changes and upgrades to the
building and distribution of substitutes continues to be a topic of
discussion within Guix.</p><p>One of the packages which I prefer to not build myself is the
Linux-Libre kernel. The kernel, while not requiring an overabundance of
RAM to build, does take a very long time on my build machine (which my
children argue is actually their Kodi computer), and I will often delay
reconfiguring my laptop while I want for a substitute to be prepared by
the official build farm. The official kernel configuration, as is the
case with many GNU/Linux distributions, errs on the side of
inclusiveness, and this is really what causes the build to take such a
long time when I build the package for myself.</p><p>The Linux kernel, however, can also just be described as a package
installed on my machine, and as such can be customized just like any
other package. The procedure is a little bit different, although this
is primarily due to the nature of how the package definition is written.</p><p>The
<a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/linux.scm#n294"><code>linux-libre</code></a>
kernel package definition is actually a procedure
which creates a package.</p><pre><code class="language-scheme">(define* (make-linux-libre version hash supported-systems
#:key
;; A function that takes an arch and a variant.
;; See kernel-config for an example.
(extra-version #f)
(configuration-file #f)
(defconfig "defconfig")
(extra-options %default-extra-linux-options)
(patches (list %boot-logo-patch)))
...)</code></pre><p>The current <code>linux-libre</code> package is for the 5.1.x series, and is
declared like this:</p><pre><code class="language-scheme">(define-public linux-libre
(make-linux-libre %linux-libre-version
%linux-libre-hash
'("x86_64-linux" "i686-linux" "armhf-linux" "aarch64-linux")
#:patches %linux-libre-5.1-patches
#:configuration-file kernel-config))</code></pre><p>Any keys which are not assigned values inherit their default value from
the <code>make-linux-libre</code> definition. When comparing the two snippets above,
you may notice that the code comment in the first doesn't actually refer
to the <code>#:extra-version</code> keyword; it is actually for <code>#:configuration-file</code>.
Because of this, it is not actually easy to include a custom kernel
configuration from the definition, but don't worry, there are other ways
to work with what we do have.</p><p>There are two ways to create a kernel with a custom kernel configuration.
The first is to provide a standard <code>.config</code> file during the build
process by including an actual <code>.config</code> file as a native input to our
custom kernel. The
<a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/linux.scm#n379">following</a>
is a snippet from the custom 'configure phase of the <code>make-linux-libre</code>
package definition:</p><pre><code class="language-scheme">(let ((build (assoc-ref %standard-phases 'build))
(config (assoc-ref (or native-inputs inputs) "kconfig")))
;; Use a custom kernel configuration file or a default
;; configuration file.
(if config
(begin
(copy-file config ".config")
(chmod ".config" #o666))
(invoke "make" ,defconfig))</code></pre><p>Below is a sample kernel package for one of my computers. Linux-Libre
is just like other regular packages and can be inherited and overridden
like any other:</p><pre><code class="language-scheme">(define-public linux-libre/E2140
(package
(inherit linux-libre)
(native-inputs
`(("kconfig" ,(local-file "E2140.config"))
,@(alist-delete "kconfig"
(package-native-inputs linux-libre))))))</code></pre><p>In the same directory as the file defining <code>linux-libre-E2140</code> is a file
named <code>E2140.config</code>, which is an actual kernel configuration file. I
left the defconfig keyword of <code>make-linux-libre</code> blank, so the only
kernel configuration in the package is the one which I included as a
native-input.</p><p>The second way to create a custom kernel is to pass a new value to the
extra-options keyword of the <code>make-linux-libre</code> procedure. The
extra-options keyword works with another function defined right below it:</p><pre><code class="language-scheme">(define %default-extra-linux-options
`(;; https://lists.gnu.org/archive/html/guix-devel/2014-04/msg00039.html
("CONFIG_DEVPTS_MULTIPLE_INSTANCES" . #t)
;; Modules required for initrd:
("CONFIG_NET_9P" . m)
("CONFIG_NET_9P_VIRTIO" . m)
("CONFIG_VIRTIO_BLK" . m)
("CONFIG_VIRTIO_NET" . m)
("CONFIG_VIRTIO_PCI" . m)
("CONFIG_VIRTIO_BALLOON" . m)
("CONFIG_VIRTIO_MMIO" . m)
("CONFIG_FUSE_FS" . m)
("CONFIG_CIFS" . m)
("CONFIG_9P_FS" . m)))
(define (config->string options)
(string-join (map (match-lambda
((option . 'm)
(string-append option "=m"))
((option . #t)
(string-append option "=y"))
((option . #f)
(string-append option "=n")))
options)
"\n"))</code></pre><p>And in the custom configure script from the <code>make-linux-libre</code> package:</p><pre><code class="language-scheme">;; Appending works even when the option wasn't in the
;; file. The last one prevails if duplicated.
(let ((port (open-file ".config" "a"))
(extra-configuration ,(config->string extra-options)))
(display extra-configuration port)
(close-port port))
(invoke "make" "oldconfig"))))</code></pre><p>So by not providing a configuration-file the <code>.config</code> starts blank, and
then we write into it the collection of flags that we want. Here's
another custom kernel which I have:</p><pre><code class="language-scheme">(define %macbook41-full-config
(append %macbook41-config-options
%filesystems
%efi-support
%emulation
(@@ (gnu packages linux) %default-extra-linux-options)))
(define-public linux-libre-macbook41
;; XXX: Access the internal 'make-linux-libre' procedure, which is
;; private and unexported, and is liable to change in the future.
((@@ (gnu packages linux) make-linux-libre) (@@ (gnu packages linux) %linux-libre-version)
(@@ (gnu packages linux) %linux-libre-hash)
'("x86_64-linux")
#:extra-version "macbook41"
#:patches (@@ (gnu packages linux) %linux-libre-5.1-patches)
#:extra-options %macbook41-config-options))</code></pre><p>From the above example <code>%filesystems</code> is a collection of flags I
compiled enabling different filesystem support, <code>%efi-support</code> enables
EFI support and <code>%emulation</code> enables my x86_64-linux machine to act in
32-bit mode also. <code>%default-extra-linux-options</code> are the ones quoted
above, which had to be added in since I replaced them in the
extra-options keyword.</p><p>This all sounds like it should be doable, but how does one even know
which modules are required for their system? The two places I found
most helpful to try to answer this question were the <a href="https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Kernel">Gentoo
Handbook</a>,
and the
<a href="https://www.kernel.org/doc/html/latest/admin-guide/README.html?highlight=localmodconfig">documentation</a>
from the kernel itself. From the kernel documentation, it seems that
<code>make localmodconfig</code> is the command we want.</p><p>In order to actually run <code>make localmodconfig</code> we first need to get and
unpack the kernel source code:</p><pre><code class="language-shell">tar xf $(guix build linux-libre --source)</code></pre><p>Once inside the directory containing the source code run <code>touch .config</code>
to create an initial, empty <code>.config</code> to start with. <code>make localmodconfig</code> works by seeing what you already have in <code>.config</code> and
letting you know what you're missing. If the file is blank then you're
missing everything. The next step is to run:</p><pre><code class="language-shell">guix environment linux-libre -- make localmodconfig</code></pre><p>and note the output. Do note that the <code>.config</code> file is still empty.
The output generally contains two types of warnings. The first start
with "WARNING" and can actually be ignored in our case. The second read:</p><pre><code class="language-shell">module pcspkr did not have configs CONFIG_INPUT_PCSPKR</code></pre><p>For each of these lines, copy the <code>CONFIG_XXXX_XXXX</code> portion into the
<code>.config</code> in the directory, and append <code>=m</code>, so in the end it looks
like this:</p><pre><code class="language-shell">CONFIG_INPUT_PCSPKR=m
CONFIG_VIRTIO=m</code></pre><p>After copying all the configuration options, run <code>make localmodconfig</code>
again to make sure that you don't have any output starting with
"module". After all of these machine specific modules there are a
couple more left that are also needed. <code>CONFIG_MODULES</code> is necessary so
that you can build and load modules separately and not have everything
built into the kernel. <code>CONFIG_BLK_DEV_SD</code> is required for reading from
hard drives. It is possible that there are other modules which you
will need.</p><p>This post does not aim to be a guide to configuring your own kernel
however, so if you do decide to build a custom kernel you'll have to
seek out other guides to create a kernel which is just right for your
needs.</p><p>The second way to setup the kernel configuration makes more use of
Guix's features and allows you to share configuration segments between
different kernels. For example, all machines using EFI to boot have a
number of EFI configuration flags that they need. It is likely that all
the kernels will share a list of filesystems to support. By using
variables it is easier to see at a glance what features are enabled and
to make sure you don't have features in one kernel but missing in another.</p><p>Left undiscussed however, is Guix's initrd and its customization. It is
likely that you'll need to modify the initrd on a machine using a custom
kernel, since certain modules which are expected to be built may not be
available for inclusion into the initrd.</p><p>Suggestions and contributions toward working toward a satisfactory
custom initrd and kernel are welcome!</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package
manager and an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects
user
freedom</a>.
Guix can be used on top of any system running the kernel Linux, or it
can be used as a standalone operating system distribution for i686,
x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>