Skip to content

Commit acf3de8

Browse files
authored
nixos/guix: add declarative substituters option (#353518)
2 parents 8452b3e + 7095e0f commit acf3de8

File tree

3 files changed

+78
-13
lines changed

3 files changed

+78
-13
lines changed

nixos/doc/manual/release-notes/rl-2411.section.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,11 @@
575575

576576
- `/share/vim-plugins` now only gets linked if `programs.vim.enable` is enabled
577577

578+
- The `services.guix` module now manages trusted substitute servers
579+
declaratively. Instead of `guix archive --authorize`, list keys with
580+
`services.guix.substituters.authorizedKeys`. Default substitute servers can be
581+
set via `services.guix.substituters.urls`.
582+
578583
- The `tracy` package no longer works on X11, since it's moved to Wayland
579584
support, which is the intended default behavior by Tracy maintainers.
580585
X11 users have to switch to the new package `tracy-x11`.

nixos/modules/services/misc/guix/default.nix

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ let
4646
GUIX_LOCPATH = "${cfg.stateDir}/guix/profiles/per-user/root/guix-profile/lib/locale";
4747
LC_ALL = "C.UTF-8";
4848
};
49+
50+
# Currently, this is just done the lazy way with the official Guix script. A
51+
# more "formal" way would be creating our own Guix script to handle and
52+
# generate the ACL file ourselves.
53+
aclFile = pkgs.runCommandLocal "guix-acl" { } ''
54+
export GUIX_CONFIGURATION_DIRECTORY=./
55+
for official_server_keys in ${lib.concatStringsSep " " cfg.substituters.authorizedKeys}; do
56+
${lib.getExe' cfg.package "guix"} archive --authorize < "$official_server_keys"
57+
done
58+
install -Dm0600 ./acl "$out"
59+
'';
4960
in
5061
{
5162
meta.maintainers = with lib.maintainers; [ foo-dogsquared ];
@@ -118,6 +129,57 @@ in
118129
example = "/gnu/var";
119130
};
120131

132+
substituters = {
133+
urls = lib.mkOption {
134+
type = with lib.types; listOf str;
135+
default = [
136+
"https://ci.guix.gnu.org"
137+
"https://bordeaux.guix.gnu.org"
138+
"https://berlin.guix.gnu.org"
139+
];
140+
example = lib.literalExpression ''
141+
options.services.guix.substituters.urls.default ++ [
142+
"https://guix.example.com"
143+
"https://guix.example.org"
144+
]
145+
'';
146+
description = ''
147+
A list of substitute servers' URLs for the Guix daemon to download
148+
substitutes from.
149+
'';
150+
};
151+
152+
authorizedKeys = lib.mkOption {
153+
type = with lib.types; listOf path;
154+
default = [
155+
"${cfg.package}/share/guix/ci.guix.gnu.org.pub"
156+
"${cfg.package}/share/guix/bordeaux.guix.gnu.org.pub"
157+
"${cfg.package}/share/guix/berlin.guix.gnu.org.pub"
158+
];
159+
defaultText = ''
160+
The packaged signing keys from {option}`services.guix.package`.
161+
'';
162+
example = lib.literalExpression ''
163+
options.services.guix.substituters.authorizedKeys.default ++ [
164+
(builtins.fetchurl {
165+
url = "https://guix.example.com/signing-key.pub";
166+
})
167+
168+
(builtins.fetchurl {
169+
url = "https://guix.example.org/static/signing-key.pub";
170+
})
171+
]
172+
'';
173+
description = ''
174+
A list of signing keys for each substitute server to be authorized as
175+
a source of substitutes. Without this, the listed substitute servers
176+
from {option}`services.guix.substituters.urls` would be ignored [with
177+
some
178+
exceptions](https://guix.gnu.org/manual/en/html_node/Substitute-Authentication.html).
179+
'';
180+
};
181+
};
182+
121183
publish = {
122184
enable = mkEnableOption "substitute server for your Guix store directory";
123185

@@ -215,6 +277,8 @@ in
215277
script = ''
216278
${lib.getExe' package "guix-daemon"} \
217279
--build-users-group=${cfg.group} \
280+
${lib.optionalString (cfg.substituters.urls != [ ])
281+
"--substitute-urls='${lib.concatStringsSep " " cfg.substituters.urls}'"} \
218282
${lib.escapeShellArgs cfg.extraArgs}
219283
'';
220284
serviceConfig = {
@@ -254,11 +318,7 @@ in
254318

255319
# Make transferring files from one store to another easier with the usual
256320
# case being of most substitutes from the official Guix CI instance.
257-
system.activationScripts.guix-authorize-keys = ''
258-
for official_server_keys in ${package}/share/guix/*.pub; do
259-
${lib.getExe' package "guix"} archive --authorize < $official_server_keys
260-
done
261-
'';
321+
environment.etc."guix/acl".source = aclFile;
262322

263323
# Link the usual Guix profiles to the home directory. This is useful in
264324
# ephemeral setups where only certain part of the filesystem is
@@ -270,8 +330,8 @@ in
270330
in ''
271331
[ -d "${userProfile}" ] && ln -sfn "${userProfile}" "${location}"
272332
'';
273-
linkProfileToPath = acc: profile: location: let
274-
in acc + (linkProfile profile location);
333+
linkProfileToPath = acc: profile: location:
334+
acc + (linkProfile profile location);
275335

276336
# This should contain export-only Guix user profiles. The rest of it is
277337
# handled manually in the activation script.
@@ -387,7 +447,7 @@ in
387447
Type = "oneshot";
388448

389449
PrivateDevices = true;
390-
PrivateNetworks = true;
450+
PrivateNetwork = true;
391451
ProtectControlGroups = true;
392452
ProtectHostname = true;
393453
ProtectKernelTunables = true;

nixos/tests/guix/publish.nix

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ in {
4747
services.guix = {
4848
enable = true;
4949

50-
extraArgs = [
51-
# Force to only get all substitutes from the local server. We don't
52-
# have anything in the Guix store directory and we cannot get
53-
# anything from the official substitute servers anyways.
54-
"--substitute-urls='http://server.local:${toString publishPort}'"
50+
# Force to only get all substitutes from the local server. We don't
51+
# have anything in the Guix store directory and we cannot get
52+
# anything from the official substitute servers anyways.
53+
substituters.urls = [ "http://server.local:${toString publishPort}" ];
5554

55+
extraArgs = [
5656
# Enable autodiscovery of the substitute servers in the local
5757
# network. This machine shouldn't need to import the signing key from
5858
# the substitute server since it is automatically done anyways.

0 commit comments

Comments
 (0)