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

Add standalone home-manager support #36

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

adam-gaia
Copy link

@adam-gaia adam-gaia commented Aug 30, 2024

Adds support for standalone home-manager configurations.

These configurations are discovered from homes/<username>/(default.nix|home.nix), similarly to how systems are discovered from hosts/<hostname>/(default.nix|configuration.nix|darwin-configuration.nix)

  • home.nix: standalone home-manager configuration
  • default.nix: an "escape hatch" giving the user complete control over homeManagerConfiguration calls

This issue was my attempt to add support in the way described by #35, however I wasn't able to do it exactly as I wanted. Home manager configs need system set to pass pkgs as an argument to HM modules. Instead of adding an option to specify the system of a particular home-manager profile, I used the existing eachSystem function to build profiles for each system specified by the user's systems flake input.

The home-manager CLI expects the flake outputs homeConfigurations.<name> not homeConfigurations.<system>.<name>. To get around this, I merged the nested attrsets so that the output becomes homeConfigurations."<name>@<system>". An example command to build the profile would be home-manager build --flake .#"agaia@x86_64-linux".

I don't love this solution TBH, but I wasn't sure of a good way for the user to specify. It crossed my mind to add a nested folder specifying the system (<repo>/homes/<system>/<name>), but I didn't like that either.

If this HM issue ever gets taken up, it could add some clarity on what to do. nix-community/home-manager#2161_

Copy link
Member

@zimbatm zimbatm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks reasonable overall.

@@ -152,6 +153,65 @@ Flake outputs:

> Depending on the system type returned, the flake outputs will be the same as detailed for NixOS or Darwin above.

### `homes/<name>/(default.nix|home.nix)`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the <name> map to a user name?

If yes, having those under a users/ structure might make sense.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name does map to a username. I don't know how I missed users/. Thats much better than homes/! Thanks

];

home.username = "myUser";
home.homeDirectory = "/home/myUser";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this maps to a user, the user could also be passed as a specialArgs argument.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a great idea, but I'm not really sure how to do it. Mind giving me a hand?


Flake outputs:

* `homeConfigurations."<name>@<system>"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current home-manager implementation, the @ sign is used for <user>@<hostname>, which is handy if you want a different profile on a specific host (eg: a server profile with no GUI apps vs a desktop profile).

Do you have any ideas on how to handle that case?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure how to handle this tbh.

A couple of ugly ideas off the top of my head:

  • subfolders for machine architecture, removing the need for user@architecture
  • user@hostname::architecture - I don't know if there are conventions for hostnames, but I can see a machine out there having :: in the name. I can't think of a better separator.

Any suggestions?

@adam-gaia adam-gaia force-pushed the standalone-homemanager branch from 8905803 to 1435c2f Compare September 21, 2024 03:54
@srounce
Copy link
Member

srounce commented Sep 21, 2024

I have a (kinda ghetto) alternative version I've been using in my own config with a similar expected directory layout to this PR (s/homes/users/). As home-manager cli expects the output path to be .#packages.<system>.homeConfigurations.<name> I decided to just generate an identical homeConfigurations set for every system:

homeConfigurations =
  usersPath:
  let
    usersPathStr = toString usersPath;

    userDirs = builtins.attrNames (
      lib.filterAttrs (_: type: type == "directory") (builtins.readDir usersPathStr)
    );
  in
  {
    packages = lib.genAttrs (import inputs.systems) (system: {
      homeConfigurations = lib.genAttrs userDirs (
        name:
        inputs.home-manager.lib.homeManagerConfiguration {
          pkgs = import inputs.nixpkgs {
            inherit system;

            config.allowUnfree = true;
          };

          modules = [
            "${usersPathStr}/${name}/home.nix"
          ];

          extraSpecialArgs = {
            inherit inputs system;
            flake = inputs.self;
            perSystem = lib.mapAttrs (
              _: flake: flake.legacyPackages.${system} or { } // flake.packages.${system} or { }
            ) inputs;
          };
        }
      );
    });
  };

and then in my flake.nix I have

  outputs =
    inputs:
    let
      lib = inputs.nixpkgs.lib;
      slib = import ./lib { inherit inputs; };
    in
    lib.recursiveUpdate (inputs.blueprint {
      inherit inputs;

      nixpkgs.config = {
        allowUnfree = true;
      };
    }) (slib.homeConfigurations ./users);

This results in the following:

└───packages
    ├───x86_64-linux
    │   └───homeConfigurations
    │       ├───s-desktop
    │       └───s-server
    # etc...

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

Successfully merging this pull request may close these issues.

3 participants