mirror of
https://github.com/SebastianWendel/nixpkgs.git
synced 2024-09-21 04:49:01 +02:00
Merge pull request #254993 from helsinki-systems/feat/stc-mount-improvements
nixos/switch-to-configuration: Mount improvements and a lot more test cases
This commit is contained in:
commit
cc55ef9d55
|
@ -21,8 +21,9 @@ If the action is `switch` or `test`, the currently running system is inspected
|
||||||
and the actions to switch to the new system are calculated. This process takes
|
and the actions to switch to the new system are calculated. This process takes
|
||||||
two data sources into account: `/etc/fstab` and the current systemd status.
|
two data sources into account: `/etc/fstab` and the current systemd status.
|
||||||
Mounts and swaps are read from `/etc/fstab` and the corresponding actions are
|
Mounts and swaps are read from `/etc/fstab` and the corresponding actions are
|
||||||
generated. If a new mount is added, for example, the proper `.mount` unit is
|
generated. If the options of a mount are modified, for example, the proper `.mount`
|
||||||
marked to be started. The current systemd state is inspected, the difference
|
unit is reloaded (or restarted if anything else changed and it's neither the root
|
||||||
|
mount or the nix store). The current systemd state is inspected, the difference
|
||||||
between the current system and the desired configuration is calculated and
|
between the current system and the desired configuration is calculated and
|
||||||
actions are generated to get to this state. There are a lot of nuances that can
|
actions are generated to get to this state. There are a lot of nuances that can
|
||||||
be controlled by the units which are explained here.
|
be controlled by the units which are explained here.
|
||||||
|
|
|
@ -74,7 +74,7 @@ if ("@localeArchive@" ne "") {
|
||||||
|
|
||||||
if (!defined($action) || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) {
|
if (!defined($action) || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) {
|
||||||
print STDERR <<"EOF";
|
print STDERR <<"EOF";
|
||||||
Usage: $0 [switch|boot|test]
|
Usage: $0 [switch|boot|test|dry-activate]
|
||||||
|
|
||||||
switch: make the configuration the boot default and activate now
|
switch: make the configuration the boot default and activate now
|
||||||
boot: make the configuration the boot default
|
boot: make the configuration the boot default
|
||||||
|
@ -661,10 +661,20 @@ foreach my $mount_point (keys(%{$cur_fss})) {
|
||||||
# Filesystem entry disappeared, so unmount it.
|
# Filesystem entry disappeared, so unmount it.
|
||||||
$units_to_stop{$unit} = 1;
|
$units_to_stop{$unit} = 1;
|
||||||
} elsif ($cur->{fsType} ne $new->{fsType} || $cur->{device} ne $new->{device}) {
|
} elsif ($cur->{fsType} ne $new->{fsType} || $cur->{device} ne $new->{device}) {
|
||||||
|
if ($mount_point eq '/' or $mount_point eq '/nix') {
|
||||||
|
if ($cur->{options} ne $new->{options}) {
|
||||||
|
# Mount options changed, so remount it.
|
||||||
|
$units_to_reload{$unit} = 1;
|
||||||
|
record_unit($reload_list_file, $unit);
|
||||||
|
} else {
|
||||||
|
# Don't unmount / or /nix if the device changed
|
||||||
|
$units_to_skip{$unit} = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
# Filesystem type or device changed, so unmount and mount it.
|
# Filesystem type or device changed, so unmount and mount it.
|
||||||
$units_to_stop{$unit} = 1;
|
$units_to_restart{$unit} = 1;
|
||||||
$units_to_start{$unit} = 1;
|
record_unit($restart_list_file, $unit);
|
||||||
record_unit($start_list_file, $unit);
|
}
|
||||||
} elsif ($cur->{options} ne $new->{options}) {
|
} elsif ($cur->{options} ne $new->{options}) {
|
||||||
# Mount options changes, so remount it.
|
# Mount options changes, so remount it.
|
||||||
$units_to_reload{$unit} = 1;
|
$units_to_reload{$unit} = 1;
|
||||||
|
|
|
@ -58,6 +58,37 @@ in {
|
||||||
'');
|
'');
|
||||||
|
|
||||||
specialisation = rec {
|
specialisation = rec {
|
||||||
|
brokenInitInterface.configuration.config.system.extraSystemBuilderCmds = ''
|
||||||
|
echo "systemd 0" > $out/init-interface-version
|
||||||
|
'';
|
||||||
|
|
||||||
|
modifiedSystemConf.configuration.systemd.extraConfig = ''
|
||||||
|
# Hello world!
|
||||||
|
'';
|
||||||
|
|
||||||
|
addedMount.configuration.virtualisation.fileSystems."/test" = {
|
||||||
|
device = "tmpfs";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
addedMountOptsModified.configuration = {
|
||||||
|
imports = [ addedMount.configuration ];
|
||||||
|
virtualisation.fileSystems."/test".options = [ "x-test" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
addedMountDevModified.configuration = {
|
||||||
|
imports = [ addedMountOptsModified.configuration ];
|
||||||
|
virtualisation.fileSystems."/test".device = lib.mkForce "ramfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
storeMountModified.configuration = {
|
||||||
|
virtualisation.fileSystems."/".device = lib.mkForce "auto";
|
||||||
|
};
|
||||||
|
|
||||||
|
swap.configuration.swapDevices = lib.mkVMOverride [
|
||||||
|
{ device = "/swapfile"; size = 1; }
|
||||||
|
];
|
||||||
|
|
||||||
simpleService.configuration = {
|
simpleService.configuration = {
|
||||||
systemd.services.test = {
|
systemd.services.test = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
@ -643,6 +674,97 @@ in {
|
||||||
|
|
||||||
# test and dry-activate actions are tested further down below
|
# test and dry-activate actions are tested further down below
|
||||||
|
|
||||||
|
# invalid action fails the script
|
||||||
|
switch_to_specialisation("${machine}", "", action="broken-action", fail=True)
|
||||||
|
# no action fails the script
|
||||||
|
assert "Usage:" in machine.fail("${machine}/bin/switch-to-configuration 2>&1")
|
||||||
|
|
||||||
|
with subtest("init interface version"):
|
||||||
|
# Do not try to switch to an invalid init interface version
|
||||||
|
assert "incompatible" in switch_to_specialisation("${machine}", "brokenInitInterface", fail=True)
|
||||||
|
|
||||||
|
with subtest("systemd restarts"):
|
||||||
|
# systemd is restarted when its system.conf changes
|
||||||
|
out = switch_to_specialisation("${machine}", "modifiedSystemConf")
|
||||||
|
assert_contains(out, "restarting systemd...")
|
||||||
|
|
||||||
|
with subtest("continuing from an aborted switch"):
|
||||||
|
# An aborted switch will write into a file what it tried to start
|
||||||
|
# and a second switch should continue from this
|
||||||
|
machine.succeed("echo dbus.service > /run/nixos/start-list")
|
||||||
|
out = switch_to_specialisation("${machine}", "modifiedSystemConf")
|
||||||
|
assert_contains(out, "starting the following units: dbus.service\n")
|
||||||
|
|
||||||
|
with subtest("fstab mounts"):
|
||||||
|
switch_to_specialisation("${machine}", "")
|
||||||
|
# add a mountpoint
|
||||||
|
out = switch_to_specialisation("${machine}", "addedMount")
|
||||||
|
assert_lacks(out, "stopping the following units:")
|
||||||
|
assert_lacks(out, "NOT restarting the following changed units:")
|
||||||
|
assert_lacks(out, "\nrestarting the following units:")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_contains(out, "the following new units were started: test.mount\n")
|
||||||
|
# modify the mountpoint's options
|
||||||
|
out = switch_to_specialisation("${machine}", "addedMountOptsModified")
|
||||||
|
assert_lacks(out, "stopping the following units:")
|
||||||
|
assert_lacks(out, "NOT restarting the following changed units:")
|
||||||
|
assert_contains(out, "reloading the following units: test.mount\n")
|
||||||
|
assert_lacks(out, "\nrestarting the following units:")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_lacks(out, "the following new units were started:")
|
||||||
|
# modify the device
|
||||||
|
out = switch_to_specialisation("${machine}", "addedMountDevModified")
|
||||||
|
assert_lacks(out, "stopping the following units:")
|
||||||
|
assert_lacks(out, "NOT restarting the following changed units:")
|
||||||
|
assert_lacks(out, "reloading the following units:")
|
||||||
|
assert_contains(out, "\nrestarting the following units: test.mount\n")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_lacks(out, "the following new units were started:")
|
||||||
|
# modify both
|
||||||
|
out = switch_to_specialisation("${machine}", "addedMount")
|
||||||
|
assert_lacks(out, "stopping the following units:")
|
||||||
|
assert_lacks(out, "NOT restarting the following changed units:")
|
||||||
|
assert_lacks(out, "reloading the following units:")
|
||||||
|
assert_contains(out, "\nrestarting the following units: test.mount\n")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_lacks(out, "the following new units were started:")
|
||||||
|
# remove the mount
|
||||||
|
out = switch_to_specialisation("${machine}", "")
|
||||||
|
assert_contains(out, "stopping the following units: test.mount\n")
|
||||||
|
assert_lacks(out, "NOT restarting the following changed units:")
|
||||||
|
assert_contains(out, "reloading the following units: dbus.service\n")
|
||||||
|
assert_lacks(out, "\nrestarting the following units:")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_lacks(out, "the following new units were started:")
|
||||||
|
# change something about the / mount
|
||||||
|
out = switch_to_specialisation("${machine}", "storeMountModified")
|
||||||
|
assert_lacks(out, "stopping the following units:")
|
||||||
|
assert_contains(out, "NOT restarting the following changed units: -.mount")
|
||||||
|
assert_contains(out, "reloading the following units: dbus.service\n")
|
||||||
|
assert_lacks(out, "\nrestarting the following units:")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_lacks(out, "the following new units were started:")
|
||||||
|
|
||||||
|
with subtest("swaps"):
|
||||||
|
switch_to_specialisation("${machine}", "")
|
||||||
|
# add a swap
|
||||||
|
out = switch_to_specialisation("${machine}", "swap")
|
||||||
|
assert_lacks(out, "stopping the following units:")
|
||||||
|
assert_lacks(out, "NOT restarting the following changed units:")
|
||||||
|
assert_contains(out, "reloading the following units: dbus.service\n")
|
||||||
|
assert_lacks(out, "\nrestarting the following units:")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_contains(out, "the following new units were started: swapfile.swap")
|
||||||
|
# remove it
|
||||||
|
out = switch_to_specialisation("${machine}", "")
|
||||||
|
assert_contains(out, "stopping swap device: /swapfile")
|
||||||
|
assert_lacks(out, "stopping the following units:")
|
||||||
|
assert_lacks(out, "NOT restarting the following changed units:")
|
||||||
|
assert_contains(out, "reloading the following units: dbus.service\n")
|
||||||
|
assert_lacks(out, "\nrestarting the following units:")
|
||||||
|
assert_lacks(out, "\nstarting the following units:")
|
||||||
|
assert_lacks(out, "the following new units were started:")
|
||||||
|
|
||||||
with subtest("services"):
|
with subtest("services"):
|
||||||
switch_to_specialisation("${machine}", "")
|
switch_to_specialisation("${machine}", "")
|
||||||
# Nothing happens when nothing is changed
|
# Nothing happens when nothing is changed
|
||||||
|
|
Loading…
Reference in a new issue