How to Make your own Guix Channel
March 3, 2024
Understanding Channels #
GNU/Guix is a transactional package manager and an advanced distribution of the GNU system that “respects user freedom”. As a powerful tool, Guix allows users to create their own package repositories in the form of Git repositories called channels.
This allows you to host your own packages to share with the world, or just with your friends.
Channels are a repository of Guix package definitions hosted using Git. This functionality opens up an avenue for users to extend Guix and its package collection, enabling the addition of custom software or services that may not be available in the default Guix repository.
You can create public or private channels, however private channels only work through SSH, which isn’t supported by all Git hosting platforms (for example GitHub).
You don’t have to know Scheme to follow this, but some familiarity with Guix will be assumed. We will make frequent reference to Guix Home. As ever, the first place you should look for answers is in the Guix Reference Manual. In particular the section Creating a Channel is worth a look at if you haven’t already. Beyond this, Peter Lo has written a fantastic in-depth blog post that covers the same topic.
Role of Channels #
Channel repositories consist of Guile modules that export packages or services.
These packages then become accessible via any ‘guix’ command, once the
channel is added to the Guix channels using guix pull
.
What can you use a channel for? #
The use of channels provides numerous advantages:
- Packages: Channels can host a wide array of software, including those not available in the default Guix package collection. Channels can be pinned to specific commits, ensuring complete reproducibility of the software environment across multiple machines. Or you could get more up-to-date versions than are currently in Guix’s main channel.
- Configuration compnonents: Services for Guix Home and Guix System can be included in channels. In fact Guix Home itself started life in a third-party channel.
- Modding: Is there some feature of a program you use that you find annoying but can’t turn off? With channels, you can check out that code, disable the feature, and apply the patch to the package definition.
Creating a Channel #
Creating a channel involves several steps, including setting up a Git repository, writing package definitions in Guile modules, and making the channel available to Guix commands.
You will need Guix, GnuPG, and Git installed. You’ll also want server to host your channel, although local channels are possible too.
If you have decided that you’d like your channel to be private, then this is possible, but requires a few extra steps. We’ll cover both scenarios, starting with public channels.
Setting up GnuPG #
Before we start, you need to make sure that you’re set up to sign commits with GnuPG. There’s several guides out there that you can follow: This one by Fedora is well structured and should answer most of the questions you’d have.
Once you’ve got GnuPG set up and have generated a keypair, you’ll want to add your signing key to Git.
[user]
email = cdo@mutix.org
name = Christina O'Donnell
signingkey = 358B3178BAC1BA9B105C5CDA344C0AA8A41E474A
[commit]
gpgsign = true
gpgsign = true
tells Git to always sign commits without having to pass -S
.
This is optional but I find it to be a useful default.
Get Git signing key id #
Next you need to get your Git signing key. This is a different way of writing your GnuPG. It has the same length as your GnuPG key, but will be seen by Git when signing commits. One easy way to check this is to just sign a commit and then verify the commit to see the key ID used.
cdo@desktop ~$ gpg -K
/home/cdo/.local/secure/gnupg/pubring.kbx
-----------------------------------------
sec# rsa3072 2022-09-01 [C]
358B3178BAC1BA9B105C5CDA344C0AA8A41E474A
uid [ultimate] Christina O'Donnell (master) <cdo@mutix.org>
ssb> rsa2048 2022-09-05 [A] [expires: 2024-09-04]
ssb> rsa2048 2022-09-05 [S] [expires: 2024-09-04]
ssb> rsa4096 2022-09-20 [E] [expires: 2024-09-19]
ssb> rsa2048 2022-09-21 [S] [expires: 2024-09-20]
ssb> rsa2048 2022-09-21 [A] [expires: 2024-09-20]
cdo@desktop ~$ mkdir /tmp/test-repo; cd /tmp/test-repo
cdo@desktop /tmp/test-repo$ git init
Initialized empty Git repository in /tmp/test-repo/.git/
cdo@desktop /tmp/test-repo$ touch a
cdo@desktop /tmp/test-repo$ git add a
cdo@desktop /tmp/test-repo$ git commit -S 358B3178BAC1BA9B105C5CDA344C0AA8A41E474A -m "Test"
[master (root-commit) fd61ab6] Test
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
Here I have signed a test commit using the key 358B3178 in the gpg -K
output.
cdo@desktop /tmp/test-repo$ git verify-commit HEAD
gpg: Signature made Sun 03 Mar 2024 14:27:04 GMT
gpg: using RSA key D899861B5EAD198ACA062A9B9DA1DD5253A7AA4C
gpg: Good signature from "Christina O'Donnell (master) <cdo@mutix.org>" [ultimate]
However git verify-commit
sees a signed commit using a different key name.
It’s this name (D899861B…) that we want to use.
Setting Up a Git Repository #
To create a channel, you first need to establish a Git repository that will
home your Scheme files. These files provide the package definitions. To make
the repository a channel, initiate it as a Git repository, add your .scm
files, and make a signed commit.
cdo@desktop ~$ mkdir ~/src/cdo-guix-channel; cd ~/src/cdo-guix-channel
cdo@desktop ~/src/cdo-guix-channel$ git init
Then add .guix_channel
and .guix_authorizations
to the directory:
(channel
(version 0)
(url "https://git.mutix.org/cdo-guix-channel.git"))
(authorizations
(version 0)
(("D899 861B 5EAD 198A CA06 2A9B 9DA1 DD52 53A7 AA4C"
(name "cdo"))))
Here’s what my checkout had in it:
drwxr-xr-x 8 cdo cdo 4096 Mar 3 17:48 .git
-rw-r--r-- 1 cdo cdo 107 Mar 3 17:36 .guix-authorizations
-rw-r--r-- 1 cdo cdo 77 Mar 3 17:36 .guix-channel
Commit these with -S
to sign it.
cdo@desktop ~/src/cdo-guix-channel$ git add .
cdo@desktop ~/src/cdo-guix-channel$ git commit -S -m "Initial commit"
Next, create a keyring
branch based off master
. And add your public key to
the repo like so:
cdo@desktop ~/src/cdo-guix-channel$ git branch keyring master
cdo@desktop ~/src/cdo-guix-channel$ gpg -a --export cdo@mutix.org >cdo-358B3178.key
cdo@desktop ~/src/cdo-guix-channel$ git add .
cdo@desktop ~/src/cdo-guix-channel$ git commit -S -m "Add cdo-358B3178.key"
Then we create a remote repo using SSH. This will be different depending on the
software running on the server. Here’s how you’d do it for a bare git --daemon
:
cdo@desktop ~/src/cdo-guix-channel$ ssh git@mutix.org -- git init /srv/git/cdo-guix-channel.git
cdo@desktop ~/src/cdo-guix-channel$ git remote add origin git@git.mutix.org:cdo-guix-channel.git
cdo@desktop ~/src/cdo-guix-channel$ git push --all origin
Make a note of the first signed commit to use in the next step as the ‘channel introduction’ in the next step.
cdo@desktop ~/src/cdo-guix-channel$ git log
commit 8802797eb54c7bd83be7540446fe2efd6ffb1cb8 (HEAD -> keyring, origin/keyring)
Author: Christina O'Donnell <cdo@mutix.org>
Date: Sun Mar 3 17:49:24 2024 +0000
Add cdo key.
commit 45db57dc9add2f175b23ec72c222915baafe879b (origin/master, master)
Author: Christina O'Donnell <cdo@mutix.org>
Date: Sun Mar 3 17:36:57 2024 +0000
Initial commit
Now write a guix-channels.scm
on your machine to represent the channel:
;; ...
(define %cdo-local-channel
(channel
(name 'cdo)
(url "file:///home/cdo/src/cdo-guix-channel")
(introduction
(make-channel-introduction
"45db57dc9add2f175b23ec72c222915baafe879b"
(openpgp-fingerprint
"D899 861B 5EAD 198A CA06 2A9B 9DA1 DD52 53A7 AA4C")))))
(define %cdo-channel
(channel
(name 'cdo)
(url "git@git.mutix.org:cdo-guix-channel.git")
(introduction
(make-channel-introduction
"45db57dc9add2f175b23ec72c222915baafe879b"
(openpgp-fingerprint
"D899 861B 5EAD 198A CA06 2A9B 9DA1 DD52 53A7 AA4C")))))
(define-public %channels
(list ;; ... Other channels
%cdo-channel))
Next run guix pull
:
cdo@desktop ~/src/cdo-guix-channel$ guix pull -C guix-channels.scm
If this succeeds then you’re all done.
Troubleshooting #
If guix pull
fails, then you may have to check the channel introduction, to see if
you copied all the values correctly.
If you get an error like this:
guix pull: error: Git error: error authenticating: no auth sock variable
You’ll need to have either ssh-agent
or gpg-agent
running in SSH mode.
I found that adding the home service home-ssh-agent-service-type to my Guix Home
configuration and logging in again fixed it for me. If you’re not using Guix
Home, then you’ll want to start up ssh-agent
and ensure that you’ve added the
key that you use for connecting to your remote.
Otherwise you can test it locally by using a file://
URL, to diagnose the issue.
Writing Package Definitions #
Once your Git repository is set up, it’s time to write package
definitions. This can be accomplished by creating Guile modules that
export the packages you want to add to your channel. It’s important to
note that the package definitions should be assigned to an exported
variable name using define-public
. This assigns the package to a
variable so it can be referenced, even as a dependency of other
packages.
It’s common practice to create your own top level directory where all your files
would sit. For example, all my packages are under a cdo
directory:
cdo/packages.scm
cdo/services.scm
cdo/config/channels.scm
cdo/config/desktop.scm
cdo/config/home.scm
cdo/config/system-common.scm
cdo/config/vps.scm
Local File URL for Package Channel #
As mentioned above, if you’re working on Guix packages on only one system, you
can use a local file URL (file://
) for a package channel. This is useful when
developing on/using a channel.
What’s Next? #
Congratulations, you are now a proud owner of your very own Guix channel! A corner of the web to stash away your personal scripts and mods. Whether you’ve chosen to keep it private or share it with the world, you can now write packages in the confidence that if they work now, they’ll still work in 20 years time.
Recap #
We’ve discussed what a channel is, and what you can use it for. Then we used
GnuPG and Git to set up and sign the repo. Then we touched breifly on how you
can structure your guix channel. Finally we noted that you can set yourself up
to pull from file://
URL’s for development purposes.
Happy hacking!