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

Allow the same user profile to behave differently based on hostname #308

Closed
yipengsun opened this issue Jun 6, 2021 · 8 comments
Closed
Labels
enhancement New feature or request

Comments

@yipengsun
Copy link

yipengsun commented Jun 6, 2021

Would your feature fix an existing issue?

Don't think so

Describe the solution you'd like

Currently system and user profiles seem to be completely separated. I'd like to have the ability to make user profile behave differently on different hosts.

For example, I use awesome window manager on all my Linux hosts, but I'd like to set different tiling layouts, color schemes, and wallpapers for different hosts (they have different screen resolution, per say).

I think this will be solved if we can pass additional arguments to user profiles and/or suites.

Describe alternatives you've considered

Currently I can create different users for different hosts, e.g. user1-host1, user1-host2 but I think this is not very elegant.

@yipengsun yipengsun added the enhancement New feature or request label Jun 6, 2021
@yipengsun
Copy link
Author

Related question: For the same username, can I configure it to have different user suites enabled on different hosts? For example I'd like to have GUI enabled for me on my laptop, but not on my server for the same username.

@yipengsun
Copy link
Author

Naively, it would be nice if we can set attrs in the host section:

        hosts = {
                  laptop = { hostAttrs = { isServer = false; }; };
                  server = { hostAttrs = { isServer = true; }; };
                };

And have hostname and arch automatically pass-thru in the hostAttrs. Then maybe make hostAttrs accessible in the suite wrapper.

@blaggacao
Copy link
Contributor

Hi @yipengsun thank you for the use case!

As a general design choice we want to have portable profiles as much as possible. We would even love to see them being portable across systems (nixos / darwin / hm).

So in a sense, the intended control flow is from profiles → hosts.

I think the right way might be to override (generic enough) profiles on a per host basis (e.g. in ./hosts/myhost.nix)
to account for different screen size or different lighting conditions (colours!) at the host's locations.

I hope this makes sense, please ask reply if not. We might need to have a more indepth conversation on the direction of the control flow, indeed.

For the same username, can I configure it to have different user suites enabled on different hosts?

Suites are nothing more than "profile aggregates" at their core, so you can define different combinations of profiles in suites and then imports any of those "profile aggregates" in your hosts.

in the suite wrapper.

In recent develop the suites wrapper has gone away in favor of a better abstraction which we called importables (things passed as special args to host configs and that you therefore can import there). importables.suites remains as an attribute, of which mkFlake is still aware of but without exorbitant special meaning.

Hope this all makes sense. I'm happy to continue this conversation, though. 😄

@yipengsun
Copy link
Author

Hi, thanks for the quick reply!

I think it make sense that system profiles (i.e. the profiles that only use NixOS modules, not home-manager ones) are generic. It certainly also make sense to aggregate all host-specific settings in hosts, rather than profiles.

I'm still confused about how to implement my original use case. After reading your reply, I think my questions become:

  1. How to (partially) override user on a host-by-host basis
  2. How to make home-manager profiles override-able in hosts config

For the first question: Maybe it's better if I provide a concrete example. Currently, in the core branch, the user nixos is defined as follows:

{ ... }:
{
  home-manager.users.nixos = { suites, ... }: {
    imports = suites.base;
  };

  users.users.nixos = {
    uid = 1000;
    password = "nixos";
    description = "default";
    isNormalUser = true;
    extraGroups = [ "wheel" ];
  };
}

My understanding is that nixos will have suites.base "provisioned" by home-manager. But say I want to enable suties.someOtherUserSuite for nixos user on some of my machines, how'd I do it? Should we introduce a wrapper to the user so that they can be overridden in the host config? Naively something like:

{ suites, ... }:
{
  ### root password is empty by default ###
  imports = suites.base;

  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  networking.networkmanager.enable = true;

  fileSystems."/" = { device = "/dev/disk/by-label/nixos"; };

  userOverride = {
    nixos = {
      home-manager.users.nixos = { suites, ... }: { imports = suites.someOtherUserSuite; };
    };
  };
}

For the second question, I admit I haven't thought too much about the "control flow". If we want to maintain the (home-manager) profile -> host control flow, what is the most consistent way to change window manager color scheme and wallpapers in this case? I think here we need to partially override some of the home-manager suites/profiles.

Let's say we have awesome-wm profile defined like this:

{
  # This is a home-manager profile
  programs.awesome = {
    wallpaper = <path_to_default_wallpaper>;
  };
}

How'd we override wallpaper on a host-by-host basis?

@danielphan2003
Copy link

How'd we override wallpaper on a host-by-host basis?

I suggest using lib.mkDefault. This way you can define a sensible default for profiles and then override them later in host-specific config.

In profiles/core/default.nix:

{ lib, ... }: {
  programs.gnupg.agent.pinentryFlavor = lib.mkDefault "curses";
}

In users/profiles/awesome-wm/default.nix:

{ lib, ... }: {
  programs.awesome.wallpaper = lib.mkDefault <path>;
}

In users/nixos/default.nix:

{ lib, ... }: {
  home-manager.users.nixos = { suites, ... }: {
    imports = lib.mkDefault suites.base;
  };
}

In hosts/NixOS.nix:

{ suites, ... }:
{
  imports = suites.base;
  programs.gnupg.agent.pinentryFlavor = "qt";
  home-manager.users.nixos = { suites, ... }: {
    imports = suites.someOtherUserSuite;
  };
}

@Pacman99
Copy link
Member

Pacman99 commented Jun 8, 2021

How'd we override wallpaper on a host-by-host basis?

You can define home-manager settings in different places. So your user profile can actually import the suite but in one host file you can do this:
hosts/NixOS.nix:

{
  home-manager.users.nixos.programs.awesome.wallpaper = ...;
}

Just like most other nixos options home-manager settings for one user defined in multiple places will get merged.

@yipengsun
Copy link
Author

I see! Thanks for the suggestions!

@amarshall
Copy link
Contributor

If one does not want to have to be specific about the user at the host-level (e.g. with home-manager.users.myuser.foo = "bar";), can do instead e.g.

{
  home-manager.sharedModules = [{ foo = "bar"; }];
}

to have it apply to all users.

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

No branches or pull requests

5 participants