{ pkgs, ... }: { name = "nixos-legacy-profile-management"; meta.maintainers = [ pkgs.lib.maintainers.rycee ]; nodes.machine = { imports = [ # Make the nixpkgs channel available. "${pkgs.path}/nixos/modules/installer/cd-dvd/channel.nix" # Import the HM NixOS module. ../../../nixos ]; system.stateVersion = "24.11"; users.users.alice = { isNormalUser = true; }; specialisation = { legacy.configuration = { home-manager = { # Force legacy profile management. enableLegacyProfileManagement = true; users.alice = { home.stateVersion = "24.11"; home.file.test.text = "testfile legacy"; }; }; }; modern.configuration = { home-manager = { # Assert that we expect the option to default to false. enableLegacyProfileManagement = pkgs.lib.mkOptionDefault false; users.alice = { home.stateVersion = "24.11"; home.file.test.text = "testfile modern"; }; }; }; }; }; testScript = { nodes, ... }: let legacy = "${nodes.machine.system.build.toplevel}/specialisation/legacy"; modern = "${nodes.machine.system.build.toplevel}/specialisation/modern"; in '' start_all() machine.wait_for_unit("multi-user.target") machine.succeed("${legacy}/bin/switch-to-configuration test >&2") machine.wait_for_console_text("Finished Home Manager environment for alice.") with subtest("Home Manager file"): # The file should be linked with the expected content. path = "/home/alice/test" machine.succeed(f"test -L {path}") actual = machine.succeed(f"cat {path}") expected = "testfile legacy" assert actual == expected, f"expected {path} to contain {expected}, but got {actual}" with subtest("GC root and profile"): # There should be a GC root and Home Manager profile and they should point # to the same path in the Nix store. gcroot = "/home/alice/.local/state/home-manager/gcroots/current-home" gcrootTarget = machine.succeed(f"readlink {gcroot}") profile = "/home/alice/.local/state/nix/profiles" profileTarget = machine.succeed(f"readlink {profile}/home-manager") profile1Target = machine.succeed(f"readlink {profile}/{profileTarget}") assert gcrootTarget == profile1Target, \ f"expected GC root and profile to point to same, but pointed to {gcrootTarget} and {profile1Target}" with subtest("Switch to new profile management"): machine.succeed("${modern}/bin/switch-to-configuration test >&2") machine.wait_for_console_text("Finished Home Manager environment for alice.") # The file should be linked with the expected content. path = "/home/alice/test" machine.succeed(f"test -L {path}") actual = machine.succeed(f"cat {path}") expected = "testfile modern" assert actual == expected, f"expected {path} to contain {expected}, but got {actual}" with subtest("Switch back to old profile management"): machine.succeed("${legacy}/bin/switch-to-configuration test >&2") machine.wait_for_console_text("Finished Home Manager environment for alice.") # The file should be linked with the expected content. path = "/home/alice/test" machine.succeed(f"test -L {path}") actual = machine.succeed(f"cat {path}") expected = "testfile legacy" assert actual == expected, f"expected {path} to contain {expected}, but got {actual}" ''; }