nixpkgs/nixos/modules/system/activation/switchable-system.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

87 lines
3.2 KiB
Nix
Raw Normal View History

{ config, lib, pkgs, ... }:
let
perlWrapped = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]);
in
{
options.system.switch = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
nixos: switch to `switch-to-configuration-ng` by default The Rust `switch-to-configuration-ng` rewrite was carefully written to be compatible with the original Perl script, has been checked against NixOS VM tests, and has been available on an opt‐in basis for testing for the 24.05 release cycle. The next step towards replacing the Perl script entirely is to switch it on by default so that we can get real‐world testing from a much greater number of users. Maintaining two implementations in parallel is becoming a burden; we are having to adjust the systemd service activation behaviour slightly to fix a long‐standing bug, and backporting the changes to the Perl script is an unpleasant process. We will do it anyway to ensure that the Rust and Perl implementations keep parity with each other throughout the 24.11 release cycle, but we think the time has come to flip the switch. Taking this step now will give us two to three months to test this in the wild before the 24.11 release and gain confidence that there are no regressions. If any non‐trivial problems arise before the final release, we will revert to the Perl implementation by default. Doing this switch ASAP will help to disentangle any problems that might arise from the Rust implementation from problems that arise from the systemd service activation changes, or the upcoming switch to using systemd in stage 1 by default. The main concern that was raised about replacing the Perl script in the PR that added `switch-to-configuration-ng` was that it is currently possible to run NixOS on systems that cannot natively host a Rust compiler. This does not apply to any platforms that have official support from NixOS, and as far as I know we do not know of any such systems with users that are not cross‐compiling anyway. My understanding is that these systems are already broken by default anyway, as `systemd.shutdownRamfs.enable` is on by default and uses `make-initrd-ng`, which is also written in Rust. Switching the default while keeping the Perl implementation around will give us at least an entire release cycle to find out if there are any users that will be affected by this and decide what to do about it if so. There is currently one known inconsistency between the Perl and Rust implementations, as documented in <https://github.com/NixOS/nixpkgs/issues/312297>; the Rust implementation has more accurate handling of failed systemd units. We slightly adjust the semantics of `system.switch.enable{,Ng}` to not conflict with each other, so that `system.switch.enableNg` is on by default, but turning off `system.switch.enable` still results in no `switch-to-configuration` implementation being used. This won’t break the configuration of anyone who already opted in to `system.switch.enableNg` and is probably how the option should have worked to begin with.
2024-09-05 05:47:55 +00:00
description = ''
Whether to include the capability to switch configurations.
Disabling this makes the system unable to be reconfigured via `nixos-rebuild`.
This is good for image based appliances where updates are handled
outside the image. Reducing features makes the image lighter and
slightly more secure.
'';
};
enableNg = lib.mkOption {
type = lib.types.bool;
nixos: switch to `switch-to-configuration-ng` by default The Rust `switch-to-configuration-ng` rewrite was carefully written to be compatible with the original Perl script, has been checked against NixOS VM tests, and has been available on an opt‐in basis for testing for the 24.05 release cycle. The next step towards replacing the Perl script entirely is to switch it on by default so that we can get real‐world testing from a much greater number of users. Maintaining two implementations in parallel is becoming a burden; we are having to adjust the systemd service activation behaviour slightly to fix a long‐standing bug, and backporting the changes to the Perl script is an unpleasant process. We will do it anyway to ensure that the Rust and Perl implementations keep parity with each other throughout the 24.11 release cycle, but we think the time has come to flip the switch. Taking this step now will give us two to three months to test this in the wild before the 24.11 release and gain confidence that there are no regressions. If any non‐trivial problems arise before the final release, we will revert to the Perl implementation by default. Doing this switch ASAP will help to disentangle any problems that might arise from the Rust implementation from problems that arise from the systemd service activation changes, or the upcoming switch to using systemd in stage 1 by default. The main concern that was raised about replacing the Perl script in the PR that added `switch-to-configuration-ng` was that it is currently possible to run NixOS on systems that cannot natively host a Rust compiler. This does not apply to any platforms that have official support from NixOS, and as far as I know we do not know of any such systems with users that are not cross‐compiling anyway. My understanding is that these systems are already broken by default anyway, as `systemd.shutdownRamfs.enable` is on by default and uses `make-initrd-ng`, which is also written in Rust. Switching the default while keeping the Perl implementation around will give us at least an entire release cycle to find out if there are any users that will be affected by this and decide what to do about it if so. There is currently one known inconsistency between the Perl and Rust implementations, as documented in <https://github.com/NixOS/nixpkgs/issues/312297>; the Rust implementation has more accurate handling of failed systemd units. We slightly adjust the semantics of `system.switch.enable{,Ng}` to not conflict with each other, so that `system.switch.enableNg` is on by default, but turning off `system.switch.enable` still results in no `switch-to-configuration` implementation being used. This won’t break the configuration of anyone who already opted in to `system.switch.enableNg` and is probably how the option should have worked to begin with.
2024-09-05 05:47:55 +00:00
default = config.system.switch.enable;
defaultText = lib.literalExpression "config.system.switch.enable";
description = ''
Whether to use `switch-to-configuration-ng`, the Rust-based
re-implementation of the original Perl `switch-to-configuration`.
'';
};
};
config = lib.mkMerge [
nixos: switch to `switch-to-configuration-ng` by default The Rust `switch-to-configuration-ng` rewrite was carefully written to be compatible with the original Perl script, has been checked against NixOS VM tests, and has been available on an opt‐in basis for testing for the 24.05 release cycle. The next step towards replacing the Perl script entirely is to switch it on by default so that we can get real‐world testing from a much greater number of users. Maintaining two implementations in parallel is becoming a burden; we are having to adjust the systemd service activation behaviour slightly to fix a long‐standing bug, and backporting the changes to the Perl script is an unpleasant process. We will do it anyway to ensure that the Rust and Perl implementations keep parity with each other throughout the 24.11 release cycle, but we think the time has come to flip the switch. Taking this step now will give us two to three months to test this in the wild before the 24.11 release and gain confidence that there are no regressions. If any non‐trivial problems arise before the final release, we will revert to the Perl implementation by default. Doing this switch ASAP will help to disentangle any problems that might arise from the Rust implementation from problems that arise from the systemd service activation changes, or the upcoming switch to using systemd in stage 1 by default. The main concern that was raised about replacing the Perl script in the PR that added `switch-to-configuration-ng` was that it is currently possible to run NixOS on systems that cannot natively host a Rust compiler. This does not apply to any platforms that have official support from NixOS, and as far as I know we do not know of any such systems with users that are not cross‐compiling anyway. My understanding is that these systems are already broken by default anyway, as `systemd.shutdownRamfs.enable` is on by default and uses `make-initrd-ng`, which is also written in Rust. Switching the default while keeping the Perl implementation around will give us at least an entire release cycle to find out if there are any users that will be affected by this and decide what to do about it if so. There is currently one known inconsistency between the Perl and Rust implementations, as documented in <https://github.com/NixOS/nixpkgs/issues/312297>; the Rust implementation has more accurate handling of failed systemd units. We slightly adjust the semantics of `system.switch.enable{,Ng}` to not conflict with each other, so that `system.switch.enableNg` is on by default, but turning off `system.switch.enable` still results in no `switch-to-configuration` implementation being used. This won’t break the configuration of anyone who already opted in to `system.switch.enableNg` and is probably how the option should have worked to begin with.
2024-09-05 05:47:55 +00:00
(lib.mkIf (config.system.switch.enable && !config.system.switch.enableNg) {
system.activatableSystemBuilderCommands = ''
mkdir $out/bin
substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \
--subst-var out \
--subst-var-by toplevel ''${!toplevelVar} \
--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 localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \
--subst-var-by perl "${perlWrapped}" \
--subst-var-by shell "${pkgs.bash}/bin/sh" \
--subst-var-by su "${pkgs.shadow.su}/bin/su" \
--subst-var-by systemd "${config.systemd.package}" \
--subst-var-by utillinux "${pkgs.util-linux}" \
;
chmod +x $out/bin/switch-to-configuration
${lib.optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) ''
if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then
echo "switch-to-configuration syntax is not valid:"
echo "$output"
exit 1
fi
''}
'';
})
(lib.mkIf config.system.switch.enableNg {
# Use a subshell so we can source makeWrapper's setup hook without
# affecting the rest of activatableSystemBuilderCommands.
system.activatableSystemBuilderCommands = ''
(
source ${pkgs.buildPackages.makeWrapper}/nix-support/setup-hook
mkdir $out/bin
ln -sf ${lib.getExe pkgs.switch-to-configuration-ng} $out/bin/switch-to-configuration
wrapProgram $out/bin/switch-to-configuration \
--set OUT $out \
--set TOPLEVEL ''${!toplevelVar} \
--set DISTRO_ID ${lib.escapeShellArg config.system.nixos.distroId} \
--set INSTALL_BOOTLOADER ${lib.escapeShellArg config.system.build.installBootLoader} \
--set LOCALE_ARCHIVE ${config.i18n.glibcLocales}/lib/locale/locale-archive \
--set SYSTEMD ${config.systemd.package}
)
'';
})
];
}