Running guix package manager on top of Fedora Silverblue, updated instructions
Written by Sebastian Dümcke on
Tags: silverblue guix
I have received reports that my previous instructions on how to install the guix package manager on Fedora Silverblue ceased to work. This was due to a change in Fedora Silverblue 42/43 enabling composefs. I took some time last weekend to find a solution and publish new instructions in this post. In addition to working on the current version of Silverblue, these instructions also allow running guix without turning off SELinux and migrate to the new unprivileged daemon for an increase in security! Let’s dive right in.
Instructions
All these steps have been performed on a fresh Silverblue 43 install. If you are upgrading from a prior version with guix installed you might want to clean up the prior changes (most likely the guix-daemon.service file) and remove the guixbuild users etc…
disable composefs using method from:https://github.com/DeterminateSystems/nix-installer/issues/1445#issuecomment-2856334377 This is certainly the part most likely to break in the future. But it works in the current version 43 of Silverblue.
sudo tee /etc/ostree/prepare-root.conf <<'EOL' [composefs] enabled = yes [root] transient = true EOL sudo rpm-ostree initramfs-etc --reboot --track=/etc/ostree/prepare-root.conf
add the unprivileged build user and group required by the new guix-daemon
sudo groupadd --system guix-daemon sudo useradd -g guix-daemon -G guix-deamon,kvm -d /var/empty -s "$(command -v nologin)" -c "Unpriviledged Guix Daemon User" guix-daemon
Download the latest binary release from guix, untar the files, copy to their final location and change ownership to
guix_daemonuserARCHIVE=wn70p66a5lvk3sj0n0f9rcd5fp6f3s25-guix-binary.tar.xz tar xvf $ARCHIVE #mv gnu/store to /var/gnustore and guix to /var/guix sudo mv gnu/store /var/gnustore sudo mv var/guix /var/ sudo chown -R guix-daemon:guix:daemon /var/gnustore /var/guix sudo chown -R root:root /var/guix/profiles/per-user/root
create log directory for guix
sudo mkdir -p /var/log/guix sudo chown guix-daemon:guix-daemon /var/log/guix sudo chmod 755 /var/log/guix
adapt and install the SELinux context: This might not be required in the future if a patch is committed to the guix repository. The issue is tracked here.
sed '243s/write)/write mounton)/' $(find /var/gnustore -name guix-daemon.cil | head -n 1) > guix-daemon.cil sudo semodule -i guix-daemon.cil
- install the systemD files for mounting the store and starting the guix-daemon
Service unit to create the mount point at root level. This is the part that requires disabling
composefsin the step 1.#/etc/systemd/system/mkdir-rootfs@.service [Unit] Description=Enable mount points in / for ostree DefaultDependencies=no ConditionPathExists=!%f [Service] Type=oneshot ExecStartPre=chattr -i / ExecStart=mkdir -p '%f' ExecStopPost=chattr +i /
Service unit to mount
/var/gnustore/to/gnu/store#/etc/systemd/system/gnu-store.mount [Unit] Description=Read-only /gnu/store for GNU Guix adapted to Silverblue After=mkdir-rootfs@gnu-store.service Wants=mkdir-rootfs@gnu-store.service Before=guix-daemon.service [Install] WantedBy=guix-daemon.service [Mount] What=/var/gnustore Where=/gnu/store Type=none Options=bind,ro
Service unit to start the guix-daemon adapted to our Silverblue scenario
#/etc/systemd/system/guix-daemon.service [Unit] Description=Build daemon for GNU Guix #ensure store is mounted under /gnu/store for profile links to work After=gnu-store.mount Requires=gnu-store.mount [Service] ExecStart=/var/guix/profiles/per-user/root/current-guix/bin/guix-daemon \ --discover=no \ --substitute-urls='https://bordeaux.guix.gnu.org https://ci.guix.gnu.org' Environment='GUIX_STATE_DIRECTORY=/var/guix' 'GUIX_LOCPATH=/var/guix/profiles/per-user/root/guix-profile/lib/locale' LC_ALL=en_US.utf8 # Run under a dedicated unprivileged user account. User=guix-daemon # Bind-mount the store read-write in a private namespace, to counter the # effect of 'gnu-store.mount'. PrivateMounts=true BindPaths=/var/gnustore:/gnu/store # Disable host file system mount propagation to keep service view of the # store read-write after 'gnu-store.mount' makes it read-only system-wide. MountFlags=private # Mitigate race condition between guix-daemon and 'gnu-store.mount'. # Dependent units will only start after daemon binary is started AND THUS # the mount point is acquired in a private namespace. Type=exec # Provide the CAP_CHOWN capability so that guix-daemon can create and chown # /var/guix/profiles/per-user/$USER and also chown failed build directories # when using '--keep-failed'. Note that guix-daemon explicitly drops ambient # capabilities before executing build processes so they don't inherit them. AmbientCapabilities=CAP_CHOWN StandardOutput=journal StandardError=journal # Work around a nasty systemd ‘feature’ that kills the entire process tree # (including the daemon!) if any child, such as cc1plus, runs out of memory. OOMPolicy=continue # Despite the name, this is rate-limited: a broken daemon will eventually fail. Restart=always # See <https://lists.gnu.org/archive/html/guix-devel/2016-04/msg00608.html>. # Some package builds (for example, go@1.8.1) may require even more than # 1024 tasks. TasksMax=8192 [Install] WantedBy=multi-user.target
Mount the gnu store, remount it rw and label the files for SELinux
sudo systemctl start gnu-store.mount sudo mount -o remount,rw /gnu/store sudo restorecon -R /gnu /var/guix sudo umount /gnu/store
- Finally we can enable and start the guix-daemon:
sudo systemctl --now enable guix-daemon Last we need to authorize the substitutes and pull from the root guix to generate the local guix version:
sudo /var/guix/profiles/per-user/root/current-guix/bin/guix archive --authorize < /var/guix/profiles/per-user/root/current-guix/share/guix/ci.guix.gnu.org.pub sudo /var/guix/profiles/per-user/root/current-guix/bin/guix archive --authorize < /var/guix/profiles/per-user/root/current-guix/share/guix/bordeaux.guix.gnu.org.pub /var/guix/profiles/per-user/root/current-guix/bin/guix pull
Do not forget to source the profile as indicated by the message in the shell.
Conclusion
With these changes we can use guix on Fedora Silverblue again. However, the Silverblue project is still rapidly evolving. It is my understanding that they are migrating away from OSTree to bootc and might implement further changes that will again break these instructions. If you find any issues, do not hesitate to write me an email (code at sam-d.com), I enjoy feedback from my readers.
I had other troubles updating from 41 to 42 related to package overlays that have kept me on version 41 for far too long. My main concern in using Silverblue compared with other distributions (and guix system) is to be able to upgrade without fear and having a system that ’just works’. This has been mainly true for Silverblue aside from these recent hiccups. I have looked into other immutable distributions (nitrux, VanillaOS, blandOS, arkane Linux, SUSE) however Silverblue still seems to best respond to my needs. I am happy to have a running system with guix again.