Ben's Logarion ☪

topics:
Software
id:
a952a7cf-514d-4223-b2cc-13e6e051d777

Installing Guix on Fedora

Yesterday I went to the trouble of installing Guix on my Fedora 31 system, and along the way I encountered a few problems. Luckily, I was able to solve them myself, but my Google searches for a solution didn't turn up anything, so I thought I'd write here how to do what I did in case any one else experiences the same problem and needs advice.

Introduction

What Is Guix?

It might be worthwhile to explain a little bit about what Guix is, because the first time it was introduced to me, I couldn't really understand what it was really about. Obviously, it's a thing for installing software on your computer, but don't all Linux systems already have a package manager? Why would you want some other way to install programs on your system, and does that even work?

Guix is, of course, a kind of package management system. It's a system that automates the building and installation of software, and what makes it distinct is the way it facilitates the automatic generation of packages that are meticulously versioned and reproducable. Additionally, it offers some complex features for managing installations. It's not a lightweight system, and it has a tendency to install a large number of packages and multiple versions of packages, and it lets you quickly and even temporarily jump around between versions and environments. It actually does more than a typical user would need, but it offers features developers might find valuable.

Even so, as an end user, you could, for example, accidentally mess up your install by removing something (or multiple things), and then after coming to regret your mistake issue one simple command and it instantly goes back to the way it was before. In another scenario, let's say you update a package but later find the new version has a problem or you liked the previous version better, so you can undo that. Installed something new and decided you don't really want it after all? Roll back. Or maybe you actually did want it after all? No problem--roll forward. It's instantaneous.

Though it tends to accumulate a large backlog of data, Guix does also avoid duplication, and therefore saves some space by not keeping more copies of a file than necessary, even while providing a custom environment to every user on the system. Another user may or may not use the same programs as you, or they may be different versions, but Guix lets them smartly overlap so redundancy doesn't get out of hand. Furthermore, you can manually clear out old data whenever you like.

Aside from that, some other benefits worth considering are:

Why Did I Choose to Install Guix?

Some time ago I had Guix introduced to me by a group of developers who thought it was something amazing. They invited me to try it, but at first it didn't really seem feasible to me, and I was a little bit confused about it. Then recently a friend recommend Nix to me, and after telling me all about it and how great it is, I suddenly remembered Guix. Turns out the two are related, and you can sort ofthink of Guix as being GNU's own version of Nix.

After checking out Guix online and looking at its installation process and usage, it occurred to me that it would install very easily on any Linux system with little chance of screwing things up. It seemed simple enough that I should dare to try it, even just so I could play around with it.

Guix stores all its data in a couple centralized locations and won't get mixed up with the other files on your system such that you can't distinguish between them. When manually installing software on a Linux system that fear is always present, which is why one wisely sticks to the system's package manager and rarely strays.

Installing Guix on Fedora

In theory, Guix installation on any distro should be the same. Guix provides an install script to make the process as easy as possible. You first need only to issue one command to import the project's GPG key, and then the script can do the thing.

Enabling Substitutes

Do not do the foolish thing I did and say no to enabling substitutes (i.e. the binary repo). I knew what it was, but I said no because I wanted to watch Guix build everything from source. While it is kind of cool, it gets boring fast. (Not to mention it failed to build.) Even if you think you don't want substitutes, you probably do. Besides, it's easier to first enable them and then temporarily disable them as you see fit while invoking either the guix command or starting guix-daemon. The latter can be set up to be in effect more permanently, and consequently undoing it is trivial.

Besides, Guix packages are the result of reproducable builds, so in theory they should be identical to what your system turns out. By opting out you'd mainly just lose time. A lot of time.

If you didn't enable them during installation, there's no need to panic, as turning them on later is very simple. (It's a single command.) I was able to find that easily enough on their site, though it requires importing a GPG key fie that is supposed to be installed already along with Guix, but I had a little trouble finding it. I found a copy buried in the /gnu directory by using find, and that's probably not the best way to do it, but it worked. I assume it is meant to be available in a more obvious location. On my system the public keys are located in /gnu/store/*-guix-1.0.1/share/guix, whose version probably matches that of my installer.

Quick Daemon Workaround

After installation everything looks like it was a great success, but you'll soon notice that you can't load guix-daemon using systemd. Before getting into how to fix that, I just wanted to note that a quick workaround for the impatient is to start guix-daemon manually as root, which works fine. I fooled around with Guix for a little while like this before bothering to fix systemd. There's no problem with running Guix this way; it's just inconvenient compared to having the daemon automatically loaded and always available.

Even so, perhaps there are users who would prefer not to have the service loading and running automatically, so you could even disable that feature entirely by deleting the symlink in systemd's multiuser target directory.

SELinux Contexts

OK, now the reason I wrote this article: systemd does not load guix-daemon as a service because the Guix files are not labeled right according to SELinux. This causes systemd's attempts to execute the daemon to be denied. Therefore, you have to fix this by correcting the file permissions.

I've been using Fedora for more years than I care to count, and the Fedora Project has been using SELinux almost since the beginning. So, you'd think I'd know a thing or two about SELinux and security contexts. Well, I don't. In the past any time I messed with it I regreted it, and so I just let Fedora handle it automatically like it's supposed to. The last thing I'd ever want to do is touch contexts, but I knew that's why systemd wasn't loading guix-daemon, and it was up to me to fix it. To that end, I first frantically Googled in the hope that someone had already figured this out and posted about it online. No such luck.

My Method

When Guix is installed, there are two main directories to attend to, /gnu and /var/guix. You can check their SELinux contexts with the command ls -Z and see that they're wrong. Unfortunately, I don't remember what exactly that something was, but imagine it looks a little bit like this:

unconfined_u:object_r:default_t:s0

What you're looking at is three primary attributes ending with _u, _r, and _t, which are "user", "role", and "type". If I remember correctly, in my case the type was something like "temporary_t" or "un-somthing_t", which set off red flags. My instinct told me that systemd was refusig to load the daemon's binary because it was either the wrong type or owned by the wrong user.

I then compared this to other contexts I saw in the root and /var directories and decided that /gnu best match something like /opt, whose context is system_u:object_r:usr_t:s0. Therefore I issued the following command:

chcon -R -u system_u -t usr_t /gnu

Similarly, I recusively modified /var/guix to match what's in /var:

chcon -R -u system_u -t var_t /var/guix

After that, the following command worked:

service guix-daemon start

You can check that it's running by doing service guix-daemon status afterward. Needless to say, all of the above should be done as root.

Caution: One thing to note is that while chcon sets the files' contexts, I read that it's not the most permanent way to do this, so it's possible that the contexts might in the future somehow get reset back to something we don't want. However, this is as far as my knowlege goes, and feel free to contact me if you know more about this than I do. If I figure it out in the future I will update this page.

Official Method

Though I didn't know this at first, Guix actually comes with its own SELinux policy file designed for enabling guix-daemon to run on systems that have SELinux. The method for enabling this is described here in the official documentation, which refers to a policy file which on my system is located at /gnu/store/*-guix-1.0.1/share/selinux/guix-daemon.cil.

I have not tried this method yet, but I did notice that it uses restorecon to reset the security contexts, which means this is one of the more "permanent" methods I mentioned in my cautionary note in the previous section.

While this seems like a good solution, the items listed in the "Limitations" section of the documentation are a little bit worrisome. I do not kow if these limitations currently affect my own solution, but I'm not exactly in a hurry to find out. If it ain't broke...

Running Guix as User

The way that Guix is normally installed, it's already usable out of the box for non-root users. However, there is one caveat, which is that the systemd service that starts guix-daemon refers to a binary that Guix itself considers to belong to root. Because you're using Fedora, there is no reason to want to use Guix as root. (At least, as far as I can see.) You'll want to be running guix from your own user account, and that includes guix pull and guix package operations, which basically is all of what Guix does.

However, that caveat I mentioned means that while using Guix as yourself, the copy of guix-daemon in root's profile will not update along with the rest of the software. Your own version of this file will get updated, but systemd will keep loading root's copy.

Assuming that you are the main or possibly only person using your system, you won't want to use root's Guix at all. The solution to that is simply to modify the file /etc/systemd/system/guix-daemon.service so that references to root are replaced by your username. If your username is "babu", then this:

ExecStart=/var/guix/profiles/per-user/root/current-guix/bin/guix-daemon --build-users-group=guixbuild
Environment='GUIX_LOCPATH=/var/guix/profiles/per-user/root/guix-profile/lib/locale' LC_ALL=en_US.utf8

...should look like this:

ExecStart=/var/guix/profiles/per-user/babu/current-guix/bin/guix-daemon --build-users-group=guixbuild
Environment='GUIX_LOCPATH=/var/guix/profiles/per-user/babu/guix-profile/lib/locale' LC_ALL=en_US.utf8

Those should be the only two references in the file, and once modified you will need to issue a systemd command to reload the file. systemd was nice enough to tell me this when I first tried to reload the service: systemctl daemon-reload should do the trick.

Tips for Beginners

Assuming that if you are reading this you are probably new to Guix, I thought I'd also mention a couple things about how to use it since I personally found it daunting. I also spent some time talking to Guix devs and regular users to make sure that I was doing the right thing.

Pulling and Upgrading

When you want to do something with Guix, you will want to make sure everything is up to date before you start. First you will run the command guix pull, which updates Guix itself but will not upgrade your packages. Once the pull has completed successfully, you can run guix package -u or guix upgrade to upgrade your packages. Depending on the situation, these operations can be expensive in terms of time consumption and also data if your Internet connection is metered. Therefore, you'll want to exercise discretion when timing these operations, and it may be unwise to do them too frequently in a short span of time.

Also, it's generally a good idea to use the --dry-run option prior to get an idea of what you're getting into before committing the operation.

Searching, Installing, and Removing

As found here:

Getting Information

Here are some useful commands to look at the state of your Guix setup:

These are fairly self-explanatory. Generations are like snapshots made for every change to the system. Each generation has a number that can be used to switch between them. I recommend looking at Guix's online documents and tutorials to learn more about how this works.

Cleaning Up

If you're like me, then you're probably going to do a bunch of updates and installations while Guix is new just to check it out and see what it does. Because of that you'll end up wasting a surprising amount of disk space fooling around. That's alright of course, but because Guix is something of a monstrosity, you learn to think before you act.

Ensuring that you are all done fooling around, everything is in a final state you think it should stay in, and you have no desire to go back in time to previous generations, you can run the following commands to wipe out just about everything:

That last command runs the garbage collector, and at may impress you by freeing up gigabytes of disk space.

Uninstalling Guix

After having run Guix on Fedora for a couple weeks, I decided that it was finally time to remove it. The main reason was that I had moved onto running Guix System in a virtual machine and found that to be a more ideal solution.

Having decided I wanted it to live in the VM and make my Fedora system a little cleaner and lighter again, I surmised that the only way to remove Guix is in manual fashion, as I did not see or find any uninstallation instructions.

Removing Guix is simple because there's very few things to worry about. First of all, there are some files in /etc that you should look for. All of them should be easy to find with find because they have "guix" in their name. What you mainly need to remove there is the init scripts for systemd to no longer load the daemon, and the file in profile.d that sets up the Guix environment variables for your shell. I think that's it for /etc. (Also, you'll obviously want to make sure you stopped the daemon first if it's running.)

The next thing to do is simply remove /gnu and /var/guix from your system. Since almost everything is stored there, you're good to go after that. Optionally, you can search your home directory for whatever is left over, like ~/.guix-profile or something. I found a few cached files in another directory as well.