1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-12-04 08:01:02 +01:00
home-manager/tests/integration/nixos/legacy-profile-management.nix
Robert Helgesson de448dcb57
home-manager: avoid profile management during activation
This commit deprecates profile management from the activation script.
The profile management is instead the responsibility of the driving
software, for example, the `home-manager` tool in the case of
standalone installs.

The legacy behavior is still available for backwards compatibility but
may be removed in the future.

The new behavior resolves (or moves us closer to resolving) a number
of long standing open issues:

- `home-manager switch --rollback`, which performs a rollback to the
  previous Home Manager generation before activating. While it was
  previously possible to accomplish this by activating an old
  generation, it did always create a new profile generation.

  This option has been implemented as part of this commit.

- `home-manager switch --specialisation NAME`, which switches to the
  named specialisation. While it was previously possible to accomplish
  this by manually running the specialisation activate script, it did
  always create a new profile generation.

  This option has been implemented as part of this commit.

- `home-manager switch --test`, which activates the configuration but
  does not create a new profile generation.

  This option has _not_ been implemented here since it relies on the
  current configuration being activated on login, which we do not
  currently do.

- When using the "Home Manager as a NixOS module" installation method
  we previously created an odd `home-manager` per-user "shadow
  profile" for the user. This is no longer necessary.

  This has been implemented as part of this commit.

Fixes #3450
2025-07-22 11:00:18 +02:00

111 lines
3.8 KiB
Nix

{ 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}"
'';
}