Skip to content

Commit

Permalink
nixos/activation: improve preSwitchChecks
Browse files Browse the repository at this point in the history
A couple of improvements:

1. Avoid the generally discouraged apply argument to options, as it has
   quite weird semantics
2. Avoid issues when a user calls a preSwitchCheck `script`, which
   would've been silently overridden by the existing implementation.
   Reliance on a special attribute name like that is bound to lead to a
   very-hard-to-debug problem for someone at some point
3. Use writeShellApplication so that the preSwitchChecks are checked by
   shellcheck and and so that they run with basic bash guardrails
4. Fix shellcheck issue (testing the value of $?)
5. Add a positive preSwitchCheck to the nixos test, to make sure that
   that works as intended
  • Loading branch information
r-vdp committed Jan 23, 2025
1 parent 7db6d6c commit c120205
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 25 deletions.
50 changes: 28 additions & 22 deletions nixos/modules/system/activation/pre-switch-check.nix
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
{ lib, pkgs, ... }:
{
lib,
config,
pkgs,
...
}:
let
preSwitchCheckScript =
set:
lib.concatLines (
lib.mapAttrsToList (name: text: ''
# pre-switch check ${name}
(
${text}
)
if [[ $? != 0 ]]; then
echo "Pre-switch check '${name}' failed"
exit 1
fi
'') set
);
preSwitchCheckScript = lib.concatLines (
lib.mapAttrsToList (name: text: ''
# pre-switch check ${name}
if ! (
${text}
); then
echo "Pre-switch check '${name}' failed"
exit 1
fi
'') config.system.preSwitchChecks
);
in
{
options.system.preSwitchChecksScript = lib.mkOption {
internal = true;
readOnly = true;
default = lib.getExe (
pkgs.writeShellApplication {
name = "pre-switch-checks";
text = preSwitchCheckScript;
}
);
};

options.system.preSwitchChecks = lib.mkOption {
default = { };
example = lib.literalExpression ''
Expand All @@ -33,12 +46,5 @@ in
'';

type = lib.types.attrsOf lib.types.str;

apply =
set:
set
// {
script = pkgs.writeShellScript "pre-switch-checks" (preSwitchCheckScript set);
};
};
}
4 changes: 2 additions & 2 deletions nixos/modules/system/activation/switchable-system.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ in
--subst-var-by coreutils "${pkgs.coreutils}" \
--subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \
--subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \
--subst-var-by preSwitchCheck ${lib.escapeShellArg config.system.preSwitchChecks.script} \
--subst-var-by preSwitchCheck ${lib.escapeShellArg config.system.preSwitchChecksScript} \
--subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \
--subst-var-by perl "${perlWrapped}" \
--subst-var-by shell "${pkgs.bash}/bin/sh" \
Expand Down Expand Up @@ -94,7 +94,7 @@ in
--set TOPLEVEL ''${!toplevelVar} \
--set DISTRO_ID ${lib.escapeShellArg config.system.nixos.distroId} \
--set INSTALL_BOOTLOADER ${lib.escapeShellArg config.system.build.installBootLoader} \
--set PRE_SWITCH_CHECK ${lib.escapeShellArg config.system.preSwitchChecks.script} \
--set PRE_SWITCH_CHECK ${lib.escapeShellArg config.system.preSwitchChecksScript} \
--set LOCALE_ARCHIVE ${config.i18n.glibcLocales}/lib/locale/locale-archive \
--set SYSTEMD ${config.systemd.package}
)
Expand Down
2 changes: 1 addition & 1 deletion nixos/modules/system/activation/top-level.nix
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ in
perl = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]);
# End if legacy environment variables

preSwitchCheck = config.system.preSwitchChecks.script;
preSwitchCheck = config.system.preSwitchChecksScript;

# Not actually used in the builder. `passedChecks` is just here to create
# the build dependencies. Checks are similar to build dependencies in the
Expand Down
4 changes: 4 additions & 0 deletions nixos/tests/switch-test.nix
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,10 @@ in {
other = {
system.switch.enable = true;
users.mutableUsers = true;
system.preSwitchChecks.succeeds = ''
echo this will succeed
true
'';
specialisation.failingCheck.configuration.system.preSwitchChecks.failEveryTime = ''
echo this will fail
false
Expand Down

0 comments on commit c120205

Please sign in to comment.