nixos/system: make switch-to-configuration script pure.

Fixes #28443

Fixed few invocations to `systemctl` to have an absolute path. Additionally add
LOCALE_ARCHIVE so that perl stops spewing warning messages.

Changed files
+36 -4
nixos
modules
tests
+10 -3
nixos/modules/system/activation/switch-to-configuration.pl
···
my $action = shift @ARGV;
+
if ("@localeArchive@" ne "") {
+
$ENV{LOCALE_ARCHIVE} = "@localeArchive@";
+
}
+
if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) {
print STDERR <<EOF;
Usage: $0 [switch|boot|test]
···
sub getActiveUnits {
# FIXME: use D-Bus or whatever to query this, since parsing the
# output of list-units is likely to break.
-
my $lines = `LANG= systemctl list-units --full --no-legend`;
+
# Use current version of systemctl binary before daemon is reexeced.
+
my $lines = `LANG= /run/current-system/sw/bin/systemctl list-units --full --no-legend`;
my $res = {};
foreach my $line (split '\n', $lines) {
chomp $line;
···
sub pathToUnitName {
my ($path) = @_;
-
open my $cmd, "-|", "@systemd@/bin/systemd-escape", "--suffix=mount", "-p", $path
+
# Use current version of systemctl binary before daemon is reexeced.
+
open my $cmd, "-|", "/run/current-system/sw/bin/systemd-escape", "--suffix=mount", "-p", $path
or die "Unable to escape $path!\n";
my $escaped = join "", <$cmd>;
chomp $escaped;
···
if (scalar (keys %unitsToStop) > 0) {
print STDERR "stopping the following units: ", join(", ", @unitsToStopFiltered), "\n"
if scalar @unitsToStopFiltered;
-
system("systemctl", "stop", "--", sort(keys %unitsToStop)); # FIXME: ignore errors?
+
# Use current version of systemctl binary before daemon is reexeced.
+
system("/run/current-system/sw/bin/systemctl", "stop", "--", sort(keys %unitsToStop)); # FIXME: ignore errors?
}
print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
+1 -1
nixos/modules/system/activation/top-level.nix
···
cloner false config.nesting.children
++ cloner true config.nesting.clone;
-
systemBuilder =
let
kernelPath = "${config.boot.kernelPackages.kernel}/" +
···
done
mkdir $out/bin
+
export localeArchive="${config.i18n.glibcLocales}/lib/locale/locale-archive"
substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration
chmod +x $out/bin/switch-to-configuration
+25
nixos/tests/switch-test.nix
···
+
# Test configuration switching.
+
+
import ./make-test.nix ({ pkgs, ...} : {
+
name = "switch-test";
+
meta = with pkgs.stdenv.lib.maintainers; {
+
maintainers = [ gleber ];
+
};
+
+
nodes = {
+
machine = { config, lib, pkgs, ... }: {
+
users.mutableUsers = false;
+
};
+
other = { config, lib, pkgs, ... }: {
+
users.mutableUsers = true;
+
};
+
};
+
+
testScript = {nodes, ...}: let
+
originalSystem = nodes.machine.config.system.build.toplevel;
+
otherSystem = nodes.other.config.system.build.toplevel;
+
in ''
+
$machine->succeed("env -i ${originalSystem}/bin/switch-to-configuration test | tee /dev/stderr");
+
$machine->succeed("env -i ${otherSystem}/bin/switch-to-configuration test | tee /dev/stderr");
+
'';
+
})