home-manager icon indicating copy to clipboard operation
home-manager copied to clipboard

Flakes: per-system configuration

Open wmertens opened this issue 3 years ago • 31 comments

With flakes, the system has to be embedded in the pkgs selection. Instead, it would be easier to reuse configurations across platforms by having a setup like apps and packages, where the second level is the system.

Then pkgs can be optional.

So a config would go from

    {
      homeConfigurations = {
        ${username} = home-manager.lib.homeManagerConfiguration rec {
          pkgs = nixpkgs.legacyPackages.${system};
          modules = [
            # ...
          ];
        };
      };
    };

to

    flake-utils.lib.eachDefaultSystem (system: {
      homeConfigurations = {
        ${username} = home-manager.lib.homeManagerConfiguration rec {
          modules = [
            # ...
          ];
        };
      };
    })

I suppose both configurations could be supported by checking if the current system is an attribute in the home-manager script

wmertens avatar Jul 07 '22 18:07 wmertens

I also want this feature!

sepiabrown avatar Jul 16 '22 21:07 sepiabrown

I also ran into this inconvenience. This part of my config became a bit strange due to this restriction: https://github.com/bobvanderlinden/nixos-config/blob/bdfd8d94def9dc36166ef5725589bf3d7ae2d233/flake.nix#L38-L46

It now also isn't possible to share this home-manager configuration with OSX.

bobvanderlinden avatar Sep 05 '22 17:09 bobvanderlinden

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/improving-a-flake-nix-config-that-configures-home-manager/23389/2

nixos-discourse avatar Nov 21 '22 22:11 nixos-discourse

Still relevant.

ambroisie avatar Nov 22 '22 10:11 ambroisie

Okay, so I'm new to Nix, but I may have a solution.

When I ran home-manager switch --flake .#scott, with no exported homeConfigurations.scott, I got this output...

error: flake 'git+file:///home/scott/dotfiles' does not provide attribute 'packages.x86_64-linux.homeConfigurations."scott".activationPackage', 'legacyPackages.x86_64-linux.homeConfigurations."scott".activationPackage' or 'homeConfigurations."scott".activationPackage'.

So, I tried to export homeConfigurations.scott as packages.${system}.homeConfigurations.scott instead, and this does appear to work. I don't think this behaviour comes from home manager, but instead from the Nix CLI, when nix build is invoked by home manager which is somewhat documented.

The work around explained by @nixos-discourse will also work, with homeConfigurations."${system}-scott, although a little uglier.

It still might be an idea to consider support for homeConfigurations.${system}.scott, but this is up to the home manager contributors.

TL;DR: It appears that packages.${system}.homeConfigurations.scott will work.

scottwillmoore avatar Nov 29 '22 13:11 scottwillmoore

Meh, I do see it is a solution, but that shouldn't be a documented solution :sweat_smile: The suggestion from @wmertens still makes sense to me.

Especially new people shouldn't be placing home configuration into packages, as that adds to the already (sometimes) confusing Nix ecosystem.

bobvanderlinden avatar Nov 29 '22 15:11 bobvanderlinden

The current interface seems fairly consistent with the attributes for NixOS, the idea being that a nixosConfigurations.<name> is as specific as it gets; typically a specific host. nixosModules.<name> on the other hand can be reused in any configuration that needs it, including different cpu architectures, etc.

Perhaps for your use case, an attribute like homeModules.<name> makes more sense, considering that you seem to want to use it in more than one configuration? This way the flake schema remains consistent with that of NixOS.

roberth avatar Jan 16 '23 19:01 roberth

I think homeConfigurations is more like packages than nixosConfigurations. The reason each nixosConfiguration specifies system is that it is meant to run on specific hardware, whereas the point of hm is to make your home profile portable across hosts.

edrex avatar Mar 21 '23 01:03 edrex

Unfortunately, the workaround detailed by @scottwillmoore doesn't work in a flake-parts context, since the option expects values of type package:

error: A definition for option `perSystem.x86_64-linux.packages.homeConfigurations' is not of type `package'.

Update: perSystem.legacyPackages does pass. This is what I did (it is terrible): https://github.com/edrex/nixcfg/commit/26230ced1794c32f7e8a62fc7664ecb04a6afe94#diff-206b9ce276ab5971a2489d75eb1b12999d4bf3843b7988cbe8d687cfde61dea0

edrex avatar Mar 21 '23 01:03 edrex

The reason each nixosConfiguration specifies system is that it is meant to run on specific hardware, whereas the point of hm is to make your home profile portable across hosts.

homeConfigurations may also be specialised to specific hardware. For example, the HM config for my desktop has a number of differences compared to the config for my laptop, due to the difference in the number, size, resolution, and viewing distance of available monitors. The set of packages installed also varies between them, because they're used for different purposes.

Sharing configuration across homeConfigurations, and across a variety of systems, is already pretty trivial in a flake, for example I do something along the lines of:

{
  description = "Home Manager configuration of shados";

  inputs = {
    nixpkgs.url = "nixpkgs";
    home-manager = {
      url = github:nix-community/home-manager;
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { nixpkgs, home-manager, ... } @ inputs:
    let
      mkHomeConfig = machineModule: system: home-manager.lib.homeManagerConfiguration {
        pkgs = import nixpkgs {
          inherit system;
        };

        modules = [
          ./sharedConfig
          machineModule
        ];

        extraSpecialArgs = {
          inherit inputs system;
        };
      };
    in {
      homeConfigurations."shados@desktop" = mkHomeConfig ./machine/desktop.nix "x86_64-linux";
      homeConfigurations."shados@laptop" = mkHomeConfig ./machine/laptop.nix "x86_64-linux";
      homeConfigurations."shados@work" = mkHomeConfig ./machine/work.nix "x86_64-darwin";
      homeConfigurations."shados@arm-vm" = mkHomeConfig ./machine/arm-vm.nix "aarch64-linux";
    };
}

Anything truly portable lives in the ./sharedConfig module (or its imported modules), and per-device config lives in files under ./machine.

If your HM config is intended to be 100% portable and identical across machines, you could get something pretty close to what @wmertens originally wanted:

      homeConfigurations = with nixpkgs.lib; listToAttrs (flip map flake-utils.lib.defaultSystems
        (system: nameValuePair "${username}-${system}" home-manager.lib.homeManagerConfiguration {
          pkgs = import nixpkgs { inherit system; };
          modules = [
            # ...
          ];
        }));

And then build with home-manager switch --flake ~/.config/home-manager#username-x86_64-linux, and drop the --flake option on subsequent calls, as per usual.


If anything, I would say a better change would be for home-manager.lib.homeManagerConfiguration to explicitly take a system argument and a bare nixpkgs argument, instead of an instantiated pkgs. This would bring HM more in line with nixpkgs, and I think this would also make it easier to fix #2942 & #2954...

Shados avatar Jun 16 '23 01:06 Shados

Oh this was a pitfall. I was wondering why it was complaining

flake ... does not provide attribute 'packages.x86_64-linux.homeConfigurations." username".activationPackage', 'legacyPackages.x86_64-linux.homeConfigurations."username".activationPackage' or 'homeConfigurations."username".activationPackage'

because I didn't understand that the (standalone) home-manager acts like nixos-rebuild, but instead of picking the hostName from the nixosConfigurations, it picks the username from homeConfigurations.

So I have to home-manager switch --flake .#<username>-x86_64-linux to support multiple platforms, ahhh.

I don't understand why the system can't be read and used prior the flake resolve. That would make things easier, on system flakes as well.

martin-braun avatar Jul 17 '23 20:07 martin-braun

(...) because I didn't understand that the (standalone) home-manager acts like nixos-rebuild, but instead of picking the hostName from the nixosConfigurations, it picks the username from homeConfigurations.

So I have to home-manager switch --flake .#<username>-x86_64-linux to support multiple platforms, ahhh.

I don't understand why the system can't be read and used prior the flake resolve. That would make things easier, on system flakes as well.

home-manager switch (without any other arguments) works for me when I have <path.to.flake>#homeConfigurations."$USER@$(hostname)".activationPackage?

Maybe because it (my HM nix setup/repo) always imports all HM modules for all systems (read: any configured Linux user/combo) through a home.nix in root of repo, but I didn't think it has to be that way had.

A symlink is needed though to ~/.config/home-manager, pointing to config repo I'm pretty sure.

x10an14 avatar Jul 17 '23 23:07 x10an14

@x10an14 I couldn't figure out how to do that. For me, it will always try to find the configuration of the username and only the username. I've seen a lot of configs that follow the $USER@$(hostname) scheme, but I couldn't pin point the key to toggle this behavior, unless passing '.#'$USER@${hostname}.

My situation is probably different and that might be relevant, because my configuration is strictly separated. My HM profile is a single-user multi-host configuration that I want to resolve by hostname only, similarly how Nix is doing it for the system flakes in /etc/nixos/ on sudo nixos-rebuild switch.

I think my recent issue #4246 is a dub, so I will quote myself:

It would be nice if I could tell the home-server in my configuration to look for the hostname instead of username in homeConfigurations. I know I can use the --flake attribute with #<hostname> to get what I want, but it adds necessary tooling that I feel could be solved within the configuration itself.

Why would I want that? Since we can store user configurations in $HOME, it's reasonable to maintain single-user repositories (one user per repo) for multiple hosts, instead of the common case to have a per-user (multi user) repo for many hosts, which often puts everything together (incl. system configuration).

Imho, user and system should be separated, even user and another user (different persons) should be separated. So for me personally, it would make sense if home-manager switch looks for homeConfiguration."<hostName>" instead of homeConfiguration."<username>".

Or why not just looking for homeConfiguration."<username>@<hostName>", then homeConfiguration."<username>", then homeConfiguration."<hostName>", in that order to give much flexibility. As soon as a configuration is found, it will be used.

Lastly, I want to emphasize that I don't like any work-arounds that require more abstraction and complexity. I'm happy to learn Flakes in their purest form, I don't want to involve additional abstractions, I even keep myself from defining any functions to re-use (i.e. mkHomeConfiguration) to keep the declaration flow as simple as possible, since I'm still learning.

For now, I will just have to pass more arguments to home-server, but hopefully my opinion will matter in the slightest. Perhaps one will acknowledge it as valuable feedback of new-comers and their problems adapting Nix in general, but I'm still too inexperienced to give a fundamental opinion to be honest.

Thank you.

martin-braun avatar Jul 18 '23 05:07 martin-braun

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

  • If this is resolved, please consider closing it so that the maintainers know not to focus on this.
  • If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
If you are not the original author of the issue

  • If you are also experiencing this issue, please add details of your situation to help with the debugging process.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

stale[bot] avatar Oct 16 '23 22:10 stale[bot]

Still relevant.

ambroisie avatar Oct 17 '23 12:10 ambroisie

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317/4

nixos-discourse avatar Oct 22 '23 10:10 nixos-discourse

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

  • If this is resolved, please consider closing it so that the maintainers know not to focus on this.
  • If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
If you are not the original author of the issue

  • If you are also experiencing this issue, please add details of your situation to help with the debugging process.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

stale[bot] avatar Jan 21 '24 08:01 stale[bot]

Still relevant.

jzbor avatar Jan 21 '24 18:01 jzbor

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

  • If this is resolved, please consider closing it so that the maintainers know not to focus on this.
  • If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
If you are not the original author of the issue

  • If you are also experiencing this issue, please add details of your situation to help with the debugging process.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

stale[bot] avatar Apr 22 '24 03:04 stale[bot]

Still relevant.

zeorin avatar Apr 22 '24 07:04 zeorin