Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flakes: per-system configuration #3075

Open
wmertens opened this issue Jul 7, 2022 · 28 comments
Open

Flakes: per-system configuration #3075

wmertens opened this issue Jul 7, 2022 · 28 comments
Assignees

Comments

@wmertens
Copy link
Contributor

wmertens commented Jul 7, 2022

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

@sepiabrown
Copy link
Contributor

I also want this feature!

@bobvanderlinden
Copy link

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.

@nixos-discourse
Copy link

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

@ambroisie
Copy link
Contributor

Still relevant.

@scottwillmoore
Copy link

scottwillmoore commented Nov 29, 2022

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.

@bobvanderlinden
Copy link

Meh, I do see it is a solution, but that shouldn't be a documented solution 😅 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.

@roberth
Copy link
Contributor

roberth commented Jan 16, 2023

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.

@edrex
Copy link

edrex commented Mar 21, 2023

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
Copy link

edrex commented Mar 21, 2023

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): edrex/nixcfg@26230ce#diff-206b9ce276ab5971a2489d75eb1b12999d4bf3843b7988cbe8d687cfde61dea0

@Shados
Copy link

Shados commented Jun 16, 2023

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...

@martin-braun
Copy link

martin-braun commented Jul 17, 2023

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.

@x10an14
Copy link
Contributor

x10an14 commented Jul 17, 2023

(...)
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.

@martin-braun
Copy link

martin-braun commented Jul 18, 2023

@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.

@stale
Copy link

stale bot commented Oct 16, 2023

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 stale bot added the status: stale label Oct 16, 2023
@ambroisie
Copy link
Contributor

Still relevant.

@stale stale bot removed the status: stale label Oct 17, 2023
@nixos-discourse
Copy link

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

Copy link

stale bot commented Jan 21, 2024

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 stale bot added the status: stale label Jan 21, 2024
@jzbor
Copy link

jzbor commented Jan 21, 2024

Still relevant.

@stale stale bot removed the status: stale label Jan 21, 2024
Copy link

stale bot commented Apr 22, 2024

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 stale bot added the status: stale label Apr 22, 2024
@zeorin
Copy link

zeorin commented Apr 22, 2024

Still relevant.

@stale stale bot removed the status: stale label Apr 22, 2024
Copy link

stale bot commented Jul 26, 2024

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 stale bot added the status: stale label Jul 26, 2024
@Pamplemousse
Copy link
Contributor

Still relevant 🥲

@stale stale bot removed the status: stale label Aug 21, 2024
@soulomoon
Copy link

Still relevant 🥲

@FBIGlowie
Copy link

still unrelevant

@lz37
Copy link

lz37 commented Nov 5, 2024

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.

genus!!! it works

Copy link

stale bot commented Feb 4, 2025

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 stale bot added the status: stale label Feb 4, 2025
@davidmh
Copy link

davidmh commented Feb 4, 2025

Still relevant.

@stale stale bot removed the status: stale label Feb 4, 2025
@pabroux
Copy link

pabroux commented Feb 9, 2025

For anyone wanting a system agnostic setup for Home Manager and not wanting to give extra argument to home-manager switch, here what should look like your flake.nix:

{
  description = "unvX: a simple Home Manager configuration";

  inputs = {
    # nixpkgs, home-manager and flake-utils are by default loaded since they are
    # available in the global flake registry.
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = {
    nixpkgs,
    home-manager,
    flake-utils,
    ...
  }: 
    flake-utils.lib.eachSystem flake-utils.lib.allSystems (system: {
      # Specify your Home Manager profiles. Home Manager will by
      # default match first `$USER@$(hostname)`. If not found, it
      # will then default to `$USER`.
      packages.homeConfigurations = {
        "marty@Mcfly-MacBook-Pro.local" = home-manager.lib.homeManagerConfiguration {
          pkgs = nixpkgs.legacyPackages.${system};

          # Specify your Home Manager configurations.
          modules = [./host/Mcfly-MacBook-Pro/user/marty/home.nix];

          # Specify extra arguments to pass through your configurations.
        };
      };
    });
}

If you want to use symlinks with Nix flakes, see my repo unvX.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests